[SDL_gpu] offset support on storage buffers

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?

We cut this because D3D12 makes it very annoying to do. You can provide an offset by sending a uniform value containing the offset.