support dynamic uniform buffers on vulkan

This commit is contained in:
Gregory Wells
2025-07-23 11:37:12 -04:00
parent 9c03d38f51
commit 0da1a8a4f6
14 changed files with 22 additions and 13 deletions

View File

@@ -37,6 +37,7 @@ gnDeviceFunctions loadMetalDeviceFunctions() {
._gnCreateBuffer = createMetalBuffer, ._gnCreateBuffer = createMetalBuffer,
._gnBufferData = metalBufferData, ._gnBufferData = metalBufferData,
._gnBufferSubData = metalBufferSubData,
._gnMapBuffer = mapMetalBuffer, ._gnMapBuffer = mapMetalBuffer,
._gnDestroyBuffer = destroyMetalBuffer, ._gnDestroyBuffer = destroyMetalBuffer,

View File

@@ -11,5 +11,6 @@ struct gnPlatformBuffer_t {
gnReturnCode createMetalBuffer(gnBufferHandle buffer, gnDevice device, gnBufferInfo info); gnReturnCode createMetalBuffer(gnBufferHandle buffer, gnDevice device, gnBufferInfo info);
void metalBufferData(gnBufferHandle buffer, size_t dataSize, void* data); void metalBufferData(gnBufferHandle buffer, size_t dataSize, void* data);
void metalBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, gnBufferMemory data);
void* mapMetalBuffer(gnBufferHandle buffer); void* mapMetalBuffer(gnBufferHandle buffer);
void destroyMetalBuffer(gnBufferHandle buffer); void destroyMetalBuffer(gnBufferHandle buffer);

View File

@@ -14,9 +14,12 @@ gnReturnCode createMetalBuffer(gnBufferHandle buffer, gnDevice device, gnBufferI
return GN_SUCCESS; return GN_SUCCESS;
} }
void metalBufferData(gnBufferHandle buffer, size_t dataSize, void* data) { void metalBufferData(gnBufferHandle buffer, size_t dataSize, void* data) {
metalBufferSubData(buffer, 0, dataSize, data);
}
void metalBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, gnBufferMemory data) {
void* bufferData; void* bufferData;
if (buffer->buffer->useStagingBuffer) { if (buffer->buffer->useStagingBuffer) {
memcpy(buffer->buffer->stagingBuffer.contents, data, dataSize); memcpy(buffer->buffer->stagingBuffer.contents + offset, data, dataSize);
id<MTLCommandBuffer> commandBuffer = [buffer->device->outputDevice->transferQueue commandBuffer]; id<MTLCommandBuffer> commandBuffer = [buffer->device->outputDevice->transferQueue commandBuffer];
id<MTLBlitCommandEncoder> encoder = [commandBuffer blitCommandEncoder]; id<MTLBlitCommandEncoder> encoder = [commandBuffer blitCommandEncoder];
[encoder copyFromBuffer:buffer->buffer->stagingBuffer sourceOffset:0 toBuffer:buffer->buffer->buffer destinationOffset:0 size:dataSize]; [encoder copyFromBuffer:buffer->buffer->stagingBuffer sourceOffset:0 toBuffer:buffer->buffer->buffer destinationOffset:0 size:dataSize];
@@ -24,7 +27,7 @@ void metalBufferData(gnBufferHandle buffer, size_t dataSize, void* data) {
[commandBuffer commit]; [commandBuffer commit];
[commandBuffer waitUntilCompleted]; [commandBuffer waitUntilCompleted];
} else } else
memcpy(buffer->buffer->buffer.contents, data, dataSize); memcpy(buffer->buffer->buffer.contents + offset, data, dataSize);
} }
void* mapMetalBuffer(gnBufferHandle buffer) { void* mapMetalBuffer(gnBufferHandle buffer) {
return buffer->buffer->buffer.contents; return buffer->buffer->buffer.contents;

View File

@@ -69,12 +69,12 @@ void drawIndexed(gnCommandBufferHandle buffer, gnIndexType type, int indexCount,
buffer->commandBuffer->changedBuffer = gnFalse; buffer->commandBuffer->changedBuffer = gnFalse;
} }
void bindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set) { void bindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set, uint32_t dynamicOffsetCount, uint32_t* dynamicOffsets) {
vkCmdBindDescriptorSets( vkCmdBindDescriptorSets(
buffer->commandBuffer->buffer, buffer->commandBuffer->buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS, VK_PIPELINE_BIND_POINT_GRAPHICS,
buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->pipelineLayout, set, 1, buffer->commandBuffer->boundGraphicsPipeline->graphicsPipeline->pipelineLayout, set, 1,
&uniform->uniform->set, 0, NULL &uniform->uniform->set, dynamicOffsetCount, dynamicOffsets
); );
} }

View File

