add support for storage buffers in vulkan

This commit is contained in:
Greg Wells
2025-07-03 13:30:47 -04:00
parent d9937c2833
commit 665ce6847a
15 changed files with 83 additions and 13 deletions

View File

@@ -41,6 +41,7 @@ gnDeviceFunctions loadVulkanDeviceFunctions() {
._gnCreateBuffer = createBuffer, ._gnCreateBuffer = createBuffer,
._gnBufferData = bufferData, ._gnBufferData = bufferData,
._gnBufferSubData = vulkanBufferSubData,
._gnMapBuffer = mapBuffer, ._gnMapBuffer = mapBuffer,
._gnDestroyBuffer = destroyBuffer, ._gnDestroyBuffer = destroyBuffer,
@@ -49,6 +50,7 @@ gnDeviceFunctions loadVulkanDeviceFunctions() {
._gnDestroyUniformPool = destroyUniformPool, ._gnDestroyUniformPool = destroyUniformPool,
._gnUpdateBufferUniform = updateBufferUniform, ._gnUpdateBufferUniform = updateBufferUniform,
._gnUpdateStorageUniform = updateVulkanStorageUniform,
._gnUpdateImageUniform = updateImageUniform, ._gnUpdateImageUniform = updateImageUniform,
._gnCreateTexture = createTexture, ._gnCreateTexture = createTexture,

View File

@@ -11,6 +11,7 @@ VkBufferUsageFlags vkGryphnBufferType(gnBufferType type) {
case GN_VERTEX_BUFFER: usageFlags |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; break; case GN_VERTEX_BUFFER: usageFlags |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; break;
case GN_INDEX_BUFFER: usageFlags |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT; break; case GN_INDEX_BUFFER: usageFlags |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT; break;
case GN_UNIFORM_BUFFER: usageFlags |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; break; case GN_UNIFORM_BUFFER: usageFlags |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; break;
case GN_STORAGE_BUFFER: usageFlags |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; break;
} }
return usageFlags; return usageFlags;
} }
@@ -114,6 +115,22 @@ void bufferData(gnBufferHandle buffer, size_t dataSize, void* data) {
vkUnmapMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory); vkUnmapMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory);
} }
} }
void vulkanBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, void* data) {
void* bufferData;
if (buffer->buffer->useStagingBuffer) {
vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->stagingBuffer.memory, 0, dataSize, 0, &bufferData);
memcpy(bufferData + offset, data, dataSize);
vkUnmapMemory(buffer->device->outputDevice->device, buffer->buffer->stagingBuffer.memory);
VkCopyBuffer(
buffer->buffer->stagingBuffer.buffer, buffer->buffer->buffer.buffer, dataSize,
buffer->device->outputDevice->transferCommandPool, buffer->device->outputDevice->device,
buffer->device->outputDevice->transferQueue);
} else {
vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory, 0, dataSize, 0, &bufferData);
memcpy(bufferData + offset, data, dataSize);
vkUnmapMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory);
}
}
void* mapBuffer(gnBufferHandle buffer) { void* mapBuffer(gnBufferHandle buffer) {
void* data; void* data;
vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory, 0, buffer->info.size, 0, &data); vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory, 0, buffer->info.size, 0, &data);

View File

@@ -25,5 +25,6 @@ uint32_t VkMemoryIndex(VkPhysicalDevice device, uint32_t memoryType, VkMemoryPro
gnReturnCode createBuffer(gnBufferHandle buffer, gnOutputDeviceHandle device, gnBufferInfo info); gnReturnCode createBuffer(gnBufferHandle buffer, gnOutputDeviceHandle device, gnBufferInfo info);
void bufferData(gnBufferHandle buffer, size_t dataSize, void* data); void bufferData(gnBufferHandle buffer, size_t dataSize, void* data);
void vulkanBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, void* data);
void* mapBuffer(gnBufferHandle buffer); void* mapBuffer(gnBufferHandle buffer);
void destroyBuffer(gnBufferHandle buffer); void destroyBuffer(gnBufferHandle buffer);

View File

