Sampling a texture via SDL GPU and GLSL

I’m trying to render a texture to the screen via SDL GPU, however I can’t get the sampler2D to work in GLSL or SamplerState to work with HLSL. I get the following error via Vulkan validation layes:

Validation Error: [ VUID-VkGraphicsPipelineCreateInfo-layout-07988 ] | MessageID = 0x215f02cd
vkCreateGraphicsPipelines(): pCreateInfos[0].pStages[1] SPIR-V (VK_SHADER_STAGE_FRAGMENT_BIT) uses descriptor [Set 0, Binding 0, variable "sampler1"] (type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) but was not declared in the pipeline layout.
The Vulkan spec states: If a resource variable is declared in a shader, the corresponding descriptor set in layout must match the shader stage (https://docs.vulkan.org/spec/latest/chapters/pipelines.html#VUID-VkGraphicsPipelineCreateInfo-layout-07988)
Objects: 2
    [0] VkShaderModule 0x310000000031
    [1] VkPipelineLayout 0x350000000035

Here’s a link to the source: Elliot Lurie / Undermine · GitLab . The relevant files are data/*.glsl, and src/graphics.c. This is my first dive into GPU programming, so any and all assistance is appreciated!

Running into the same issue error on my end. Struggling to get a texture into a shader with Vulkan.

I looked at your gitlab repo, it seems like you have made a few changes since your post so I am curious if/how you managed to solve it.

Some differences I noticed from mine that might be a quirk you discovered:

  • Texture blit after draw call
  • Using storage buffer (although I doubt this would cause issue)
  • Fragment shader uses sampler2DArrayinstead of sampler2D as well as layout(set = 2, binding = 0)

Would appreciate the help.

Hi! It’s been a while and I’ve moved on to Zig and Vulkan for now. From what I can remember one of the issues I was having was the shader embeds not updating when I rebuilt the program. If you’re doing the same thing, I would suggest doing a clean build (including clearing your ccache directory).

Otherwise, if you’re getting the same validation error, I would suggest you check your num_samplers and make sure those reflect the number of textures in your shader. Also, make sure you follow SDL’s descriptor set rules specified here. The sets themselves are arbitrary at the Vulkan level, but SDL requires specific bindings so that they can simply be defined at shader module creation from what I can tell.

If not, some other things to check would be making sure you offset into the transfer buffer correctly on both the mapped data copying (memcpy, manually setting elements, etc) and the copy pass commands. I’m still a bit of a newbie but I’d be happy to take a look at some of your code too!

Legend! That descriptor set rules link you shared was exactly my issue. I clearly missed it rushing through debugging, but I honestly do wish it was more explicitly documented somehow. I understand that won’t be easy since SDL support goes beyond Vulkan.

I’m sure once things mature a bit more and tutorials start rolling out, fewer will run into this.

For the sake of others/SEO, here are the descriptor set rule snippets related to the issue that worked in the end.

Vertex Shader:

layout(set = 1, binding = 0) uniform View {
    mat4 proj;
} view;

Fragment Shader:

layout(set = 2, binding = 0) uniform sampler2D uTexture;

CPP (SDL_CreateGPUShader):

bool is_vertex = stage == SDL_GPU_SHADERSTAGE_VERTEX;
SDL_GPUShaderCreateInfo createinfo{};
createinfo.num_samplers = is_vertex ? 0 : 1;
createinfo.num_uniform_buffers = is_vertex ? 1 : 0;