actually get uniforms to work (with my test case)

This commit is contained in:
Gregory Wells
2025-07-21 09:33:05 -04:00
parent 3497e32e47
commit 6b71e44d21
5 changed files with 134 additions and 30 deletions

View File

@@ -114,6 +114,9 @@ void metalDrawIndexed(gnCommandBufferHandle buffer, gnIndexType type, int indexC
void metalBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set) { void metalBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set) {
id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder; id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
[encoder useResources:uniform->uniform->resources.data count:uniform->uniform->resources.count usage:MTLResourceUsageRead stages:MTLRenderStageFragment];
[encoder setFragmentBuffer:uniform->uniform->argumentBuffer offset:0 atIndex:2];
// for (int i = 0; i < uniform->uniform->bindingCount; i++) { // for (int i = 0; i < uniform->uniform->bindingCount; i++) {
// 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;

View File

@@ -19,6 +19,7 @@ gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnS
mtlShader shader = mtlCompileShader(shaderModuleInfo.code, shaderModuleInfo.size / 4, &options); mtlShader shader = mtlCompileShader(shaderModuleInfo.code, shaderModuleInfo.size / 4, &options);
const char* res = shader.code; const char* res = shader.code;
if (res == NULL) return GN_FAILED_TO_CONVERT_SHADER_CODE; if (res == NULL) return GN_FAILED_TO_CONVERT_SHADER_CODE;
printf("res: %s\n", res);
NSError* error = nil; NSError* error = nil;
MTLCompileOptions* mtloptions = nil; MTLCompileOptions* mtloptions = nil;
@@ -29,6 +30,8 @@ gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnS
gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){
.message = gnCombineStrings(gnCreateString("Failed to compile metal library "), errorString) .message = gnCombineStrings(gnCreateString("Failed to compile metal library "), errorString)
}); });
[shaderLib release];
free((void*)res);
return GN_FAILED_TO_CREATE_SHADER_MODULE; return GN_FAILED_TO_CREATE_SHADER_MODULE;
} }
@@ -48,7 +51,7 @@ gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnS
module->shaderModule->function = [shaderLib newFunctionWithName:functionName]; module->shaderModule->function = [shaderLib newFunctionWithName:functionName];
[shaderLib release]; [shaderLib release];
free((void*)res); if (options.stage == vertex) free((void*)res);
module->shaderModule->shaderMap = shader.map; module->shaderModule->shaderMap = shader.map;
return GN_SUCCESS; return GN_SUCCESS;
} }

View File

