Модифицируя шейдер 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;

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, но лучше иметь явное утверждение.

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

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

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

Другие вопросы по тегам