При изменении шейдера HLSL для работы в Vulkan, нужно ли разделять текстуры / сэмплеры?

Я модифицирую шейдер HLSL, используемый в D3D12, для компиляции в SPIR-V, потому что я хочу использовать тот же код шейдера в Vulkan. Вот шейдер:

#if !VULKAN
#define layout(a)  
#else
#define register(a) blank
#endif

struct VSOutput
{
    float4 pos : SV_Position;
    float2 uv : TEXCOORD;
    float4 color : COLOR;
};

layout(binding=1) Texture2D<float4> tex : register(t0);
layout(binding=1) SamplerState sLinear : register(s0);

float4 main( VSOutput vsOut ) : SV_Target
{
    return tex.SampleLevel( sLinear, vsOut.uv, 0 ) * vsOut.color;
};

Могу ли я использовать одну и ту же привязку как для текстуры, так и для сэмплера, если мой дескриптор, установленный в индексе 1, имеет тип VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, или я должен использовать два слота привязки, один для текстуры и один для сэмплера? Я спрашиваю, потому что при создании конвейера возникла ошибка

Предупреждение Vulkan: [ParameterValidation], код: 9: vkCreateGraphicsPipelines: вернул VK_ERROR_INITIALIZATION_FAILED, что указывает на сбой инициализации объекта

при использовании этого шейдера вместо шейдера GLSL, скомпилированного в SPIR-V. Мой шейдер GLSL использует такую ​​текстуру:

layout (binding = 1) uniform sampler2D textureMap;

person SurvivalMachine    schedule 26.08.2017    source источник
comment
Действительно ли создание конвейера терпит неудачу или на него жалуются только уровни проверки? Может, сэмплер комбинированных изображений не проблема?   -  person Ekzuzy    schedule 26.08.2017
comment
@Ekzuzy Он также не работает без уровней проверки, так что, возможно, проблема в другом.   -  person SurvivalMachine    schedule 26.08.2017
comment
Для справки в будущем я обнаружил, что мое создание PSO с этим шейдером HLSL не работает на AMD (драйвер 17.8.2), но работает на NVIDIA. Может это ошибка драйвера AMD.   -  person SurvivalMachine    schedule 30.08.2017


Ответы (2)


Что касается SPIR-V и Vulkan, эквивалент SPIR-V должен работать. То есть вы можете иметь переменную изображения и переменную сэмплера, привязанные к одной и той же привязке, и использовать на ней COMBINED_IMAGE_SAMPLER:

Доступ к записям набора дескрипторов VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER также можно получить через отдельный сэмплер и переменные шейдера сэмплированного изображения.

и:

Допустимо, чтобы нескольким переменным шейдера был назначен один и тот же набор дескрипторов и значения привязки, если все те, которые статически используются компилируемой точкой входа, совместимы с типом дескриптора в привязке макета набора дескрипторов.

Комбинированные типы дескрипторов изображения / сэмплера совместимы как с изображениями, так и с сэмплерами.

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

Я бы посоветовал, если в остальном ваш код верен, заполнить отчет об ошибке.


layout (binding = 1) uniform sampler2D textureMap;

Также рекомендуется указывать set. KHR_vulkan_glsl по умолчанию установлен на 0, но лучше иметь явную инструкцию.

person Nicol Bolas    schedule 26.08.2017

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

layout( set=S, binding=B ) ...

Вот пример использования комбинированного сэмплера изображений. Если вы хотите, вы также можете использовать отдельные объекты сэмплера и сэмплера изображения. Затем вы должны определить их в двух отдельных привязках и использовать два дескриптора. Но дескриптор комбинированного сэмплера изображений может иметь лучшую производительность на некоторых платформах.

person Ekzuzy    schedule 26.08.2017