From 4f722d372ae7246f123762b0407cbec1e6e71d65 Mon Sep 17 00:00:00 2001
From: Caleb Cornett <[EMAIL REDACTED]>
Date: Sun, 15 Sep 2024 20:17:43 -0500
Subject: [PATCH] GPU: Metal vertex buffer indices should grow upward (#10837)
---
include/SDL3/SDL_gpu.h | 2 +-
src/gpu/metal/SDL_gpu_metal.m | 25 ++++++++++---------------
2 files changed, 11 insertions(+), 16 deletions(-)
diff --git a/include/SDL3/SDL_gpu.h b/include/SDL3/SDL_gpu.h
index 64f9779de5b15..6ad4532ba1e80 100644
--- a/include/SDL3/SDL_gpu.h
+++ b/include/SDL3/SDL_gpu.h
@@ -1983,7 +1983,7 @@ extern SDL_DECLSPEC SDL_GPUSampler *SDLCALL SDL_CreateGPUSampler(
* - [[texture]]: Sampled textures, followed by storage textures
* - [[sampler]]: Samplers with indices corresponding to the sampled textures
* - [[buffer]]: Uniform buffers, followed by storage buffers. Vertex buffer 0
- * is bound at [[buffer(30)]], vertex buffer 1 at [[buffer(29)]], and so on.
+ * is bound at [[buffer(14)]], vertex buffer 1 at [[buffer(15)]], and so on.
* Rather than manually authoring vertex buffer indices, use the
* [[stage_in]] attribute which will automatically use the vertex input
* information from the SDL_GPUPipeline.
diff --git a/src/gpu/metal/SDL_gpu_metal.m b/src/gpu/metal/SDL_gpu_metal.m
index 7dd33a21be69d..2b98c35f85460 100644
--- a/src/gpu/metal/SDL_gpu_metal.m
+++ b/src/gpu/metal/SDL_gpu_metal.m
@@ -30,9 +30,9 @@
// Defines
-#define METAL_MAX_BUFFER_COUNT 31
-#define WINDOW_PROPERTY_DATA "SDL_GPUMetalWindowPropertyData"
-#define SDL_GPU_SHADERSTAGE_COMPUTE 2
+#define METAL_FIRST_VERTEX_BUFFER_SLOT 14
+#define WINDOW_PROPERTY_DATA "SDL_GPUMetalWindowPropertyData"
+#define SDL_GPU_SHADERSTAGE_COMPUTE 2
#define TRACK_RESOURCE(resource, type, array, count, capacity) \
Uint32 i; \
@@ -633,11 +633,6 @@ static MTLColorWriteMask SDLToMetal_ColorWriteMask(
// Helper Functions
-static Uint32 METAL_INTERNAL_GetVertexBufferIndex(Uint32 binding)
-{
- return METAL_MAX_BUFFER_COUNT - 1 - binding;
-}
-
// FIXME: This should be moved into SDL_sysgpu.h
static inline Uint32 METAL_INTERNAL_NextHighestAlignment(
Uint32 n,
@@ -1097,11 +1092,12 @@ static void METAL_ReleaseGraphicsPipeline(
Uint32 loc = createinfo->vertex_input_state.vertex_attributes[i].location;
vertexDescriptor.attributes[loc].format = SDLToMetal_VertexFormat[createinfo->vertex_input_state.vertex_attributes[i].format];
vertexDescriptor.attributes[loc].offset = createinfo->vertex_input_state.vertex_attributes[i].offset;
- vertexDescriptor.attributes[loc].bufferIndex = METAL_INTERNAL_GetVertexBufferIndex(createinfo->vertex_input_state.vertex_attributes[i].buffer_slot);
+ vertexDescriptor.attributes[loc].bufferIndex =
+ METAL_FIRST_VERTEX_BUFFER_SLOT + createinfo->vertex_input_state.vertex_attributes[i].buffer_slot;
}
for (Uint32 i = 0; i < createinfo->vertex_input_state.num_vertex_buffers; i += 1) {
- binding = METAL_INTERNAL_GetVertexBufferIndex(createinfo->vertex_input_state.vertex_buffer_descriptions[i].slot);
+ binding = METAL_FIRST_VERTEX_BUFFER_SLOT + createinfo->vertex_input_state.vertex_buffer_descriptions[i].slot;
vertexDescriptor.layouts[binding].stepFunction = SDLToMetal_StepFunction[createinfo->vertex_input_state.vertex_buffer_descriptions[i].input_rate];
vertexDescriptor.layouts[binding].stepRate = (createinfo->vertex_input_state.vertex_buffer_descriptions[i].input_rate == SDL_GPU_VERTEXINPUTRATE_INSTANCE)
? createinfo->vertex_input_state.vertex_buffer_descriptions[i].instance_step_rate
@@ -2371,17 +2367,16 @@ static void METAL_BindVertexBuffers(
MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer;
id<MTLBuffer> metalBuffers[MAX_VERTEX_BUFFERS];
NSUInteger bufferOffsets[MAX_VERTEX_BUFFERS];
- NSRange range = NSMakeRange(METAL_INTERNAL_GetVertexBufferIndex(firstBinding), numBindings);
+ NSRange range = NSMakeRange(METAL_FIRST_VERTEX_BUFFER_SLOT + firstBinding, numBindings);
if (range.length == 0) {
return;
}
- for (Uint32 i = 0; i < range.length; i += 1) {
+ for (Uint32 i = 0; i < numBindings; i += 1) {
MetalBuffer *currentBuffer = ((MetalBufferContainer *)bindings[i].buffer)->activeBuffer;
- NSUInteger bindingIndex = range.length - 1 - i;
- metalBuffers[bindingIndex] = currentBuffer->handle;
- bufferOffsets[bindingIndex] = bindings[i].offset;
+ metalBuffers[firstBinding + i] = currentBuffer->handle;
+ bufferOffsets[firstBinding + i] = bindings[i].offset;
METAL_INTERNAL_TrackBuffer(metalCommandBuffer, currentBuffer);
}