@@ -17,5 +17,5 @@ void setScissor(gnCommandBuffer buffer, gnScissor scissor);
void bindBuffer(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type); void bindBuffer(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type);
void draw(gnCommandBuffer buffer, int vertexCount, int firstVertex, int instanceCount, int firstInstance); void draw(gnCommandBuffer buffer, int vertexCount, int firstVertex, int instanceCount, int firstInstance);
void drawIndexed(gnCommandBufferHandle buffer, gnIndexType type, int indexCount, int firstIndex, int vertexOffset, int instanceCount, int firstInstance); void drawIndexed(gnCommandBufferHandle buffer, gnIndexType type, int indexCount, int firstIndex, int vertexOffset, int instanceCount, int firstInstance);
void bindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set); void bindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set, uint32_t dynamicOffsetCount, uint32_t* dynamicOffsets);
void pushConstant(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data); void pushConstant(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data);

View File

@@ -13,7 +13,7 @@ void updateBufferUniform(gnUniform uniform, gnBufferUniformInfo* info) {
VkWriteDescriptorSet write = { VkWriteDescriptorSet write = {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, .descriptorType = (info->dynamic) ? VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1, .descriptorCount = 1,
.pBufferInfo = &bufferInfo, .pBufferInfo = &bufferInfo,
.dstSet = uniform->uniform->set, .dstSet = uniform->uniform->set,

View File

@@ -4,6 +4,7 @@
VkDescriptorType vkGryphnUniformType(gnUniformType type) { VkDescriptorType vkGryphnUniformType(gnUniformType type) {
switch(type) { switch(type) {
case GN_UNIFORM_BUFFER_DESCRIPTOR: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; case GN_UNIFORM_BUFFER_DESCRIPTOR: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
case GN_DYNAMIC_UNIFORM_BUFFER_DESCRIPTOR: return VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC;
case GN_SHADER_STORE_BUFFER_DESCRIPTOR: return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; case GN_SHADER_STORE_BUFFER_DESCRIPTOR: return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
case GN_COMBINED_IMAGE_SAMPLER_DESCRIPTOR: return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; case GN_COMBINED_IMAGE_SAMPLER_DESCRIPTOR: return VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
case GN_UNIFORM_TYPE_MAX: return VK_DESCRIPTOR_TYPE_MAX_ENUM; case GN_UNIFORM_TYPE_MAX: return VK_DESCRIPTOR_TYPE_MAX_ENUM;

View File

@@ -19,8 +19,8 @@ void gnCommandSetViewport(gnCommandBufferHandle buffer, gnViewport viewport) {
void gnCommandSetScissor(gnCommandBufferHandle buffer, gnScissor scissor) { void gnCommandSetScissor(gnCommandBufferHandle buffer, gnScissor scissor) {
buffer->commandPool->instance->callingLayer->commandFunctions._gnCommandSetScissor(buffer, scissor); buffer->commandPool->instance->callingLayer->commandFunctions._gnCommandSetScissor(buffer, scissor);
} }
void gnCommandBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set) { void gnCommandBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set, uint32_t dynamicOffsetCount, uint32_t* dynamicOffsets) {
buffer->commandPool->instance->callingLayer->commandFunctions._gnCommandBindUniform(buffer, uniform, set); buffer->commandPool->instance->callingLayer->commandFunctions._gnCommandBindUniform(buffer, uniform, set, dynamicOffsetCount, dynamicOffsets);
} }
void gnCommandBindBuffer(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type) { void gnCommandBindBuffer(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type) {
buffer->commandPool->instance->callingLayer->commandFunctions._gnCommandBindBuffer(buffer, bufferToBind, type); buffer->commandPool->instance->callingLayer->commandFunctions._gnCommandBindBuffer(buffer, bufferToBind, type);

View File

@@ -8,7 +8,7 @@ void gnCommandEndRenderPass(gnCommandBufferHandle buffer);
void gnCommandBindGraphicsPipeline(gnCommandBufferHandle buffer, gnGraphicsPipelineHandle graphicsPipeline); void gnCommandBindGraphicsPipeline(gnCommandBufferHandle buffer, gnGraphicsPipelineHandle graphicsPipeline);
void gnCommandSetViewport(gnCommandBufferHandle buffer, gnViewport viewport); void gnCommandSetViewport(gnCommandBufferHandle buffer, gnViewport viewport);
void gnCommandSetScissor(gnCommandBufferHandle buffer, gnScissor scissor); void gnCommandSetScissor(gnCommandBufferHandle buffer, gnScissor scissor);
void gnCommandBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set); void gnCommandBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set, uint32_t dynamicOffsetCount, uint32_t* dynamicOffsets);
void gnCommandPushConstant(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data); void gnCommandPushConstant(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data);
#include "buffers/gryphn_buffer.h" #include "buffers/gryphn_buffer.h"

View File

@@ -2,6 +2,7 @@
#include "stdint.h" #include "stdint.h"
#include "stdlib.h" #include "stdlib.h"
#include "utils/lists/gryphn_array_list.h" #include "utils/lists/gryphn_array_list.h"
#include "utils/gryphn_bool.h"
#include "gryphn_handles.h" #include "gryphn_handles.h"
typedef struct gnBufferUniformInfo { typedef struct gnBufferUniformInfo {
@@ -9,6 +10,7 @@ typedef struct gnBufferUniformInfo {
gnBuffer buffer; gnBuffer buffer;
size_t offset; size_t offset;
size_t size; size_t size;
gnBool dynamic;
} gnBufferUniformInfo; } gnBufferUniformInfo;
typedef struct gnStorageUniformInfo { typedef struct gnStorageUniformInfo {

View File

@@ -4,6 +4,7 @@
typedef enum gnUniformType { typedef enum gnUniformType {
GN_UNIFORM_BUFFER_DESCRIPTOR, GN_UNIFORM_BUFFER_DESCRIPTOR,
GN_DYNAMIC_UNIFORM_BUFFER_DESCRIPTOR,
GN_SHADER_STORE_BUFFER_DESCRIPTOR, GN_SHADER_STORE_BUFFER_DESCRIPTOR,
GN_COMBINED_IMAGE_SAMPLER_DESCRIPTOR, GN_COMBINED_IMAGE_SAMPLER_DESCRIPTOR,
GN_UNIFORM_TYPE_MAX GN_UNIFORM_TYPE_MAX

View File

@@ -23,7 +23,7 @@ typedef struct gnCommandFunctions_t {
void (*_gnCommandBindGraphicsPipeline)(gnCommandBufferHandle buffer, gnGraphicsPipelineHandle graphicsPipeline); void (*_gnCommandBindGraphicsPipeline)(gnCommandBufferHandle buffer, gnGraphicsPipelineHandle graphicsPipeline);
void (*_gnCommandSetViewport)(gnCommandBufferHandle buffer, gnViewport viewport); void (*_gnCommandSetViewport)(gnCommandBufferHandle buffer, gnViewport viewport);
void (*_gnCommandSetScissor)(gnCommandBufferHandle buffer, gnScissor scissor); void (*_gnCommandSetScissor)(gnCommandBufferHandle buffer, gnScissor scissor);
void (*_gnCommandBindUniform)(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set); void (*_gnCommandBindUniform)(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set, uint32_t dynamicOffsetCount, uint32_t* dynamicOffsets);
void (*_gnCommandPushConstant)(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data); void (*_gnCommandPushConstant)(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data);
void (*_gnCommandBindBuffer)(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type); void (*_gnCommandBindBuffer)(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type);

View File

@@ -41,8 +41,8 @@ void checkCommandSetViewport(gnCommandBufferHandle buffer, gnViewport viewport)
void checkCommandSetScissor(gnCommandBufferHandle buffer, gnScissor scissor) { void checkCommandSetScissor(gnCommandBufferHandle buffer, gnScissor scissor) {
CHECK_VOID_FUNCTION(buffer->instance, _gnCommandSetScissor, commandFunctions, buffer, scissor); CHECK_VOID_FUNCTION(buffer->instance, _gnCommandSetScissor, commandFunctions, buffer, scissor);
} }
void checkCommandBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set) { void checkCommandBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set, uint32_t dynamicOffsetCount, uint32_t* dynamicOffsets) {
CHECK_VOID_FUNCTION(buffer->instance, _gnCommandBindUniform, commandFunctions, buffer, uniform, set); CHECK_VOID_FUNCTION(buffer->instance, _gnCommandBindUniform, commandFunctions, buffer, uniform, set, dynamicOffsetCount, dynamicOffsets);
} }
void checkCommandPushConstant(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data) { void checkCommandPushConstant(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data) {
CHECK_VOID_FUNCTION(buffer->instance, _gnCommandPushConstant, commandFunctions, buffer, layout, data); CHECK_VOID_FUNCTION(buffer->instance, _gnCommandPushConstant, commandFunctions, buffer, layout, data);

View File

@@ -12,7 +12,7 @@ void checkCommandEndRenderPass(gnCommandBufferHandle buffer);
void checkCommandBindGraphicsPipeline(gnCommandBufferHandle buffer, gnGraphicsPipelineHandle graphicsPipeline); void checkCommandBindGraphicsPipeline(gnCommandBufferHandle buffer, gnGraphicsPipelineHandle graphicsPipeline);
void checkCommandSetViewport(gnCommandBufferHandle buffer, gnViewport viewport); void checkCommandSetViewport(gnCommandBufferHandle buffer, gnViewport viewport);
void checkCommandSetScissor(gnCommandBufferHandle buffer, gnScissor scissor); void checkCommandSetScissor(gnCommandBufferHandle buffer, gnScissor scissor);
void checkCommandBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set); void checkCommandBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set, uint32_t dynamicOffsetCount, uint32_t* dynamicOffsets);
void checkCommandPushConstant(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data); void checkCommandPushConstant(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data);
void checkCommandBindBuffer(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type); void checkCommandBindBuffer(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type);