diff --git a/rendering_api/vulkan/src/buffers/vulkan_buffer.c b/rendering_api/vulkan/src/buffers/vulkan_buffer.c index 14aef30..0cfbbad 100644 --- a/rendering_api/vulkan/src/buffers/vulkan_buffer.c +++ b/rendering_api/vulkan/src/buffers/vulkan_buffer.c @@ -10,8 +10,11 @@ case GN_VERTEX_BUFFER: return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; } } -gnReturnCode gnCreateBufferFn(gnBufferHandle buffer, gnOutputDeviceHandle device, gnBufferInfo info) { - buffer->buffer = malloc(sizeof(struct gnPlatformBuffer_t)); +gnReturnCode VkCreateBuffer( + VkBuffer* buffer, VkDeviceMemory* memory, gnBufferInfo info, + VkDevice device, VkPhysicalDevice physcialDevice, + VkMemoryPropertyFlags flags +) { VkBufferCreateInfo bufferInfo = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .size = info.size, @@ -19,22 +22,21 @@ gnReturnCode gnCreateBufferFn(gnBufferHandle buffer, gnOutputDeviceHandle device .sharingMode = VK_SHARING_MODE_EXCLUSIVE }; - if (vkCreateBuffer(device->outputDevice->device, &bufferInfo, NULL, &buffer->buffer->buffer) != VK_SUCCESS) + if (vkCreateBuffer(device, &bufferInfo, NULL, buffer) != VK_SUCCESS) return GN_FAILED_TO_CREATE_BUFFER; VkMemoryRequirements bufferRequirements; - vkGetBufferMemoryRequirements(device->outputDevice->device, buffer->buffer->buffer, &bufferRequirements); - - VkPhysicalDeviceMemoryProperties memoryProperties; - vkGetPhysicalDeviceMemoryProperties(device->physicalDevice.physicalDevice->device, &memoryProperties); + vkGetBufferMemoryRequirements(device, *buffer, &bufferRequirements); VkMemoryAllocateInfo memoryAllocateInfo = { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, .allocationSize = bufferRequirements.size, }; + VkPhysicalDeviceMemoryProperties memoryProperties; + vkGetPhysicalDeviceMemoryProperties(physcialDevice, &memoryProperties); + gnBool foundMemory = gnFalse; - VkMemoryPropertyFlagBits flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; i++) { if ((bufferRequirements.memoryTypeBits & (1 << i)) && (memoryProperties.memoryTypes[i].propertyFlags & flags) == flags) { memoryAllocateInfo.memoryTypeIndex = i; @@ -43,10 +45,30 @@ gnReturnCode gnCreateBufferFn(gnBufferHandle buffer, gnOutputDeviceHandle device } // this whole thing was adapted from vulkan-tutorial.com if (!foundMemory) return GN_FAILED_TO_ALLOCATE_MEMORY; - if (vkAllocateMemory(device->outputDevice->device, &memoryAllocateInfo, NULL, &buffer->buffer->bufferMemory) != VK_SUCCESS) { + if (vkAllocateMemory(device, &memoryAllocateInfo, NULL, memory) != VK_SUCCESS) { return GN_FAILED_TO_ALLOCATE_MEMORY; } - vkBindBufferMemory(device->outputDevice->device, buffer->buffer->buffer, buffer->buffer->bufferMemory, 0); + vkBindBufferMemory(device, *buffer, *memory, 0); + return GN_SUCCESS; +} + +gnReturnCode gnCreateBufferFn(gnBufferHandle buffer, gnOutputDeviceHandle device, gnBufferInfo info) { + buffer->buffer = malloc(sizeof(struct gnPlatformBuffer_t)); + gnReturnCode createdBuffer = VkCreateBuffer( + &buffer->buffer->buffer, &buffer->buffer->bufferMemory, + info, device->outputDevice->device, device->physicalDevice.physicalDevice->device, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT + ); + + if (info.usage == GN_STATIC_DRAW) { + gnReturnCode createdBuffer = VkCreateBuffer( + &buffer->buffer->stagingBuffer, &buffer->buffer->stagingBufferMemory, + info, device->outputDevice->device, device->physicalDevice.physicalDevice->device, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT + ); + buffer->buffer->useStagingBuffer = gnTrue; + } + return GN_SUCCESS; } void gnBufferDataFn(gnBufferHandle buffer, size_t dataSize, void* data) { @@ -56,6 +78,11 @@ void gnBufferDataFn(gnBufferHandle buffer, size_t dataSize, void* data) { vkUnmapMemory(buffer->device->outputDevice->device, buffer->buffer->bufferMemory); } void gnDestroyBufferFn(gnBufferHandle buffer) { + if (buffer->buffer->useStagingBuffer == gnTrue) { + vkDestroyBuffer(buffer->device->outputDevice->device, buffer->buffer->stagingBuffer, NULL); + vkFreeMemory(buffer->device->outputDevice->device, buffer->buffer->stagingBufferMemory, NULL); + } + vkDestroyBuffer(buffer->device->outputDevice->device, buffer->buffer->buffer, NULL); vkFreeMemory(buffer->device->outputDevice->device, buffer->buffer->bufferMemory, NULL); free(buffer->buffer); diff --git a/rendering_api/vulkan/src/buffers/vulkan_buffer.h b/rendering_api/vulkan/src/buffers/vulkan_buffer.h index b6c0359..c26793b 100644 --- a/rendering_api/vulkan/src/buffers/vulkan_buffer.h +++ b/rendering_api/vulkan/src/buffers/vulkan_buffer.h @@ -1,7 +1,13 @@ #pragma once #include +#include "utils/gryphn_bool.h" struct gnPlatformBuffer_t { VkBuffer buffer; VkDeviceMemory bufferMemory; + + // for if static draw + VkBuffer stagingBuffer; + VkDeviceMemory stagingBufferMemory; + gnBool useStagingBuffer; }; diff --git a/src/core/buffers/gryphn_buffer.h b/src/core/buffers/gryphn_buffer.h index 8f6d7e1..c5a9012 100644 --- a/src/core/buffers/gryphn_buffer.h +++ b/src/core/buffers/gryphn_buffer.h @@ -7,9 +7,14 @@ typedef enum gnBufferType { GN_VERTEX_BUFFER = 0x00000001 } gnBufferType; +typedef enum gnBufferUsage { + GN_STATIC_DRAW, GN_DYNAMIC_DRAW +} gnBufferUsage; // i love that OpenGL does this so im stealing it + typedef struct gnBufferInfo { size_t size; gnBufferType type; + gnBufferUsage usage; } gnBufferInfo; #ifdef GN_REVEAL_IMPL