diff --git a/rendering_api/metal/src/core/pipelines/graphics_pipeline/metal_graphics_pipeline.m b/rendering_api/metal/src/core/pipelines/graphics_pipeline/metal_graphics_pipeline.m index 6951cf5..612de06 100644 --- a/rendering_api/metal/src/core/pipelines/graphics_pipeline/metal_graphics_pipeline.m +++ b/rendering_api/metal/src/core/pipelines/graphics_pipeline/metal_graphics_pipeline.m @@ -91,6 +91,7 @@ gnReturnCode gnCreateGraphicsPipelineFn(struct gnGraphicsPipeline_t* graphicsPip return GN_FAILED_TO_CREATE_GRAPHICS_PIPELINE; } [descriptor release]; + [vertexDescriptor release]; [error release]; return GN_SUCCESS; } diff --git a/rendering_api/vulkan/src/buffers/vulkan_buffer.c b/rendering_api/vulkan/src/buffers/vulkan_buffer.c new file mode 100644 index 0000000..12d2fe1 --- /dev/null +++ b/rendering_api/vulkan/src/buffers/vulkan_buffer.c @@ -0,0 +1,56 @@ +#include "vulkan_buffer.h" +#include "core/buffers/gryphn_buffer.h" +#include "core/output_device/gryphn_output_device.h" +#include "output_device/vulkan_output_devices.h" +#include "output_device/vulkan_physical_device.h" + +VkBufferUsageFlags vkGryphnBufferType(gnBufferType type) { +switch (type) { +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)); + VkBufferCreateInfo bufferInfo = { + .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, + .size = info.size, + .usage = vkGryphnBufferType(info.type), + .sharingMode = VK_SHARING_MODE_EXCLUSIVE + }; + + if (vkCreateBuffer(device->outputDevice->device, &bufferInfo, NULL, &buffer->buffer->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); + + VkMemoryAllocateInfo memoryAllocateInfo = { + .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, + .allocationSize = bufferRequirements.size, + }; + + 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; + foundMemory = gnTrue; + } + } // 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) { + return GN_FAILED_TO_ALLOCATE_MEMORY; + } + vkBindBufferMemory(device->outputDevice->device, buffer->buffer->buffer, buffer->buffer->bufferMemory, 0); + return GN_SUCCESS; +} +void gnDestroyBufferFn(gnBufferHandle buffer) { + 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 new file mode 100644 index 0000000..b6c0359 --- /dev/null +++ b/rendering_api/vulkan/src/buffers/vulkan_buffer.h @@ -0,0 +1,7 @@ +#pragma once +#include + +struct gnPlatformBuffer_t { + VkBuffer buffer; + VkDeviceMemory bufferMemory; +}; diff --git a/src/core/instance/init/gryphn_init.c b/src/core/instance/init/gryphn_init.c index 47e9778..ebad1f5 100644 --- a/src/core/instance/init/gryphn_init.c +++ b/src/core/instance/init/gryphn_init.c @@ -84,6 +84,8 @@ void gnLoadDeviceFunctions(struct gnDynamicLibrary_t* lib, struct gnDeviceFuncti gnLoadDLLFunction(lib, functions->_gnDestroyCommandPool, "gnDestroyCommandPoolFn"); gnLoadDLLFunction(lib, functions->_gnCreateSemaphore, "gnCreateSemaphoreFn"); gnLoadDLLFunction(lib, functions->_gnDestroySemaphore, "gnDestroySemaphoreFn"); + gnLoadDLLFunction(lib, functions->_gnCreateBuffer, "gnCreateBufferFn"); + gnLoadDLLFunction(lib, functions->_gnDestroyBuffer, "gnDestroyBufferFn"); gnLoadDLLFunction(lib, functions->_gnCreateFence, "gnCreateFenceFn"); gnLoadDLLFunction(lib, functions->_gnSignalFence, "gnSignalFenceFn"); gnLoadDLLFunction(lib, functions->_gnWaitForFence, "gnWaitForFenceFn"); diff --git a/src/utils/gryphn_error_code.h b/src/utils/gryphn_error_code.h index a235510..62ef6a2 100644 --- a/src/utils/gryphn_error_code.h +++ b/src/utils/gryphn_error_code.h @@ -35,7 +35,9 @@ typedef enum gnReturnCode_t { GN_FAILED_TO_CREATE_SEMAPHORE, GN_FAILED_TO_SUBMIT_COMMAND_BUFFER, GN_OUT_OF_DATE_PRESENTATION_QUEUE, - GN_SUBOPTIMAL_PRESENTATION_QUEUE + GN_SUBOPTIMAL_PRESENTATION_QUEUE, + GN_FAILED_TO_CREATE_BUFFER, + GN_FAILED_TO_ALLOCATE_MEMORY } gnReturnCode; typedef gnReturnCode gnErrorCode; @@ -76,5 +78,7 @@ static const char* gnErrorCodeToCString(enum gnReturnCode_t returnCode) { case GN_FAILED_TO_SUBMIT_COMMAND_BUFFER: return "GN_FAILED_TO_SUBMIT_COMMAND_BUFFER"; case GN_OUT_OF_DATE_PRESENTATION_QUEUE: return "GN_OUT_OF_DATE_PRESENTATION_QUEUE"; case GN_SUBOPTIMAL_PRESENTATION_QUEUE: return "GN_SUBOPTIMAL_PRESENTATION_QUEUE"; + case GN_FAILED_TO_ALLOCATE_MEMORY: return "GN_FAILED_TO_ALLOCATE_MEMORY"; + case GN_FAILED_TO_CREATE_BUFFER: return "GN_FAILED_TO_CREATE_BUFFER"; } }