support dynamic uniform buffers on metal
This commit is contained in:
@@ -117,8 +117,31 @@ void metalBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t
|
|||||||
|
|
||||||
[encoder useResources:uniform->uniform->usedResources count:uniform->uniform->usedResourceCount usage:MTLResourceUsageRead stages:MTLRenderStageVertex | MTLRenderStageFragment];
|
[encoder useResources:uniform->uniform->usedResources count:uniform->uniform->usedResourceCount usage:MTLResourceUsageRead stages:MTLRenderStageVertex | MTLRenderStageFragment];
|
||||||
|
|
||||||
[encoder setVertexBuffer:uniform->uniform->argumentBuffers[mtlVertex] offset:0 atIndex:(set + 1)];
|
int startIndex = 0;
|
||||||
[encoder setFragmentBuffer:uniform->uniform->argumentBuffers[mtlFragment] offset:0 atIndex:(set + 1)];
|
for (int i = 0; i < dynamicOffsetCount; i++) {
|
||||||
|
int c = startIndex;
|
||||||
|
for (; c < MAX_METAL_BINDINGS; c++) {
|
||||||
|
if (uniform->uniform->isDynamic[c]) {
|
||||||
|
gnBufferUniformInfo updateInfo = {
|
||||||
|
.binding = c,
|
||||||
|
.dynamic = gnTrue,
|
||||||
|
.offset = dynamicOffsets[i],
|
||||||
|
.size = 0
|
||||||
|
};
|
||||||
|
mtlBufferUniformInfo info = {
|
||||||
|
.baseInfo = &updateInfo,
|
||||||
|
.buffer = (id<MTLBuffer>)uniform->uniform->usedResources[uniform->uniform->indexMap[c]]
|
||||||
|
};
|
||||||
|
mtlUpdateMetalBufferUniform(uniform, &info);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startIndex = c + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
[encoder setVertexBytes:uniform->uniform->argumentBuffers[mtlVertex].contents length:uniform->uniform->encoders[mtlVertex].encodedLength atIndex:(set + 1)];
|
||||||
|
[encoder setFragmentBytes:uniform->uniform->argumentBuffers[mtlFragment].contents length:uniform->uniform->encoders[mtlFragment].encodedLength atIndex:(set + 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
void metalBindVertexBytes(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data) {
|
void metalBindVertexBytes(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data) {
|
||||||
|
@@ -8,6 +8,8 @@ typedef struct metalUniformBinding {
|
|||||||
gnUniformType type;
|
gnUniformType type;
|
||||||
uint32_t binding;
|
uint32_t binding;
|
||||||
void* data;
|
void* data;
|
||||||
|
|
||||||
|
gnBool isDynamic;
|
||||||
} metalUniformBinding;
|
} metalUniformBinding;
|
||||||
|
|
||||||
typedef id<MTLResource> mtlResource;
|
typedef id<MTLResource> mtlResource;
|
||||||
@@ -17,13 +19,21 @@ typedef struct gnPlatformUniform_t {
|
|||||||
gnShaderModuleStage stageUsed[MAX_METAL_BINDINGS];
|
gnShaderModuleStage stageUsed[MAX_METAL_BINDINGS];
|
||||||
id<MTLArgumentEncoder> encoders[mtlMaxStage];
|
id<MTLArgumentEncoder> encoders[mtlMaxStage];
|
||||||
id<MTLBuffer> argumentBuffers[mtlMaxStage];
|
id<MTLBuffer> argumentBuffers[mtlMaxStage];
|
||||||
|
|
||||||
|
|
||||||
mtlResource usedResources[MAX_METAL_BINDINGS];
|
mtlResource usedResources[MAX_METAL_BINDINGS];
|
||||||
int indexMap[MAX_METAL_BINDINGS];
|
int indexMap[MAX_METAL_BINDINGS];
|
||||||
uint32_t usedResourceCount;
|
uint32_t usedResourceCount;
|
||||||
|
|
||||||
|
gnBool isDynamic[MAX_METAL_BINDINGS];
|
||||||
} gnPlatformUniform;
|
} gnPlatformUniform;
|
||||||
|
|
||||||
void updateMetalBufferUniform(gnUniform uniform, gnBufferUniformInfo* info);
|
void updateMetalBufferUniform(gnUniform uniform, gnBufferUniformInfo* info);
|
||||||
void updateMetalStorageUniform(gnUniform uniform, gnStorageUniformInfo* info);
|
void updateMetalStorageUniform(gnUniform uniform, gnStorageUniformInfo* info);
|
||||||
void updateMetalImageUniform(gnUniform uniform, gnImageUniformInfo* info);
|
void updateMetalImageUniform(gnUniform uniform, gnImageUniformInfo* info);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct mtlBufferUniformInfo {
|
||||||
|
gnBufferUniformInfo* baseInfo;
|
||||||
|
id<MTLBuffer> buffer;
|
||||||
|
} mtlBufferUniformInfo;
|
||||||
|
|
||||||
|
void mtlUpdateMetalBufferUniform(gnUniformHandle uniform, mtlBufferUniformInfo* info);
|
||||||
|
@@ -4,16 +4,25 @@
|
|||||||
#include "texture/metal_texture.h"
|
#include "texture/metal_texture.h"
|
||||||
#include <buffer/metal_buffer.h>
|
#include <buffer/metal_buffer.h>
|
||||||
|
|
||||||
void updateMetalBufferUniform(gnUniform uniform, gnBufferUniformInfo* info) {
|
void mtlUpdateMetalBufferUniform(gnUniformHandle uniform, mtlBufferUniformInfo* info) {
|
||||||
if (uniform->uniform->indexMap[info->binding] == -1) {
|
if (uniform->uniform->indexMap[info->baseInfo->binding] == -1) {
|
||||||
uniform->uniform->indexMap[info->binding] = uniform->uniform->usedResourceCount;
|
uniform->uniform->indexMap[info->baseInfo->binding] = uniform->uniform->usedResourceCount;
|
||||||
uniform->uniform->usedResourceCount++;
|
uniform->uniform->usedResourceCount++;
|
||||||
}
|
}
|
||||||
uniform->uniform->usedResources[uniform->uniform->indexMap[info->binding]] = info->buffer->buffer->buffer;
|
uniform->uniform->isDynamic[info->baseInfo->binding] = info->baseInfo->dynamic;
|
||||||
if ((uniform->uniform->stageUsed[info->binding] & GN_VERTEX_SHADER_MODULE) == GN_VERTEX_SHADER_MODULE)
|
uniform->uniform->usedResources[uniform->uniform->indexMap[info->baseInfo->binding]] = info->buffer;
|
||||||
[uniform->uniform->encoders[mtlVertex] setBuffer:info->buffer->buffer->buffer offset:0 atIndex:uniform->uniform->indexMap[info->binding]];
|
if ((uniform->uniform->stageUsed[info->baseInfo->binding] & GN_VERTEX_SHADER_MODULE) == GN_VERTEX_SHADER_MODULE)
|
||||||
if ((uniform->uniform->stageUsed[info->binding] & GN_FRAGMENT_SHADER_MODULE) == GN_FRAGMENT_SHADER_MODULE)
|
[uniform->uniform->encoders[mtlVertex] setBuffer:info->buffer offset:info->baseInfo->offset atIndex:uniform->uniform->indexMap[info->baseInfo->binding]];
|
||||||
[uniform->uniform->encoders[mtlFragment] setBuffer:info->buffer->buffer->buffer offset:0 atIndex:uniform->uniform->index[info->binding]];
|
if ((uniform->uniform->stageUsed[info->baseInfo->binding] & GN_FRAGMENT_SHADER_MODULE) == GN_FRAGMENT_SHADER_MODULE)
|
||||||
|
[uniform->uniform->encoders[mtlFragment] setBuffer:info->buffer offset:info->baseInfo->offset atIndex:uniform->uniform->index[info->baseInfo->binding]];
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateMetalBufferUniform(gnUniform uniform, gnBufferUniformInfo* info) {
|
||||||
|
mtlBufferUniformInfo mtlInfo = {
|
||||||
|
.baseInfo = info,
|
||||||
|
.buffer = info->buffer->buffer->buffer
|
||||||
|
};
|
||||||
|
mtlUpdateMetalBufferUniform(uniform, &mtlInfo);
|
||||||
}
|
}
|
||||||
void updateMetalStorageUniform(gnUniform uniform, gnStorageUniformInfo* info) {
|
void updateMetalStorageUniform(gnUniform uniform, gnStorageUniformInfo* info) {
|
||||||
if (uniform->uniform->indexMap[info->binding] == -1) {
|
if (uniform->uniform->indexMap[info->binding] == -1) {
|
||||||
@@ -22,9 +31,9 @@ void updateMetalStorageUniform(gnUniform uniform, gnStorageUniformInfo* info) {
|
|||||||
}
|
}
|
||||||
uniform->uniform->usedResources[uniform->uniform->indexMap[info->binding]] = info->buffer->buffer->buffer;
|
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)
|
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]];
|
[uniform->uniform->encoders[mtlVertex] setBuffer:info->buffer->buffer->buffer offset:info->offset atIndex:uniform->uniform->indexMap[info->binding]];
|
||||||
if ((uniform->uniform->stageUsed[info->binding] & GN_FRAGMENT_SHADER_MODULE) == GN_FRAGMENT_SHADER_MODULE)
|
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]];
|
[uniform->uniform->encoders[mtlFragment] setBuffer:info->buffer->buffer->buffer offset:info->offset atIndex:uniform->uniform->index[info->binding]];
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateMetalImageUniform(gnUniform uniform, gnImageUniformInfo* info) {
|
void updateMetalImageUniform(gnUniform uniform, gnImageUniformInfo* info) {
|
||||||
|
Reference in New Issue
Block a user