@@ -1,6 +1,8 @@
#pragma once #pragma once
#include "uniforms/gryphn_uniform.h" #include "uniforms/gryphn_uniform.h"
#include <Metal/Metal.h>
#include <uniforms/gryphn_uniform_pool.h> #include <uniforms/gryphn_uniform_pool.h>
#include "shader_module/metal_shader_module.h"
typedef struct metalUniformBinding { typedef struct metalUniformBinding {
gnUniformType type; gnUniformType type;
@@ -8,9 +10,15 @@ typedef struct metalUniformBinding {
void* data; void* data;
} metalUniformBinding; } metalUniformBinding;
typedef id<MTLResource> mtlResource;
GN_ARRAY_LIST(mtlResource);
typedef struct gnPlatformUniform_t { typedef struct gnPlatformUniform_t {
uint32_t bindingCount; uint32_t index[MAX_METAL_BINDINGS];
metalUniformBinding* bindings; id<MTLArgumentEncoder> encoder;
id<MTLBuffer> argumentBuffer;
mtlResourceArrayList resources;
} gnPlatformUniform; } gnPlatformUniform;
void updateMetalBufferUniform(gnUniform uniform, gnBufferUniformInfo* info); void updateMetalBufferUniform(gnUniform uniform, gnBufferUniformInfo* info);

View File

@@ -1,32 +1,47 @@
#include <uniforms/gryphn_uniform.h> #include <uniforms/gryphn_uniform.h>
#include "metal_uniform.h" #include "metal_uniform.h"
#include "devices/metal_output_devices.h"
#include "texture/metal_texture.h"
#include <buffer/metal_buffer.h>
void updateMetalBufferUniform(gnUniform uniform, gnBufferUniformInfo* info) { void updateMetalBufferUniform(gnUniform uniform, gnBufferUniformInfo* info) {
for (int i = 0; i < uniform->uniform->bindingCount; i++) { // [uniform->uniform->encoder setBuffer:info->buffer->buffer->buffer offset:0 atIndex:0];
if (uniform->uniform->bindings[i].binding == info->binding) {
uniform->uniform->bindings[i].data = malloc(sizeof(gnBufferUniformInfo));
memcpy(uniform->uniform->bindings[i].data, info, sizeof(gnBufferUniformInfo));
break;
}
}
} }
void updateMetalStorageUniform(gnUniform uniform, gnStorageUniformInfo* info) { void updateMetalStorageUniform(gnUniform uniform, gnStorageUniformInfo* info) {
for (int i = 0; i < uniform->uniform->bindingCount; i++) { // [uniform->uniform->encoder setBuffer:info->buffer->buffer->buffer offset:0 atIndex:uniform->uniform->index[info->binding]];
if (uniform->uniform->bindings[i].binding == info->binding) { // for (int i = 0; i < uniform->uniform->bindingCount; i++) {
uniform->uniform->bindings[i].data = malloc(sizeof(gnStorageUniformInfo)); // if (uniform->uniform->bindings[i].binding == info->binding) {
memcpy(uniform->uniform->bindings[i].data, info, sizeof(gnStorageUniformInfo)); // uniform->uniform->bindings[i].data = malloc(sizeof(gnStorageUniformInfo));
break; // memcpy(uniform->uniform->bindings[i].data, info, sizeof(gnStorageUniformInfo));
} // break;
} // }
// }
} }
void updateMetalImageUniform(gnUniform uniform, gnImageUniformInfo* info) { void updateMetalImageUniform(gnUniform uniform, gnImageUniformInfo* info) {
for (int i = 0; i < uniform->uniform->bindingCount; i++) { printf("%p\n", info->texture->texture->texture);
if (uniform->uniform->bindings[i].binding == info->binding) { [uniform->uniform->encoder setTexture:info->texture->texture->texture atIndex:uniform->uniform->index[info->binding]];
uniform->uniform->bindings[i].data = malloc(sizeof(gnImageUniformInfo)); [uniform->uniform->encoder setSamplerState:info->texture->texture->sampler atIndex:uniform->uniform->index[info->binding] + 1];
memcpy(uniform->uniform->bindings[i].data, info, sizeof(gnImageUniformInfo));
break; uniform->uniform->resources = mtlResourceArrayListCreate();
} mtlResourceArrayListAdd(&uniform->uniform->resources, info->texture->texture->texture);
} // mtlResourceArrayListAdd(&uniform->uniform->resources, info->texture->texture->sampler);
// printf("updating metal image uniform %i\n", uniform->uniform->index[info->binding]);
// printf("binding: %i\n", info->binding);
// printf("mapped index: %i\n", uniform->uniform->index[info->binding]);
// id<MTLBuffer> buffer = [uniform->pool->device->outputDevice->device newBufferWithLength:sizeof(int) options:MTLResourceStorageModeShared];
// printf("uniform %p | uniform->uniform %p | encoder %p\n", uniform, uniform->uniform, uniform->uniform->encoder);
// [uniform->uniform->encoder setBuffer:buffer offset:0 atIndex:0];
//info->binding
// for (int i = 0; i < uniform->uniform->bindingCount; i++) {
// if (uniform->uniform->bindings[i].binding == info->binding) {
// uniform->uniform->bindings[i].data = malloc(sizeof(gnImageUniformInfo));
// memcpy(uniform->uniform->bindings[i].data, info, sizeof(gnImageUniformInfo));
// break;
// }
// }
} }

View File

@@ -1,6 +1,7 @@
#include <uniforms/gryphn_uniform_pool.h> #include <uniforms/gryphn_uniform_pool.h>
#include <uniforms/gryphn_uniform.h> #include <uniforms/gryphn_uniform.h>
#include "metal_uniform.h" #include "metal_uniform.h"
#include "devices/metal_output_devices.h"
gnReturnCode createMetalUniformPool(gnUniformPool pool, gnDeviceHandle device) { gnReturnCode createMetalUniformPool(gnUniformPool pool, gnDeviceHandle device) {
return GN_SUCCESS; return GN_SUCCESS;
@@ -11,12 +12,86 @@ gnUniform* allocateMetalUniforms(gnUniformPool pool, const gnUniformAllocationIn
for (int i = 0; i < allocInfo.setCount; i++) { for (int i = 0; i < allocInfo.setCount; i++) {
uniforms[i] = malloc(sizeof(struct gnUniform_t)); uniforms[i] = malloc(sizeof(struct gnUniform_t));
uniforms[i]->uniform = malloc(sizeof(gnPlatformUniform)); uniforms[i]->uniform = malloc(sizeof(gnPlatformUniform));
uniforms[i]->uniform->bindingCount = allocInfo.sets[i].uniformBindingCount;
uniforms[i]->uniform->bindings = malloc(sizeof(metalUniformBinding) * allocInfo.sets[i].uniformBindingCount); MTLArgumentDescriptor *texDesc = [[MTLArgumentDescriptor alloc] init];
for (int c = 0; c < allocInfo.sets[i].uniformBindingCount; c++) { texDesc.dataType = MTLDataTypeTexture;
uniforms[i]->uniform->bindings[c].type = allocInfo.sets[i].uniformBindings[c].type; texDesc.index = 0;
uniforms[i]->uniform->bindings[c].binding = allocInfo.sets[i].uniformBindings[c].binding; texDesc.access = MTLBindingAccessReadOnly;
}
MTLArgumentDescriptor *samplerDesc = [[MTLArgumentDescriptor alloc] init];
samplerDesc.dataType = MTLDataTypeSampler;
samplerDesc.index = 1;
uniforms[i]->uniform->encoder = [pool->device->outputDevice->device newArgumentEncoderWithArguments:@[texDesc, samplerDesc]];
uniforms[i]->uniform->argumentBuffer = [pool->device->outputDevice->device newBufferWithLength:[uniforms[i]->uniform->encoder encodedLength]
options:MTLResourceStorageModeShared];
[uniforms[i]->uniform->encoder setArgumentBuffer:uniforms[i]->uniform->argumentBuffer offset:0];
// int currentIndex = 0;
// NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:allocInfo.sets[i].uniformBindingCount];
// MTLArgumentDescriptor* textureDescriptor = [[MTLArgumentDescriptor alloc] init];
// textureDescriptor.dataType = MTLDataTypeTexture;
// textureDescriptor.index = 0;
// textureDescriptor.arrayLength = 1;
// textureDescriptor.access = MTLBindingAccessReadOnly;
// textureDescriptor.textureType = MTLTextureType2D;
// MTLArgumentDescriptor* samplerDescriptor = [[MTLArgumentDescriptor alloc] init];
// samplerDescriptor.dataType = MTLDataTypeSampler;
// samplerDescriptor.index = 1;
// samplerDescriptor.arrayLength = 1;
// samplerDescriptor.access = MTLBindingAccessReadOnly;
// [arguments addObject:textureDescriptor];
// [arguments addObject:samplerDescriptor];
// for (int c = 0; c < allocInfo.sets[i].uniformBindingCount; c++) {
// if (allocInfo.sets[i].uniformBindings[c].type == GN_IMAGE_DESCRIPTOR) {
// MTLArgumentDescriptor* textureDescriptor = [[MTLArgumentDescriptor alloc] init];
// textureDescriptor.dataType = MTLDataTypeTexture;
// textureDescriptor.index = 0;
// textureDescriptor.arrayLength = 1;
// textureDescriptor.access = MTLBindingAccessReadOnly;
// textureDescriptor.textureType = MTLTextureType2DMultisample;
// [arguments addObject:textureDescriptor];
// MTLArgumentDescriptor* samplerDescriptor = [[MTLArgumentDescriptor alloc] init];
// samplerDescriptor.dataType = MTLDataTypeSampler;
// samplerDescriptor.index = 1;
// samplerDescriptor.arrayLength = 1;
// samplerDescriptor.access = MTLBindingAccessReadOnly;
// [arguments addObject:samplerDescriptor];
// uniforms[i]->uniform->index[allocInfo.sets[i].uniformBindings[c].binding] = currentIndex;
// currentIndex += 2;
// }
// }
// for (int c = 0; c < allocInfo.sets[i].uniformBindingCount; c++) {
// if (allocInfo.sets[i].uniformBindings[c].type == GN_UNIFORM_BUFFER_DESCRIPTOR ||
// allocInfo.sets[i].uniformBindings[c].type == GN_SHADER_STORE_BUFFER_DESCRIPTOR) {
// // MTLArgumentDescriptor* bufferDescriptor = [[MTLArgumentDescriptor alloc] init];
// // bufferDescriptor.dataType = MTLDataTypePointer;
// // bufferDescriptor.index = currentIndex;
// // bufferDescriptor.arrayLength = 1;
// // bufferDescriptor.access = MTLBindingAccessReadOnly;
// // [arguments addObject:bufferDescriptor];
// // uniforms[i]->uniform->index[allocInfo.sets[i].uniformBindings[c].binding] = currentIndex;
// // currentIndex++;
// }
// }
// if (arguments.count > 0) {
// uniforms[i]->uniform->encoder = [pool->device->outputDevice->device newArgumentEncoderWithArguments:arguments];
// uniforms[i]->uniform->argumentBuffer = [pool->device->outputDevice->device newBufferWithLength:uniforms[i]->uniform->encoder.encodedLength options:MTLResourceStorageModeShared];
// [uniforms[i]->uniform->encoder setArgumentBuffer:uniforms[i]->uniform->argumentBuffer offset:0];
// }
// printf("argument encoder %p, argument buffer %p\n", uniforms[i]->uniform->encoder, uniforms[i]->uniform->argumentBuffer);
// for (int k = 0; k < arguments.count; k++) [[arguments objectAtIndex:k] release];
} }
return uniforms; return uniforms;
} }