Hey, SDL experts - it’s my impression that in APIs like Metal (with MTLAttributeDescriptor) and Vulkan (with VkDescriptorBufferInfo), buffers can be bound to shader slots with offsets as if they’re sub-allocated (similar in concept to a “buffer view”, or std::span<>
in C++20), but I can’t seem to find an equivalent way to do that in SDL_gpu today.
This use case came around as I was trying to store the entire geometry data for a given mesh in a single buffer, and have the shader pull all of the data from regular storage buffers (SSBOs/SRVs) declared in different input slots, instead of vertex/attrib buffers.
For example, the vertex shader starts like this:
struct SceneState {
float4x4 projectionModelViewMatrix;
float4x4 normalMatrix;
float4 lightPos;
float4 lightColor;
};
StructuredBuffer<float3> vertices : register(t0, space0);
StructuredBuffer<float3> normals : register(t1, space0);
StructuredBuffer<float2> texCoords : register(t2, space0);
StructuredBuffer<int3> indices : register(t3, space0);
ConstantBuffer<SceneState> scene : register(b0, space1);
struct VertexOut {
float4 pos : SV_POSITION;
float2 texCoord : TEXCOORD0;
float3 diffuse : COLOR0;
};
VertexOut VSMain(int vid : SV_VERTEXID) {
const float4 vertexIn = float4(vertices[indices[vid].x], 1.0);
const float4 normalIn = float4(normals[indices[vid].y], 0.0);
const float2 texCoordIn = texCoords[indices[vid].z];
(...)
}
Now, suppose I have my buffer sub-allocated like this:
0x0000 ~ 0x2FFF : Vertex data (float3)
0x3000 ~ 0x5FFF : Normals data (float3)
0x6000 ~ 0x7FFF : TexCoords data (float2)
0x8000 ~ 0xAFFF : Vertex+Normal+TexCoord Index data (int3)
I can’t find a way to bind a storage buffer with an offset to a render pass, yet SDL_BindGPUVertexBuffers()
works just like that, since it takes SDL_GPUBufferBinding
arrays. Even something like the example below would already work:
SDL_BindGPUVertexStorageBufferOffset(renderPassPtr, 0, &geometryBufferPtr, 0x0000);
SDL_BindGPUVertexStorageBufferOffset(renderPassPtr, 1, &geometryBufferPtr, 0x3000);
SDL_BindGPUVertexStorageBufferOffset(renderPassPtr, 2, &geometryBufferPtr, 0x6000);
SDL_BindGPUVertexStorageBufferOffset(renderPassPtr, 3, &geometryBufferPtr, 0x8000);
Is there any reason SDL_BindGPUVertexBuffers()
and SDL_BindGPUVertexStorageBuffers()
differ in this aspect today?