I get the following error when trying to use a shader storage image on Linux with the Vulkan backend (SDL 3.4.2)
Validation Error: [ VUID-VkComputePipelineCreateInfo-layout-07990 ] | MessageID = 0x830b328a
vkCreateComputePipelines(): pCreateInfos[0].stage SPIR-V (VK_SHADER_STAGE_COMPUTE_BIT) uses descriptor [Set 0, Binding 0, variable "u_src"] which has a VkDescriptorType mismatch.
VkDescriptorSetLayoutBinding::descriptorType is VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
Possible VkDescriptorType for the SPIR-V variable are: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
Info on SPIR-V mapping for each type:
- VK_DESCRIPTOR_TYPE_STORAGE_IMAGE is an OpTypeImage, with Sampled = 2, in UniformConstant
Full list of mappings can be found at https://docs.vulkan.org/spec/latest/chapters/interfaces.html#interfaces-resources-storage-class-correspondence
(VkDescriptorSetLayout from VkPipelineLayoutCreateInfo::pSetLayouts[0]).
The Vulkan spec states: If a resource variable is declared in a shader, layout is not VK_NULL_HANDLE, and the descriptor type is not VK_DESCRIPTOR_TYPE_MUTABLE_EXT, the corresponding descriptor set in layout must match the descriptor type (https://docs.vulkan.org/spec/latest/chapters/pipelines.html#VUID-VkComputePipelineCreateInfo-layout-07990)
Objects: 2
[0] VkShaderModule 0x300000000030
[1] VkDescriptorSetLayout 0x310000000031
#include <SDL3/SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char const *argv[]) {
SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS, "1");
SDL_Init(SDL_INIT_VIDEO);
SDL_GPUDevice* device = SDL_CreateGPUDevice(
SDL_GPU_SHADERFORMAT_SPIRV,
true, // debug mode
NULL // driver - NULL to auto-select
);
float w = 600; float h = 600;
SDL_Window* window = SDL_CreateWindow("hi", w, h, SDL_WINDOW_HIGH_PIXEL_DENSITY);
SDL_ClaimWindowForGPUDevice(device, window);
char* file = "sdl-gpu-test.comp.spv";
size_t code_size; void* code = SDL_LoadFile(file, &code_size);
SDL_GPUComputePipeline* compute_pipeline = SDL_CreateGPUComputePipeline(
device,
&(SDL_GPUComputePipelineCreateInfo){
.code_size=code_size,
.code=code,
.entrypoint="main",
.format=SDL_GPU_SHADERFORMAT_SPIRV,
.num_samplers=0,
.num_uniform_buffers=0,
.num_readonly_storage_textures=1,
.num_readonly_storage_buffers=0,
.num_readwrite_storage_textures=1,
.num_readwrite_storage_buffers=0,
.threadcount_x=32,
.threadcount_y=32,
.threadcount_z=1,
});
if (!compute_pipeline) {
printf("%s\n", SDL_GetError());
exit(-1);
}
SDL_GPUTexture* texture1 = SDL_CreateGPUTexture(device,
&(SDL_GPUTextureCreateInfo){
.type = SDL_GPU_TEXTURETYPE_2D,
.format = SDL_GPU_TEXTUREFORMAT_R8_UINT,
.usage = SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_READ,
.width = w,
.height = h,
.layer_count_or_depth = 1,
.num_levels = 1,
});
SDL_GPUTexture* texture2 = SDL_CreateGPUTexture(device,
&(SDL_GPUTextureCreateInfo){
.type = SDL_GPU_TEXTURETYPE_2D,
.format = SDL_GPU_TEXTUREFORMAT_R8_UINT,
.usage = SDL_GPU_TEXTUREUSAGE_COMPUTE_STORAGE_WRITE,
.width = w,
.height = h,
.layer_count_or_depth = 1,
.num_levels = 1,
.sample_count = SDL_GPU_SAMPLECOUNT_1,
});
SDL_GPUCommandBuffer* cmd_buf = SDL_AcquireGPUCommandBuffer(device);
SDL_GPUComputePass* compute_pass = SDL_BeginGPUComputePass(cmd_buf,
(SDL_GPUStorageTextureReadWriteBinding[]){
{ .texture = texture2,
.cycle = true
},
}, 1,
NULL, 0); // buffers
SDL_BindGPUComputePipeline(compute_pass, compute_pipeline);
SDL_BindGPUComputeStorageTextures(compute_pass,
0, (SDL_GPUTexture*[]){texture1}, 1);
SDL_DispatchGPUCompute(compute_pass, ceil(w/32), ceil(h/32), 1);
SDL_EndGPUComputePass(compute_pass);
SDL_SubmitGPUCommandBuffer(cmd_buf);
return 0;
}
#version 460
#define SDL_COMP_READ_ONLY_BINDING_SET 0 // read-only tex+buffers
#define SDL_COMP_READ_WRITE_BINDING_SET 1 // read-write tex+buffers
#define SDL_COMP_UNIFORM_BINDING_SET 2 // uniforms
layout(local_size_x = 32, local_size_y = 32, local_size_z = 1) in;
layout(set = SDL_COMP_READ_ONLY_BINDING_SET, binding = 0, r8ui) uniform readonly uimage2D u_src;
layout(set = SDL_COMP_READ_WRITE_BINDING_SET, binding = 0, r8ui) uniform writeonly uimage2D u_dst;
void main() {
ivec2 p = ivec2(gl_GlobalInvocationID.xy);
imageStore(u_dst, p, imageLoad(u_src, p));
}
glslang -V sdl-gpu-test.comp -o sdl-gpu-test.comp.spv && clang sdl-gpu-test.c -lSDL3 -lm && ./a.out
I get the following error when trying to use a shader storage image on Linux with the Vulkan backend (SDL 3.4.2)
Here's the minimal test program:
and corresponding compute shader GLSL
Compiled and run with
(Removing the "readonly" specifier also gives the same result)