2016-06-29 12 views
3

У меня есть геометрический шейдер со следующим нажимным постоянным блоком:Нажимать постоянный предел в геометрическом шейдере?

layout(push_constant) uniform Instance { 
    mat4 VP; 
    vec3 posCam; 
    float radius; 
    float curvature; 
} u_instance; 

Нажимными константы определены в макете трубопровода, как это:

uint32_t offset = 0; 
uint32_t size = 21 *sizeof(float); 
vk::PushConstantRange range {vk::ShaderStageFlagBits::eGeometry,offset,size}; 

Однако Vulkan слоев проверки бросить эту ошибку:

Push constant range covering variable starting at offset 0 not accessible from stage VK_SHADER_STAGE_GEOMETRY_BIT 

Что здесь означает «недоступно»? Почему бы им не быть доступными? Если я перемещаю push-константы на другой этап (например, фрагмент или вершинный шейдер), ошибка не возникает.

Кроме того, я получаю эту ошибку только от Nvidia GeForce GTX 650 Ti. Я также пробовал это на карте AMD, которая отлично работала.

Есть ли какое-то ограничение на константы толчка для геометрических шейдеров? Я проверил ограничения для моего графического ядра Nvidia, общий максимальный размер постоянного тока - 256 байтов, и поддерживаются геометрические шейдеры. Я также ничего не могу найти в спецификации Вулкана.

ответ

2

Я думаю, что std430 правила упаковки (или 14.5.4. Офсетная и Stride Назначение от Vulkan спецификации) могут испортить размеры. Например. vec3 будет выложен как vec4 (может быть, 22*sizeof(float)? - извините, не совсем уверен в этом сам).

код слой открыт, если вы хотите, чтобы исследовать себя (и я нашел линию по производству этого доклада): https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/layers/core_validation.cpp#L1976

UPDATE: Я не думаю, что я был прав выше. Что 1.0.17 SDK glslangValidator дает мне is 84 байта (21 * float; с смещениями членов 0, 64, 76 и 80 соответственно). Весь блок добирается до множителя 16, хотя (до всего размера блока 96 B).

Кроме того, сообщение привязано к предоставленному перечислению для сцены (оно сравнивает его со стадией шейдерного модуля). Очень странно, что сообщение об ошибке будет отличаться от реализаций ... (убедитесь, что вы обновили SDK и драйверы, и будьте подозрительны к обертке vkcpp или тому, что находится в этом размещенном коде) и отметьте pStages[n].stage членом используемого VkGraphicsPipelineCreateInfo и PushRange (которое слой сравнивает).

2

Можете ли вы добавить еще какой-нибудь код (или загрузить его где-нибудь)? Я просто проверил это с вашим постоянным блоком push на GTX 980 с уровнями проверки, скомпилированными из исходного кода и не получающими никаких предупреждений о валидации.

Additionally, I only get this error on a Nvidia GeForce GTX 650 Ti. I've also tried it on an AMD card, which worked fine.

Это очень странно, так как сообщения проверки не генерируются драйверами и как таковые не должны отличаться между реализациями (если только это не связано с проверки пределов устройств).

Is there some kind of limitation on push constants for geometry shaders? I've checked the limitations for my Nvidia GPU, the total max push constant size is 256 bytes, and geometry shaders are supported. I also can't find anything in the Vulkan specification either.

Не существует постоянного постоянного предела, специфичного для геометрического шейдера. Если вы превысите ограничение на постоянный размер push, уровни проверки будут выдавать ошибку.

I think that std430 packing rules (or 14.5.4. Offset and Stride Assignment of the Vulkan spec) can mess up the sizes. E.g. the vec3 would be laid out as vec4 (so maybe 22*sizeof(float)? - sorry not exactly confident in this myself).

Не уверен, что упаковка будет проблемой здесь, но в основном это должно работать без сообщения уровня проверки. Если бы шаг был проблемой, то уровни проверки еще не должны запускать ничего, если вы начинаете со смещения 0.