How I am supposed to restrict bindings across shaders in the same file for slang?
I am a little confused on what is broken. I thought slang compilation was supposed to "handle the bindings." so here I would of expected that ubo would of been included in only the vertex spirv, and texSampler would only be included in the fragment spirv. I am sure that there is probably something I need to do explicitly here, but I was sold on slang auto-magically handing these types of things. I am new to graphics programming and initially followed the old tutorial to completion then wanted to try porting over to slang. Any help is appreciated, as i have been digging through the slang and vulkan documentation for a while and its been hard to figure out how it all comes together without a real example.
slang file :
struct MatrixParameters{
float4x4 model;
float4x4 view;
float4x4 proj;
}
struct Vertex{
float3 position;
float3 color;
float2 uv;
}
struct VOut
{
float4 position : SV_POSITION;
float3 fragColor;
float2 fragTexCoord;
}
ConstantBuffer<MatrixParameters> ubo;
[shader("vertex")]
VOut main(Vertex input)
{
VOut output;
output.position = mul(ubo.proj, mul(ubo.view, mul(ubo.model, float4(input.position, 1.0))));
output.fragColor = input.color;
output.fragTexCoord = input.uv;
return output;
}
uniform DescriptorHandle<Sampler2D> texSampler;
[shader("fragment")]
float4 main(VOut input) : SV_TARGET
{
float4 outColor = float4(input.fragColor * texSampler.Sample(input.fragTexCoord).rgb, 1.0);
return outColor;
}
c++ program file :
// CREATING DESCRIPTOR SET LAYOUT
VkDescriptorSetLayoutBinding uboLayoutBinding{};
uboLayoutBinding.binding = 0;
uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uboLayoutBinding.descriptorCount = 1;
uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
uboLayoutBinding.pImmutableSamplers = nullptr;
VkDescriptorSetLayoutBinding samplerLayoutBinding{};
samplerLayoutBinding.binding = 1;
samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
samplerLayoutBinding.descriptorCount = 1;
samplerLayoutBinding.pImmutableSamplers = nullptr;
samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
std::array<VkDescriptorSetLayoutBinding, 2> bindings = { uboLayoutBinding, samplerLayoutBinding };
VkDescriptorSetLayoutCreateInfo layoutInfo{};
layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());
layoutInfo.pBindings = bindings.data();
vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &outDescriptorSetLayout)
...
slangModule->getDefinedEntryPoint(0, vertexEntryPoint.writeRef());
slangModule->getDefinedEntryPoint(1, fragmentEntryPoint.writeRef());
slangResources.mpSessionInstance->createCompositeComponentType(
componentTypes.data(), // {slangModule, vertexEntryPoint, fragmentEntryPoint }
componentTypes.size(),
composedProgram.writeRef(),
diagnosticBlob.writeRef());
composedProgram->getEntryPointCode(
0,
0,
spirvCode,
diagnosticBlob.writeRef()
);
VkShaderModuleCreateInfo shaderModuleCreateInfo{};
shaderModuleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
shaderModuleCreateInfo.codeSize = spirvCode->getBufferSize();
shaderModuleCreateInfo.pCode = reinterpret_cast<const uint32_t *>(spirvCode->getBufferPointer());
VkShaderModule vertexModule;
vkCreateShaderModule(device, &shaderModuleCreateInfo, nullptr, &comboModule);
composedProgram->getEntryPointCode(
1,
0,
spirvCode2,
diagnosticBlob.writeRef()
);
VkShaderModuleCreateInfo shaderModuleCreateInfoFr{};
shaderModuleCreateInfoFr.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
shaderModuleCreateInfoFr.codeSize = spirvCode2->getBufferSize();
shaderModuleCreateInfoFr.pCode = reinterpret_cast<const uint32_t *>(spirvCode2->getBufferPointer());
VkShaderModule fragmentModule;
vkCreateShaderModule(device, &shaderModuleCreateInfoFr, nullptr, &fragmentModule;
ERROR output :
validation layer: vkCreateGraphicsPipelines(): pCreateInfos[0].pStages[0] shader [VK_SHADER_STAGE_VERTEX_BIT] uses descriptor [Set 0, Binding 1, variable "ubo"] (VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) but the VkDescriptorSetLayoutBinding::stageFlags was VK_SHADER_STAGE_FRAGMENT_BIT.
(VkDescriptorSetLayout from VkPipelineLayoutCreateInfo::pSetLayouts[0]).
The Vulkan spec states: If a resource variable is declared in a shader and layout is not VK_NULL_HANDLE, the corresponding descriptor set in layout must match the shader stage (https://docs.vulkan.org/spec/latest/chapters/pipelines.html#VUID-VkGraphicsPipelineCreateInfo-layout-07988)
validation layer: vkCreateGraphicsPipelines(): pCreateInfos[0].pStages[1] shader [VK_SHADER_STAGE_FRAGMENT_BIT] uses descriptor [Set 0, Binding 0, variable "globalParams"] (VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) but the VkDescriptorSetLayoutBinding::stageFlags was VK_SHADER_STAGE_VERTEX_BIT.