@@ -24,6 +24,26 @@ void updateBufferUniform(gnUniform uniform, gnBufferUniformInfo* info) {
vkUpdateDescriptorSets(uniform->pool->device->outputDevice->device, 1, &write, 0, NULL); vkUpdateDescriptorSets(uniform->pool->device->outputDevice->device, 1, &write, 0, NULL);
} }
void updateVulkanStorageUniform(gnUniform uniform, gnStorageUniformInfo* info) {
VkDescriptorBufferInfo bufferInfo = {
.buffer = info->buffer->buffer->buffer.buffer,
.offset = info->offset,
.range = info->size
};
VkWriteDescriptorSet write = {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.descriptorCount = 1,
.pBufferInfo = &bufferInfo,
.dstSet = uniform->uniform->set,
.dstBinding = info->binding,
.dstArrayElement = 0
};
vkUpdateDescriptorSets(uniform->pool->device->outputDevice->device, 1, &write, 0, NULL);
}
void updateImageUniform(gnUniform uniform, gnImageUniformInfo* info) { void updateImageUniform(gnUniform uniform, gnImageUniformInfo* info) {
VkDescriptorImageInfo imageInfo = { VkDescriptorImageInfo imageInfo = {
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,

View File

@@ -7,4 +7,5 @@ typedef struct gnPlatformUniform_t {
} gnPlatformUniform; } gnPlatformUniform;
void updateBufferUniform(gnUniform uniform, gnBufferUniformInfo* info); void updateBufferUniform(gnUniform uniform, gnBufferUniformInfo* info);
void updateVulkanStorageUniform(gnUniform uniform, gnStorageUniformInfo* info);
void updateImageUniform(gnUniform uniform, gnImageUniformInfo* info); void updateImageUniform(gnUniform uniform, gnImageUniformInfo* info);

View File

@@ -50,26 +50,26 @@ gnUniform* allocateUniforms(gnUniformPool pool, gnUniformAllocationInfo allocInf
}; };
// TODO: redo this, its not warning me IDK why cuz its totally wrong // TODO: redo this, its not warning me IDK why cuz its totally wrong
VkDescriptorPoolSize poolSizes[GN_UNIFORM_TYPE_MAX]; VkDescriptorPoolSize poolSizes[GN_UNIFORM_TYPE_MAX] = { };
for (int i = 0; i < allocInfo.setCount; i++) { for (int i = 0; i < allocInfo.setCount; i++)
for (int c = 0; c < allocInfo.sets[i].uniformBindingCount; c++) { for (int c = 0; c < allocInfo.sets[i].uniformBindingCount; c++)
poolSizes[allocInfo.sets[i].uniformBindings[c].type].descriptorCount++; poolSizes[allocInfo.sets[i].uniformBindings[c].type].descriptorCount++;
}
}
uint32_t count = 0; uint32_t count = 0;
VkDescriptorPoolSize realPoolSize[GN_UNIFORM_TYPE_MAX] = {}; VkDescriptorPoolSize realPoolSizes[GN_UNIFORM_TYPE_MAX] = {};
for (int i = 0; i < GN_UNIFORM_TYPE_MAX; i++) { for (int i = 0; i < GN_UNIFORM_TYPE_MAX; i++) {
if (poolSizes[i].descriptorCount <= 0) continue; poolSizes[i].type = vkGryphnUniformType(i);
realPoolSize[count] = poolSizes[i]; if (poolSizes[i].descriptorCount > 0) {
realPoolSizes[count] = poolSizes[i];
count++; count++;
} }
}
VkDescriptorPoolCreateInfo poolInfo = { VkDescriptorPoolCreateInfo poolInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.poolSizeCount = count, .poolSizeCount = count,
.pPoolSizes = realPoolSize, .pPoolSizes = realPoolSizes,
.maxSets = allocInfo.setCount .maxSets = allocInfo.setCount
}; };

View File

@@ -11,6 +11,9 @@ gnReturnCode gnCreateBuffer(gnBufferHandle* buffer, gnOutputDeviceHandle device,
void gnBufferData(gnBufferHandle buffer, size_t dataSize, void* data) { void gnBufferData(gnBufferHandle buffer, size_t dataSize, void* data) {
buffer->device->instance->callingLayer->deviceFunctions._gnBufferData(buffer, dataSize, data); buffer->device->instance->callingLayer->deviceFunctions._gnBufferData(buffer, dataSize, data);
} }
void gnBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, gnBufferMemory data) {
buffer->device->instance->callingLayer->deviceFunctions._gnBufferSubData(buffer, offset, dataSize, data);
}
void* gnMapBuffer(gnBufferHandle buffer) { void* gnMapBuffer(gnBufferHandle buffer) {
if (buffer->info.usage == GN_STATIC_DRAW) return NULL; if (buffer->info.usage == GN_STATIC_DRAW) return NULL;
return buffer->device->instance->callingLayer->deviceFunctions._gnMapBuffer(buffer); return buffer->device->instance->callingLayer->deviceFunctions._gnMapBuffer(buffer);

View File

@@ -11,7 +11,8 @@ typedef enum gnIndexType {
typedef enum gnBufferType { typedef enum gnBufferType {
GN_VERTEX_BUFFER = 0x00000001, GN_VERTEX_BUFFER = 0x00000001,
GN_INDEX_BUFFER = 0x00000002, GN_INDEX_BUFFER = 0x00000002,
GN_UNIFORM_BUFFER = 0x00000004 GN_UNIFORM_BUFFER = 0x00000004,
GN_STORAGE_BUFFER = 0x00000008
} gnBufferType; } gnBufferType;
typedef enum gnBufferUsage { typedef enum gnBufferUsage {
@@ -37,5 +38,6 @@ GN_ARRAY_LIST(gnBufferMemory);
gnReturnCode gnCreateBuffer(gnBufferHandle* buffer, gnOutputDeviceHandle device, gnBufferInfo info); gnReturnCode gnCreateBuffer(gnBufferHandle* buffer, gnOutputDeviceHandle device, gnBufferInfo info);
void gnBufferData(gnBufferHandle buffer, size_t dataSize, gnBufferMemory data); void gnBufferData(gnBufferHandle buffer, size_t dataSize, gnBufferMemory data);
void gnBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, gnBufferMemory data);
gnBufferMemory gnMapBuffer(gnBufferHandle buffer); gnBufferMemory gnMapBuffer(gnBufferHandle buffer);
void gnDestroyBuffer(gnBufferHandle buffer); void gnDestroyBuffer(gnBufferHandle buffer);

View File

@@ -7,6 +7,10 @@ void gnUpdateBufferUniform(gnUniform uniform, gnBufferUniformInfo bufferInfo) {
uniform->pool->device->instance->callingLayer->deviceFunctions._gnUpdateBufferUniform(uniform, &bufferInfo); uniform->pool->device->instance->callingLayer->deviceFunctions._gnUpdateBufferUniform(uniform, &bufferInfo);
} }
void gnUpdateStorageUniform(gnUniform uniform, gnStorageUniformInfo storageInfo) {
uniform->pool->device->instance->callingLayer->deviceFunctions._gnUpdateStorageUniform(uniform, &storageInfo);
}
void gnUpdateImageUniform(gnUniform uniform, gnImageUniformInfo imageInfo) { void gnUpdateImageUniform(gnUniform uniform, gnImageUniformInfo imageInfo) {
uniform->pool->device->instance->callingLayer->deviceFunctions._gnUpdateImageUniform(uniform, &imageInfo); uniform->pool->device->instance->callingLayer->deviceFunctions._gnUpdateImageUniform(uniform, &imageInfo);
} }

View File

@@ -11,6 +11,12 @@ typedef struct gnBufferUniformInfo {
size_t size; size_t size;
} gnBufferUniformInfo; } gnBufferUniformInfo;
typedef struct gnStorageUniformInfo {
gnBuffer buffer;
size_t offset, size;
uint32_t binding;
} gnStorageUniformInfo;
typedef struct gnImageUniformInfo { typedef struct gnImageUniformInfo {
uint32_t binding; uint32_t binding;
gnTexture texture; gnTexture texture;
@@ -22,7 +28,8 @@ struct gnUniform_t {
gnUniformPool pool; gnUniformPool pool;
}; };
#endif #endif
GN_ARRAY_LIST(gnUniform) GN_ARRAY_LIST(gnUniform);
void gnUpdateBufferUniform(gnUniform uniform, gnBufferUniformInfo bufferInfo); void gnUpdateBufferUniform(gnUniform uniform, gnBufferUniformInfo bufferInfo);
void gnUpdateStorageUniform(gnUniform uniform, gnStorageUniformInfo storageInfo);
void gnUpdateImageUniform(gnUniform uniform, gnImageUniformInfo imageInfo); void gnUpdateImageUniform(gnUniform uniform, gnImageUniformInfo imageInfo);

View File

@@ -4,8 +4,8 @@
typedef enum gnUniformType { typedef enum gnUniformType {
GN_UNIFORM_BUFFER_DESCRIPTOR, GN_UNIFORM_BUFFER_DESCRIPTOR,
GN_SHADER_STORE_BUFFER_DESCRIPTOR,
GN_IMAGE_DESCRIPTOR, GN_IMAGE_DESCRIPTOR,
GN_SHADER_STORE_BUFFER_DESCRIPTOR,
GN_UNIFORM_TYPE_MAX GN_UNIFORM_TYPE_MAX
} gnUniformType; } gnUniformType;

View File

@@ -13,6 +13,7 @@ typedef struct gnCommandPoolInfo gnCommandPoolInfo;
typedef struct gnBufferInfo gnBufferInfo; typedef struct gnBufferInfo gnBufferInfo;
typedef struct gnUniformAllocationInfo gnUniformAllocationInfo; typedef struct gnUniformAllocationInfo gnUniformAllocationInfo;
typedef struct gnBufferUniformInfo gnBufferUniformInfo; typedef struct gnBufferUniformInfo gnBufferUniformInfo;
typedef struct gnStorageUniformInfo gnStorageUniformInfo;
typedef struct gnImageUniformInfo gnImageUniformInfo; typedef struct gnImageUniformInfo gnImageUniformInfo;
typedef struct gnTextureInfo gnTextureInfo; typedef struct gnTextureInfo gnTextureInfo;
typedef struct gnSubmitInfo gnSubmitInfo; typedef struct gnSubmitInfo gnSubmitInfo;
@@ -43,6 +44,7 @@ typedef struct gnDeviceFunctions {
gnReturnCode (*_gnCreateBuffer)(gnBufferHandle buffer, gnDeviceHandle device, gnBufferInfo info); gnReturnCode (*_gnCreateBuffer)(gnBufferHandle buffer, gnDeviceHandle device, gnBufferInfo info);
void (*_gnBufferData)(gnBufferHandle buffer, size_t size, void* data); void (*_gnBufferData)(gnBufferHandle buffer, size_t size, void* data);
void (*_gnBufferSubData)(gnBufferHandle buffer, size_t offset, size_t dataSize, void* data);
void* (*_gnMapBuffer)(gnBufferHandle buffer); void* (*_gnMapBuffer)(gnBufferHandle buffer);
void (*_gnDestroyBuffer)(gnBufferHandle buffer); void (*_gnDestroyBuffer)(gnBufferHandle buffer);
@@ -51,6 +53,7 @@ typedef struct gnDeviceFunctions {
void (*_gnDestroyUniformPool)(gnUniformPool pool); void (*_gnDestroyUniformPool)(gnUniformPool pool);
void (*_gnUpdateBufferUniform)(gnUniform uniform, gnBufferUniformInfo* bufferInfo); void (*_gnUpdateBufferUniform)(gnUniform uniform, gnBufferUniformInfo* bufferInfo);
void (*_gnUpdateStorageUniform)(gnUniform uniform, gnStorageUniformInfo* storageInfo);
void (*_gnUpdateImageUniform)(gnUniform uniform, gnImageUniformInfo* imageInfo); void (*_gnUpdateImageUniform)(gnUniform uniform, gnImageUniformInfo* imageInfo);
gnReturnCode (*_gnCreateTexture)(gnTexture texture, gnDevice device, const gnTextureInfo info); gnReturnCode (*_gnCreateTexture)(gnTexture texture, gnDevice device, const gnTextureInfo info);

View File

@@ -63,6 +63,7 @@ gnDeviceFunctions loadFunctionLoaderDeviceFunctions() {
._gnCreateBuffer = checkCreateBuffer, ._gnCreateBuffer = checkCreateBuffer,
._gnBufferData = checkBufferData, ._gnBufferData = checkBufferData,
._gnBufferSubData = checkBufferSubData,
._gnMapBuffer = checkMapBuffer, ._gnMapBuffer = checkMapBuffer,
._gnDestroyBuffer = checkDestroyBuffer, ._gnDestroyBuffer = checkDestroyBuffer,
@@ -71,6 +72,7 @@ gnDeviceFunctions loadFunctionLoaderDeviceFunctions() {
._gnDestroyUniformPool = checkDestroyUniformPool, ._gnDestroyUniformPool = checkDestroyUniformPool,
._gnUpdateBufferUniform = checkUpdateBufferUniform, ._gnUpdateBufferUniform = checkUpdateBufferUniform,
._gnUpdateStorageUniform = checkUpdateStorageUniform,
._gnUpdateImageUniform = checkUpdateImageUniform, ._gnUpdateImageUniform = checkUpdateImageUniform,
._gnCreateTexture = checkCreateTexture, ._gnCreateTexture = checkCreateTexture,

View File

@@ -110,6 +110,9 @@ gnReturnCode checkCreateBuffer(gnBufferHandle buffer, gnDeviceHandle device, gnB
void checkBufferData(gnBufferHandle buffer, size_t size, void* data) { void checkBufferData(gnBufferHandle buffer, size_t size, void* data) {
CHECK_VOID_FUNCTION(buffer->device->instance, _gnBufferData, buffer, size, data); CHECK_VOID_FUNCTION(buffer->device->instance, _gnBufferData, buffer, size, data);
} }
void checkBufferSubData(gnBufferHandle buffer, size_t offset, size_t size, void* data) {
CHECK_VOID_FUNCTION(buffer->device->instance, _gnBufferSubData, buffer, offset, size, data);
}
void* checkMapBuffer(gnBufferHandle buffer) { void* checkMapBuffer(gnBufferHandle buffer) {
loaderLayer* nextLayer = loaderGetNextLayer(buffer->device->instance); loaderLayer* nextLayer = loaderGetNextLayer(buffer->device->instance);
if (nextLayer->deviceFunctions._gnMapBuffer == NULL) { if (nextLayer->deviceFunctions._gnMapBuffer == NULL) {
@@ -146,6 +149,9 @@ void checkDestroyUniformPool(gnUniformPool pool) {
void checkUpdateBufferUniform(gnUniform uniform, gnBufferUniformInfo* bufferInfo) { void checkUpdateBufferUniform(gnUniform uniform, gnBufferUniformInfo* bufferInfo) {
CHECK_VOID_FUNCTION(uniform->pool->device->instance, _gnUpdateBufferUniform, uniform, bufferInfo); CHECK_VOID_FUNCTION(uniform->pool->device->instance, _gnUpdateBufferUniform, uniform, bufferInfo);
} }
void checkUpdateStorageUniform(gnUniform uniform, gnStorageUniformInfo* storageInfo) {
CHECK_VOID_FUNCTION(uniform->pool->device->instance, _gnUpdateStorageUniform, uniform, storageInfo);
}
void checkUpdateImageUniform(gnUniform uniform, gnImageUniformInfo* imageInfo) { void checkUpdateImageUniform(gnUniform uniform, gnImageUniformInfo* imageInfo) {
CHECK_VOID_FUNCTION(uniform->pool->device->instance, _gnUpdateImageUniform, uniform, imageInfo); CHECK_VOID_FUNCTION(uniform->pool->device->instance, _gnUpdateImageUniform, uniform, imageInfo);
} }

View File

@@ -24,6 +24,7 @@ void checkDestroySemaphore(gnSemaphoreHandle semaphore);
gnReturnCode checkCreateBuffer(gnBufferHandle buffer, gnDeviceHandle device, gnBufferInfo info); gnReturnCode checkCreateBuffer(gnBufferHandle buffer, gnDeviceHandle device, gnBufferInfo info);
void checkBufferData(gnBufferHandle buffer, size_t size, void* data); void checkBufferData(gnBufferHandle buffer, size_t size, void* data);
void checkBufferSubData(gnBufferHandle buffer, size_t offset, size_t size, void* data);
void* checkMapBuffer(gnBufferHandle buffer); void* checkMapBuffer(gnBufferHandle buffer);
void checkDestroyBuffer(gnBufferHandle buffer); void checkDestroyBuffer(gnBufferHandle buffer);
@@ -32,6 +33,7 @@ gnUniform* checkUniformPoolAllocateUniforms(gnUniformPool pool, gnUniformAllocat
void checkDestroyUniformPool(gnUniformPool pool); void checkDestroyUniformPool(gnUniformPool pool);
void checkUpdateBufferUniform(gnUniform uniform, gnBufferUniformInfo* bufferInfo); void checkUpdateBufferUniform(gnUniform uniform, gnBufferUniformInfo* bufferInfo);
void checkUpdateStorageUniform(gnUniform uniform, gnStorageUniformInfo* storageInfo);
void checkUpdateImageUniform(gnUniform uniform, gnImageUniformInfo* imageInfo); void checkUpdateImageUniform(gnUniform uniform, gnImageUniformInfo* imageInfo);
gnReturnCode checkCreateTexture(gnTexture texture, gnDevice device, const gnTextureInfo info); gnReturnCode checkCreateTexture(gnTexture texture, gnDevice device, const gnTextureInfo info);