https://github.com/libsdl-org/SDL_shadercross/commit/efa0d1531bf3cccfc5ecf3076716f14684f29965
From efa0d1531bf3cccfc5ecf3076716f14684f29965 Mon Sep 17 00:00:00 2001
From: Mirko Covizzi <[EMAIL REDACTED]>
Date: Sun, 12 Jan 2025 02:40:55 +0100
Subject: [PATCH] MSL: fix buffer ordering when transpiling compute from SPIRV
(#77)
Fixes the buffer ordering when transpiling compute shaders
from SPIRV.
The SPV kernel execution model produces a different
layout for HLSL and GLSL. When used with GLSL, the bindings
set are ignored by SPIRV-cross. In this case, use GLCompute
model instead. This produces the expected result.
Also properly assigns the return values that are checked
for errors.
Signed-off-by: Mirko Covizzi <mrkcvzz@gmail.com>
---
src/SDL_shadercross.c | 94 +++++++++++++++++++++++--------------------
1 file changed, 50 insertions(+), 44 deletions(-)
diff --git a/src/SDL_shadercross.c b/src/SDL_shadercross.c
index 0e69c4e..efc15c4 100644
--- a/src/SDL_shadercross.c
+++ b/src/SDL_shadercross.c
@@ -948,7 +948,11 @@ static SPIRVTranspileContext *SDL_ShaderCross_INTERNAL_TranspileFromSPIRV(
} else if (shaderStage == SDL_SHADERCROSS_SHADERSTAGE_FRAGMENT) {
executionModel = SpvExecutionModelFragment;
} else { // compute
- executionModel = SpvExecutionModelKernel;
+ if (backend == SPVC_BACKEND_HLSL) {
+ executionModel = SpvExecutionModelKernel;
+ } else {
+ executionModel = SpvExecutionModelGLCompute;
+ }
}
// MSL doesn't have descriptor sets, so we have to set up index remapping
@@ -1433,20 +1437,19 @@ static SPIRVTranspileContext *SDL_ShaderCross_INTERNAL_TranspileFromSPIRV(
num_textures += 1;
}
- // Storage buffers
+ // Uniform buffers
result = spvc_resources_get_resource_list_for_type(
resources,
- SPVC_RESOURCE_TYPE_STORAGE_BUFFER,
+ SPVC_RESOURCE_TYPE_UNIFORM_BUFFER,
(const spvc_reflected_resource **)&reflected_resources,
- &num_storage_buffers);
+ &num_uniform_buffers);
if (result < 0) {
SPVC_ERROR(spvc_resources_get_resource_list_for_type);
spvc_context_destroy(context);
return NULL;
}
- // Readonly storage buffers
- for (size_t i = 0; i < num_storage_buffers; i += 1) {
+ for (size_t i = 0; i < num_uniform_buffers; i += 1) {
if (!spvc_compiler_has_decoration(compiler, reflected_resources[i].id, SpvDecorationDescriptorSet) || !spvc_compiler_has_decoration(compiler, reflected_resources[i].id, SpvDecorationBinding)) {
SDL_SetError("%s", "Shader resources must have descriptor set and binding index!");
spvc_context_destroy(context);
@@ -1454,38 +1457,57 @@ static SPIRVTranspileContext *SDL_ShaderCross_INTERNAL_TranspileFromSPIRV(
}
unsigned int descriptor_set_index = spvc_compiler_get_decoration(compiler, reflected_resources[i].id, SpvDecorationDescriptorSet);
- if (!(descriptor_set_index == 0 || descriptor_set_index == 1)) {
- SDL_SetError("%s", "Descriptor set index for compute storage buffer must be 0 or 1!");
+ if (descriptor_set_index != 2) {
+ SDL_SetError("%s", "Descriptor set index for compute uniform buffer must be 2!");
spvc_context_destroy(context);
return NULL;
}
- // Skip readwrite buffers
- if (descriptor_set_index != 0) { continue; }
-
unsigned int binding_index = spvc_compiler_get_decoration(compiler, reflected_resources[i].id, SpvDecorationBinding);
binding.stage = executionModel;
binding.desc_set = descriptor_set_index;
binding.binding = binding_index;
binding.msl_buffer = binding_index;
- spvc_compiler_msl_add_resource_binding(compiler, &binding);
+ result = spvc_compiler_msl_add_resource_binding(compiler, &binding);
if (result < 0) {
SPVC_ERROR(spvc_compiler_msl_add_resource_binding);
spvc_context_destroy(context);
return NULL;
}
+ }
+ num_buffers += num_uniform_buffers;
- num_buffers += 1;
+ // Storage buffers
+ result = spvc_resources_get_resource_list_for_type(
+ resources,
+ SPVC_RESOURCE_TYPE_STORAGE_BUFFER,
+ (const spvc_reflected_resource **)&reflected_resources,
+ &num_storage_buffers);
+ if (result < 0) {
+ SPVC_ERROR(spvc_resources_get_resource_list_for_type);
+ spvc_context_destroy(context);
+ return NULL;
}
- // Readwrite storage buffers
+ // Readonly storage buffers
size_t current_num_buffers = num_buffers;
for (size_t i = 0; i < num_storage_buffers; i += 1) {
+ if (!spvc_compiler_has_decoration(compiler, reflected_resources[i].id, SpvDecorationDescriptorSet) || !spvc_compiler_has_decoration(compiler, reflected_resources[i].id, SpvDecorationBinding)) {
+ SDL_SetError("%s", "Shader resources must have descriptor set and binding index!");
+ spvc_context_destroy(context);
+ return NULL;
+ }
+
unsigned int descriptor_set_index = spvc_compiler_get_decoration(compiler, reflected_resources[i].id, SpvDecorationDescriptorSet);
+ if (!(descriptor_set_index == 0|| descriptor_set_index == 1)) {
+ SDL_SetError("%s", "Descriptor set index for compute storage buffer must be 0 or 1!");
+ spvc_context_destroy(context);
+ return NULL;
+ }
- // Skip readonly buffers
- if (descriptor_set_index != 1) { continue; }
+ // Skip readwrite buffers
+ if (descriptor_set_index != 0) { continue; }
unsigned int binding_index = spvc_compiler_get_decoration(compiler, reflected_resources[i].id, SpvDecorationBinding);
@@ -1493,7 +1515,7 @@ static SPIRVTranspileContext *SDL_ShaderCross_INTERNAL_TranspileFromSPIRV(
binding.desc_set = descriptor_set_index;
binding.binding = binding_index;
binding.msl_buffer = current_num_buffers + binding_index;
- spvc_compiler_msl_add_resource_binding(compiler, &binding);
+ result = spvc_compiler_msl_add_resource_binding(compiler, &binding);
if (result < 0) {
SPVC_ERROR(spvc_compiler_msl_add_resource_binding);
spvc_context_destroy(context);
@@ -1503,46 +1525,30 @@ static SPIRVTranspileContext *SDL_ShaderCross_INTERNAL_TranspileFromSPIRV(
num_buffers += 1;
}
- // Uniform buffers
- result = spvc_resources_get_resource_list_for_type(
- resources,
- SPVC_RESOURCE_TYPE_UNIFORM_BUFFER,
- (const spvc_reflected_resource **)&reflected_resources,
- &num_uniform_buffers);
- if (result < 0) {
- SPVC_ERROR(spvc_resources_get_resource_list_for_type);
- spvc_context_destroy(context);
- return NULL;
- }
-
- for (size_t i = 0; i < num_uniform_buffers; i += 1) {
- if (!spvc_compiler_has_decoration(compiler, reflected_resources[i].id, SpvDecorationDescriptorSet) || !spvc_compiler_has_decoration(compiler, reflected_resources[i].id, SpvDecorationBinding)) {
- SDL_SetError("%s", "Shader resources must have descriptor set and binding index!");
- spvc_context_destroy(context);
- return NULL;
- }
-
+ // Readwrite storage buffers
+ current_num_buffers = num_buffers;
+ for (size_t i = 0; i < num_storage_buffers; i += 1) {
unsigned int descriptor_set_index = spvc_compiler_get_decoration(compiler, reflected_resources[i].id, SpvDecorationDescriptorSet);
- if (descriptor_set_index != 2) {
- SDL_SetError("%s", "Descriptor set index for compute uniform buffer must be 2!");
- spvc_context_destroy(context);
- return NULL;
- }
+
+ // Skip readonly buffers
+ if (descriptor_set_index != 1) { continue; }
unsigned int binding_index = spvc_compiler_get_decoration(compiler, reflected_resources[i].id, SpvDecorationBinding);
binding.stage = executionModel;
binding.desc_set = descriptor_set_index;
binding.binding = binding_index;
- binding.msl_buffer = num_buffers + binding_index;
- spvc_compiler_msl_add_resource_binding(compiler, &binding);
+ binding.msl_buffer = current_num_buffers + binding_index;
+ result = spvc_compiler_msl_add_resource_binding(compiler, &binding);
if (result < 0) {
SPVC_ERROR(spvc_compiler_msl_add_resource_binding);
spvc_context_destroy(context);
return NULL;
}
+
+ num_buffers += 1;
}
- num_buffers += num_uniform_buffers;
+
}
result = spvc_compiler_install_compiler_options(compiler, options);