uniform buffer rebinding

This commit is contained in:
Greg Wells
2025-07-01 12:19:26 -04:00
parent 7c5c333fa2
commit f7f5d4b3a4
5 changed files with 46 additions and 16 deletions

View File

@@ -115,10 +115,16 @@ void metalBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t
if (uniform->uniform->bindings[i].type == GN_UNIFORM_BUFFER_DESCRIPTOR) { if (uniform->uniform->bindings[i].type == GN_UNIFORM_BUFFER_DESCRIPTOR) {
gnBufferUniformInfo info = *(gnBufferUniformInfo*)uniform->uniform->bindings[i].data; gnBufferUniformInfo info = *(gnBufferUniformInfo*)uniform->uniform->bindings[i].data;
[encoder setVertexBuffer:info.buffer->buffer->buffer for (int c = 0; c < buffer->commandBuffer->boundGraphcisPipeline->graphicsPipeline->vertexShaderMaps.uniformBufferMaps.count; c++) {
offset:info.offset metalBindingMap map = buffer->commandBuffer->boundGraphcisPipeline->graphicsPipeline->vertexShaderMaps.uniformBufferMaps.data[c];
atIndex:(info.binding + 1) if (map.set == set && map.binding == uniform->uniform->bindings[i].binding) {
]; [encoder setVertexBuffer:info.buffer->buffer->buffer
offset:info.offset
atIndex:1
];
break;
}
}
} else if (uniform->uniform->bindings[i].type == GN_IMAGE_DESCRIPTOR) { } else if (uniform->uniform->bindings[i].type == GN_IMAGE_DESCRIPTOR) {
for (int c = 0; c < buffer->commandBuffer->boundGraphcisPipeline->graphicsPipeline->fragmentShaderMaps.textureMaps.count; c++) { for (int c = 0; c < buffer->commandBuffer->boundGraphcisPipeline->graphicsPipeline->fragmentShaderMaps.textureMaps.count; c++) {
metalBindingMap map = buffer->commandBuffer->boundGraphcisPipeline->graphicsPipeline->fragmentShaderMaps.textureMaps.data[c]; metalBindingMap map = buffer->commandBuffer->boundGraphcisPipeline->graphicsPipeline->fragmentShaderMaps.textureMaps.data[c];

View File

@@ -5,7 +5,7 @@
typedef struct gnPlatformGraphicsPipeline_t { typedef struct gnPlatformGraphicsPipeline_t {
id<MTLRenderPipelineState> graphicsPipeline; id<MTLRenderPipelineState> graphicsPipeline;
metalBindingMaps fragmentShaderMaps; metalBindingMaps vertexShaderMaps, fragmentShaderMaps;
} gnPlatformGraphicsPipeline; } gnPlatformGraphicsPipeline;
gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gnOutputDevice device, gnGraphicsPipelineInfo info); gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gnOutputDevice device, gnGraphicsPipelineInfo info);

View File

@@ -62,6 +62,7 @@ gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gn
for (int i = 0; i < info.shaderModuleCount; i++) { for (int i = 0; i < info.shaderModuleCount; i++) {
if (info.shaderModules[i]->info.stage == GN_VERTEX_SHADER_MODULE) { if (info.shaderModules[i]->info.stage == GN_VERTEX_SHADER_MODULE) {
[descriptor setVertexFunction:info.shaderModules[i]->shaderModule->function]; [descriptor setVertexFunction:info.shaderModules[i]->shaderModule->function];
graphicsPipeline->graphicsPipeline->vertexShaderMaps = info.shaderModules[i]->shaderModule->maps;
} else if (info.shaderModules[i]->info.stage == GN_FRAGMENT_SHADER_MODULE) { } else if (info.shaderModules[i]->info.stage == GN_FRAGMENT_SHADER_MODULE) {
[descriptor setFragmentFunction:info.shaderModules[i]->shaderModule->function]; [descriptor setFragmentFunction:info.shaderModules[i]->shaderModule->function];
graphicsPipeline->graphicsPipeline->fragmentShaderMaps = info.shaderModules[i]->shaderModule->maps; graphicsPipeline->graphicsPipeline->fragmentShaderMaps = info.shaderModules[i]->shaderModule->maps;

View File

@@ -11,6 +11,7 @@ typedef struct metalBindingMap {
GN_ARRAY_LIST(metalBindingMap); GN_ARRAY_LIST(metalBindingMap);
typedef struct metalBindingMaps { typedef struct metalBindingMaps {
metalBindingMapArrayList uniformBufferMaps;
metalBindingMapArrayList textureMaps; metalBindingMapArrayList textureMaps;
} metalBindingMaps; } metalBindingMaps;

View File

@@ -35,6 +35,35 @@ metalBindingMapArrayList loadTextureBindingInformation(spvc_resources resources,
return bindings; return bindings;
} }
metalBindingMapArrayList loadUniformBufferInformation(spvc_resources resources, spvc_compiler compiler, gnShaderModuleStage stage) {
metalBindingMapArrayList bindings = metalBindingMapArrayListCreate();
const spvc_reflected_resource *list = NULL;
size_t count;
spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count);
for (int i = 0; i < count; i++){
uint32_t set = spvc_compiler_get_decoration(compiler, list[i].id, SpvDecorationDescriptorSet),
binding = spvc_compiler_get_decoration(compiler, list[i].id, SpvDecorationBinding);
uint32_t realBinding = binding;
// if ((stage & GN_VERTEX_SHADER_MODULE) == GN_VERTEX_SHADER_MODULE)
realBinding += 1;
metalBindingMap map = {
.set = set, .binding = binding,
.metalBindingIndex = realBinding
};
metalBindingMapArrayListAdd(&bindings, map);
spvc_compiler_unset_decoration(compiler, list[i].id, SpvDecorationBinding);
spvc_compiler_set_decoration(compiler, list[i].id, SpvDecorationBinding, realBinding);
}
return bindings;
}
gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo) { gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo) {
module->shaderModule = malloc(sizeof(struct gnPlatformShaderModule_t)); module->shaderModule = malloc(sizeof(struct gnPlatformShaderModule_t));
@@ -53,23 +82,13 @@ gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnS
spvc_context_create_compiler(context, SPVC_BACKEND_MSL, ir, SPVC_CAPTURE_MODE_COPY, &compiler); spvc_context_create_compiler(context, SPVC_BACKEND_MSL, ir, SPVC_CAPTURE_MODE_COPY, &compiler);
spvc_compiler_create_shader_resources(compiler, &resources); spvc_compiler_create_shader_resources(compiler, &resources);
spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count);
for (int i = 0; i < count; i++){
uint32_t set = spvc_compiler_get_decoration(compiler, list[i].id, SpvDecorationDescriptorSet),
binding = spvc_compiler_get_decoration(compiler, list[i].id, SpvDecorationBinding);
if ((shaderModuleInfo.stage & GN_VERTEX_SHADER_MODULE) == GN_VERTEX_SHADER_MODULE)
binding += 1;
spvc_compiler_unset_decoration(compiler, list[i].id, SpvDecorationBinding);
spvc_compiler_set_decoration(compiler, list[i].id, SpvDecorationBinding, binding);
}
spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_PUSH_CONSTANT, &list, &count); spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_PUSH_CONSTANT, &list, &count);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
// TODO: get the buffer index // TODO: get the buffer index
} }
module->shaderModule->maps.uniformBufferMaps = loadUniformBufferInformation(resources, compiler, shaderModuleInfo.stage);
module->shaderModule->maps.textureMaps = loadTextureBindingInformation(resources, compiler); module->shaderModule->maps.textureMaps = loadTextureBindingInformation(resources, compiler);
spvc_compiler_create_compiler_options(compiler, &options); spvc_compiler_create_compiler_options(compiler, &options);
@@ -116,6 +135,9 @@ gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnS
return GN_FAILED_TO_FIND_ENTRY_POINT; return GN_FAILED_TO_FIND_ENTRY_POINT;
} }
printf("%s", result);
NSString* functionName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding]; NSString* functionName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
module->shaderModule->function = [shaderLib newFunctionWithName:functionName]; module->shaderModule->function = [shaderLib newFunctionWithName:functionName];