finish redoing metal shader workflow

This commit is contained in:
Gregory Wells
2025-07-21 13:27:40 -04:00
parent 46d1c2e802
commit 1f85aa30bd
11 changed files with 242 additions and 228 deletions

View File

@@ -14,8 +14,10 @@ typedef id<MTLResource> mtlResource;
typedef struct gnPlatformUniform_t {
uint32_t index[MAX_METAL_BINDINGS];
id<MTLArgumentEncoder> encoder;
id<MTLBuffer> argumentBuffer;
gnShaderModuleStage stageUsed[MAX_METAL_BINDINGS];
id<MTLArgumentEncoder> encoders[mtlMaxStage];
id<MTLBuffer> argumentBuffers[mtlMaxStage];
mtlResource usedResources[MAX_METAL_BINDINGS];
int indexMap[MAX_METAL_BINDINGS];

View File

@@ -5,54 +5,40 @@
#include <buffer/metal_buffer.h>
void updateMetalBufferUniform(gnUniform uniform, gnBufferUniformInfo* info) {
// [uniform->uniform->encoder setBuffer:info->buffer->buffer->buffer offset:0 atIndex:0];
}
void updateMetalStorageUniform(gnUniform uniform, gnStorageUniformInfo* info) {
// [uniform->uniform->encoder setBuffer:info->buffer->buffer->buffer offset:0 atIndex:uniform->uniform->index[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(gnStorageUniformInfo));
// memcpy(uniform->uniform->bindings[i].data, info, sizeof(gnStorageUniformInfo));
// break;
// }
// }
}
void updateMetalImageUniform(gnUniform uniform, gnImageUniformInfo* info) {
// mtlResource usedResources[MAX_METAL_BINDINGS];
// uint32_t indexMap[MAX_METAL_BINDINGS];
// uint32_t usedResourceCount;
if (uniform->uniform->indexMap[info->binding] == -1) {
uniform->uniform->indexMap[info->binding] = uniform->uniform->usedResourceCount;
uniform->uniform->usedResourceCount++;
}
uniform->uniform->usedResources[uniform->uniform->indexMap[info->binding]] = info->texture->texture->texture;
[uniform->uniform->encoder setTexture:info->texture->texture->texture atIndex:uniform->uniform->index[info->binding]];
[uniform->uniform->encoder setSamplerState:info->texture->texture->sampler atIndex:uniform->uniform->index[info->binding] + 1];
// 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;
// }
// }
uniform->uniform->usedResources[uniform->uniform->indexMap[info->binding]] = info->buffer->buffer->buffer;
if ((uniform->uniform->stageUsed[info->binding] & GN_VERTEX_SHADER_MODULE) == GN_VERTEX_SHADER_MODULE)
[uniform->uniform->encoders[mtlVertex] setBuffer:info->buffer->buffer->buffer offset:0 atIndex:uniform->uniform->indexMap[info->binding]];
if ((uniform->uniform->stageUsed[info->binding] & GN_FRAGMENT_SHADER_MODULE) == GN_FRAGMENT_SHADER_MODULE)
[uniform->uniform->encoders[mtlFragment] setBuffer:info->buffer->buffer->buffer offset:0 atIndex:uniform->uniform->index[info->binding]];
}
void updateMetalStorageUniform(gnUniform uniform, gnStorageUniformInfo* info) {
if (uniform->uniform->indexMap[info->binding] == -1) {
uniform->uniform->indexMap[info->binding] = uniform->uniform->usedResourceCount;
uniform->uniform->usedResourceCount++;
}
uniform->uniform->usedResources[uniform->uniform->indexMap[info->binding]] = info->buffer->buffer->buffer;
if ((uniform->uniform->stageUsed[info->binding] & GN_VERTEX_SHADER_MODULE) == GN_VERTEX_SHADER_MODULE)
[uniform->uniform->encoders[mtlVertex] setBuffer:info->buffer->buffer->buffer offset:0 atIndex:uniform->uniform->indexMap[info->binding]];
if ((uniform->uniform->stageUsed[info->binding] & GN_FRAGMENT_SHADER_MODULE) == GN_FRAGMENT_SHADER_MODULE)
[uniform->uniform->encoders[mtlFragment] setBuffer:info->buffer->buffer->buffer offset:0 atIndex:uniform->uniform->index[info->binding]];
}
void updateMetalImageUniform(gnUniform uniform, gnImageUniformInfo* info) {
if (uniform->uniform->indexMap[info->binding] == -1) {
uniform->uniform->indexMap[info->binding] = uniform->uniform->usedResourceCount;
uniform->uniform->usedResourceCount++;
}
uniform->uniform->usedResources[uniform->uniform->indexMap[info->binding]] = info->texture->texture->texture;
if ((uniform->uniform->stageUsed[info->binding] & GN_VERTEX_SHADER_MODULE) == GN_VERTEX_SHADER_MODULE) {
[uniform->uniform->encoders[mtlVertex] setTexture:info->texture->texture->texture atIndex:uniform->uniform->indexMap[info->binding]];
[uniform->uniform->encoders[mtlVertex] setSamplerState:info->texture->texture->sampler atIndex:uniform->uniform->indexMap[info->binding] + 1];
}
if ((uniform->uniform->stageUsed[info->binding] & GN_FRAGMENT_SHADER_MODULE) == GN_FRAGMENT_SHADER_MODULE) {
[uniform->uniform->encoders[mtlFragment] setTexture:info->texture->texture->texture atIndex:uniform->uniform->index[info->binding]];
[uniform->uniform->encoders[mtlFragment] setSamplerState:info->texture->texture->sampler atIndex:uniform->uniform->index[info->binding] + 1];
}
}

View File

@@ -12,55 +12,64 @@ gnUniform* allocateMetalUniforms(gnUniformPool pool, const gnUniformAllocationIn
for (int i = 0; i < allocInfo.setCount; i++) {
uniforms[i] = malloc(sizeof(struct gnUniform_t));
uniforms[i]->uniform = malloc(sizeof(gnPlatformUniform));
int currentIndex = 0;
NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:allocInfo.sets[i].uniformBindingCount];
NSMutableArray* totalArguments = [NSMutableArray arrayWithCapacity:allocInfo.sets[i].uniformBindingCount];
NSMutableArray* vertexArguments = [NSMutableArray arrayWithCapacity:allocInfo.sets[i].uniformBindingCount];
NSMutableArray* fragmentArguments = [NSMutableArray arrayWithCapacity:allocInfo.sets[i].uniformBindingCount];
for (int c = 0; c < allocInfo.sets[i].uniformBindingCount; c++) {
if (allocInfo.sets[i].uniformBindings[c].type == GN_COMBINED_IMAGE_SAMPLER_DESCRIPTOR) {
MTLArgumentDescriptor* textureDescriptor = [[MTLArgumentDescriptor alloc] init];
textureDescriptor.dataType = MTLDataTypeTexture;
textureDescriptor.index = 0;
textureDescriptor.arrayLength = 1;
textureDescriptor.access = MTLBindingAccessReadOnly;
textureDescriptor.textureType = MTLTextureType2DMultisample;
[arguments addObject:textureDescriptor];
gnUniformBinding binding = allocInfo.sets[i].uniformBindings[c];
if (binding.type == GN_UNIFORM_BUFFER_DESCRIPTOR ||
binding.type == GN_SHADER_STORE_BUFFER_DESCRIPTOR) {
MTLArgumentDescriptor* descriptor = [[MTLArgumentDescriptor alloc] init];
descriptor.dataType = MTLDataTypePointer;
descriptor.index = 0;
descriptor.arrayLength = 1;
descriptor.access = MTLBindingAccessReadOnly;
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;
if ((binding.stage & GN_VERTEX_SHADER_MODULE) == GN_VERTEX_SHADER_MODULE) [vertexArguments addObject:descriptor];
if ((binding.stage & GN_FRAGMENT_SHADER_MODULE) == GN_FRAGMENT_SHADER_MODULE) [fragmentArguments addObject:descriptor];
[totalArguments addObject:descriptor];
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++;
} else if (allocInfo.sets[i].uniformBindings[c].type == GN_COMBINED_IMAGE_SAMPLER_DESCRIPTOR) {
MTLArgumentDescriptor* textureDescriptor = [[MTLArgumentDescriptor alloc] init];
textureDescriptor.dataType = MTLDataTypeTexture;
textureDescriptor.index = 1;
textureDescriptor.arrayLength = 1;
textureDescriptor.access = MTLBindingAccessReadOnly;
if ((binding.stage & GN_VERTEX_SHADER_MODULE) == GN_VERTEX_SHADER_MODULE) [vertexArguments addObject:textureDescriptor];
if ((binding.stage & GN_FRAGMENT_SHADER_MODULE) == GN_FRAGMENT_SHADER_MODULE) [fragmentArguments addObject:textureDescriptor];
[totalArguments addObject:textureDescriptor];
MTLArgumentDescriptor* samplerDescriptor = [[MTLArgumentDescriptor alloc] init];
samplerDescriptor.dataType = MTLDataTypeSampler;
samplerDescriptor.index = 2;
samplerDescriptor.arrayLength = 1;
samplerDescriptor.access = MTLBindingAccessReadOnly;
if ((binding.stage & GN_VERTEX_SHADER_MODULE) == GN_VERTEX_SHADER_MODULE) [vertexArguments addObject:samplerDescriptor];
if ((binding.stage & GN_FRAGMENT_SHADER_MODULE) == GN_FRAGMENT_SHADER_MODULE) [fragmentArguments addObject:samplerDescriptor];
[totalArguments addObject:samplerDescriptor];
uniforms[i]->uniform->index[binding.binding] = currentIndex;
currentIndex += 2;
}
uniforms[i]->uniform->stageUsed[binding.binding] = binding.stage;
}
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];
if (vertexArguments.count > 0) {
uniforms[i]->uniform->encoders[mtlVertex] = [pool->device->outputDevice->device newArgumentEncoderWithArguments:vertexArguments];
uniforms[i]->uniform->argumentBuffers[mtlVertex] = [pool->device->outputDevice->device newBufferWithLength:uniforms[i]->uniform->encoders[mtlVertex].encodedLength options:MTLResourceStorageModeShared];
[uniforms[i]->uniform->encoders[mtlVertex] setArgumentBuffer:uniforms[i]->uniform->argumentBuffers[mtlVertex] offset:0];
}
for (int k = 0; k < arguments.count; k++) [[arguments objectAtIndex:k] release];
if (fragmentArguments.count > 0) {
uniforms[i]->uniform->encoders[mtlFragment] = [pool->device->outputDevice->device newArgumentEncoderWithArguments:fragmentArguments];
uniforms[i]->uniform->argumentBuffers[mtlFragment] = [pool->device->outputDevice->device newBufferWithLength:uniforms[i]->uniform->encoders[mtlFragment].encodedLength options:MTLResourceStorageModeShared];
[uniforms[i]->uniform->encoders[mtlFragment] setArgumentBuffer:uniforms[i]->uniform->argumentBuffers[mtlFragment] offset:0];
}
for (int k = 0; k < totalArguments.count; k++) [[totalArguments objectAtIndex:k] release];
[totalArguments release];
for (int g = 0; g < MAX_METAL_BINDINGS; g++) uniforms[i]->uniform->indexMap[g] = -1;
}
return uniforms;