From fc7f75de6be550ca2e5e7ff974cca4995d12edf1 Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Tue, 4 Feb 2025 01:09:41 +0100 Subject: [PATCH] Implement Vulkan buffers --- .../Vulkan/Sources/kope/vulkan/buffer.c | 29 ++++++++-- .../Sources/kope/vulkan/buffer_structs.h | 7 ++- .../Vulkan/Sources/kope/vulkan/device.c | 57 ++++++++++++++++++- 3 files changed, 85 insertions(+), 8 deletions(-) diff --git a/Backends/Graphics5/Vulkan/Sources/kope/vulkan/buffer.c b/Backends/Graphics5/Vulkan/Sources/kope/vulkan/buffer.c index 49b0f8535..05102aa03 100644 --- a/Backends/Graphics5/Vulkan/Sources/kope/vulkan/buffer.c +++ b/Backends/Graphics5/Vulkan/Sources/kope/vulkan/buffer.c @@ -4,22 +4,39 @@ void kope_vulkan_buffer_set_name(kope_g5_buffer *buffer, const char *name) {} -void kope_vulkan_buffer_destroy(kope_g5_buffer *buffer) {} +void kope_vulkan_buffer_destroy(kope_g5_buffer *buffer) { + vkFreeMemory(buffer->vulkan.device, buffer->vulkan.memory, NULL); + vkDestroyBuffer(buffer->vulkan.device, buffer->vulkan.buffer, NULL); +} void *kope_vulkan_buffer_try_to_lock_all(kope_g5_buffer *buffer) { - return NULL; + void *data = NULL; + VkResult result = vkMapMemory(buffer->vulkan.device, buffer->vulkan.memory, 0, buffer->vulkan.size, 0, &data); + assert(result == VK_SUCCESS); + return data; } void *kope_vulkan_buffer_lock_all(kope_g5_buffer *buffer) { - return NULL; + void *data = NULL; + VkResult result = vkMapMemory(buffer->vulkan.device, buffer->vulkan.memory, 0, buffer->vulkan.size, 0, &data); + assert(result == VK_SUCCESS); + return data; } void *kope_vulkan_buffer_try_to_lock(kope_g5_buffer *buffer, uint64_t offset, uint64_t size) { - return NULL; + void *data = NULL; + VkResult result = vkMapMemory(buffer->vulkan.device, buffer->vulkan.memory, offset, size, 0, &data); + assert(result == VK_SUCCESS); + return data; } void *kope_vulkan_buffer_lock(kope_g5_buffer *buffer, uint64_t offset, uint64_t size) { - return NULL; + void *data = NULL; + VkResult result = vkMapMemory(buffer->vulkan.device, buffer->vulkan.memory, offset, size, 0, &data); + assert(result == VK_SUCCESS); + return data; } -void kope_vulkan_buffer_unlock(kope_g5_buffer *buffer) {} +void kope_vulkan_buffer_unlock(kope_g5_buffer *buffer) { + vkUnmapMemory(buffer->vulkan.device, buffer->vulkan.memory); +} diff --git a/Backends/Graphics5/Vulkan/Sources/kope/vulkan/buffer_structs.h b/Backends/Graphics5/Vulkan/Sources/kope/vulkan/buffer_structs.h index 88008aa5e..05c05ff3a 100644 --- a/Backends/Graphics5/Vulkan/Sources/kope/vulkan/buffer_structs.h +++ b/Backends/Graphics5/Vulkan/Sources/kope/vulkan/buffer_structs.h @@ -1,6 +1,8 @@ #ifndef KOPE_VULKAN_BUFFER_STRUCTS_HEADER #define KOPE_VULKAN_BUFFER_STRUCTS_HEADER +#include "vulkanmini.h" + #include #ifdef __cplusplus @@ -10,7 +12,10 @@ extern "C" { struct kope_g5_device; typedef struct kope_vulkan_buffer { - int nothing; + VkDevice device; + VkBuffer buffer; + VkDeviceMemory memory; + uint64_t size; } kope_vulkan_buffer; #ifdef __cplusplus diff --git a/Backends/Graphics5/Vulkan/Sources/kope/vulkan/device.c b/Backends/Graphics5/Vulkan/Sources/kope/vulkan/device.c index d1297dc41..483919907 100644 --- a/Backends/Graphics5/Vulkan/Sources/kope/vulkan/device.c +++ b/Backends/Graphics5/Vulkan/Sources/kope/vulkan/device.c @@ -486,7 +486,62 @@ void kope_vulkan_device_destroy(kope_g5_device *device) {} void kope_vulkan_device_set_name(kope_g5_device *device, const char *name) {} -void kope_vulkan_device_create_buffer(kope_g5_device *device, const kope_g5_buffer_parameters *parameters, kope_g5_buffer *buffer) {} +static bool memory_type_from_properties(kope_g5_device *device, uint32_t type_bits, VkFlags requirements_mask, uint32_t *type_index) { + for (uint32_t i = 0; i < 32; ++i) { + if ((type_bits & 1) == 1) { + if ((device->vulkan.device_memory_properties.memoryTypes[i].propertyFlags & requirements_mask) == requirements_mask) { + *type_index = i; + return true; + } + } + type_bits >>= 1; + } + return false; +} + +void kope_vulkan_device_create_buffer(kope_g5_device *device, const kope_g5_buffer_parameters *parameters, kope_g5_buffer *buffer) { + buffer->vulkan.device = device->vulkan.device; + + buffer->vulkan.size = parameters->size; + + VkBufferCreateInfo create_info = {0}; + create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + create_info.pNext = NULL; + create_info.size = parameters->size; + create_info.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; +#ifdef KINC_VKRT + create_info.usage |= VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT; +#endif + create_info.flags = 0; + + VkResult result = vkCreateBuffer(device->vulkan.device, &create_info, NULL, &buffer->vulkan.buffer); + assert(result == VK_SUCCESS); + + VkMemoryRequirements memory_requirements = {0}; + vkGetBufferMemoryRequirements(device->vulkan.device, buffer->vulkan.buffer, &memory_requirements); + + VkMemoryAllocateInfo memory_allocate_info; + memory_allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + memory_allocate_info.pNext = NULL; + memory_allocate_info.memoryTypeIndex = 0; + memory_allocate_info.allocationSize = memory_requirements.size; + bool memory_type_found = + memory_type_from_properties(device, memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, &memory_allocate_info.memoryTypeIndex); + assert(memory_type_found); + +#ifdef KINC_VKRT + VkMemoryAllocateFlagsInfo memory_allocate_flags_info = {0}; + memory_allocate_flags_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO; + memory_allocate_flags_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT_KHR; + memory_allocate_info.pNext = &memory_allocate_flags_info; +#endif + + result = vkAllocateMemory(device->vulkan.device, &memory_allocate_info, NULL, &buffer->vulkan.memory); + assert(result == VK_SUCCESS); + + result = vkBindBufferMemory(device->vulkan.device, buffer->vulkan.buffer, buffer->vulkan.memory, 0); + assert(result == VK_SUCCESS); +} void kope_vulkan_device_create_command_list(kope_g5_device *device, kope_g5_command_list_type type, kope_g5_command_list *list) {}