From 848844059c1bd41a004073615c56c6ee984c61bc Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Sun, 8 Dec 2024 16:43:51 +0100 Subject: [PATCH] adding manual buffer mapping --- Includes/Pulse.h | 3 +- Sources/Backends/Vulkan/VulkanBuffer.c | 29 ++++++++++---------- Sources/Backends/Vulkan/VulkanBuffer.h | 3 +- Sources/PulseBuffer.c | 14 ++++++++-- Sources/PulseDefs.h | 3 +- Sources/PulseInternal.h | 4 ++- Sources/PulsePFNs.h | 3 +- Tests/Vulkan/Buffer.c | 38 ++++++++++++++++++++++++++ 8 files changed, 76 insertions(+), 21 deletions(-) diff --git a/Includes/Pulse.h b/Includes/Pulse.h index 1d934d0..a43e497 100644 --- a/Includes/Pulse.h +++ b/Includes/Pulse.h @@ -273,7 +273,8 @@ PULSE_API bool PulseDeviceSupportsShaderFormats(PulseDevice device, PulseShaderF PULSE_API void PulseDestroyDevice(PulseDevice device); PULSE_API PulseBuffer PulseCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos); -PULSE_API bool PulseGetBufferMap(PulseBuffer buffer, void** data); +PULSE_API bool PulseMapBuffer(PulseBuffer buffer, void** data); +PULSE_API void PulseUnmapBuffer(PulseBuffer buffer); PULSE_API void PulseDestroyBuffer(PulseDevice device, PulseBuffer buffer); PULSE_API PulseImage PulseCreateImage(PulseDevice device, const PulseImageCreateInfo* create_infos); diff --git a/Sources/Backends/Vulkan/VulkanBuffer.c b/Sources/Backends/Vulkan/VulkanBuffer.c index 37d185d..d360d5f 100644 --- a/Sources/Backends/Vulkan/VulkanBuffer.c +++ b/Sources/Backends/Vulkan/VulkanBuffer.c @@ -25,23 +25,23 @@ PulseBuffer VulkanCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* VmaAllocationCreateInfo allocation_create_info = { 0 }; allocation_create_info.usage = VMA_MEMORY_USAGE_AUTO; - if(buffer->usage & PULSE_BUFFER_USAGE_STORAGE_READ || buffer->usage & PULSE_BUFFER_USAGE_STORAGE_WRITE) - vulkan_buffer->usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; if(buffer->usage & PULSE_BUFFER_USAGE_TRANSFER_UPLOAD) { vulkan_buffer->usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - allocation_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; + allocation_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; } if(buffer->usage & PULSE_BUFFER_USAGE_TRANSFER_DOWNLOAD) { vulkan_buffer->usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; - allocation_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; + allocation_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; } if(buffer->usage & PULSE_BUFFER_USAGE_UNIFORM_ACCESS) { vulkan_buffer->usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; - allocation_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; + allocation_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; } + if(buffer->usage & PULSE_BUFFER_USAGE_STORAGE_READ || buffer->usage & PULSE_BUFFER_USAGE_STORAGE_WRITE) + vulkan_buffer->usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; VkBufferCreateInfo buffer_create_info = { 0 }; buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; @@ -55,20 +55,21 @@ PulseBuffer VulkanCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* return buffer; } -bool VulkanGetBufferMap(PulseBuffer buffer, void** data) +bool VulkanMapBuffer(PulseBuffer buffer, void** data) { VulkanBuffer* vulkan_buffer = VULKAN_RETRIEVE_DRIVER_DATA_AS(buffer, VulkanBuffer*); - if(vulkan_buffer->allocation_info.pMappedData == PULSE_NULLPTR) - { - if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(buffer->device->backend)) - PulseLogErrorFmt(buffer->device->backend, "(Vulkan) cannot map a buffer (%p); Buffer has to be created with PULSE_BUFFER_USAGE_HOST_ACCESS flag", buffer); - PulseSetInternalError(PULSE_ERROR_MAP_FAILED); - return false; - } - *data = vulkan_buffer->allocation_info.pMappedData; + VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(buffer->device, VulkanDevice*); + CHECK_VK_RETVAL(buffer->device->backend, vmaMapMemory(vulkan_device->allocator, vulkan_buffer->allocation, data), PULSE_ERROR_MAP_FAILED, false); return true; } +void VulkanUnmapBuffer(PulseBuffer buffer) +{ + VulkanBuffer* vulkan_buffer = VULKAN_RETRIEVE_DRIVER_DATA_AS(buffer, VulkanBuffer*); + VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(buffer->device, VulkanDevice*); + vmaUnmapMemory(vulkan_device->allocator, vulkan_buffer->allocation); +} + void VulkanDestroyBuffer(PulseDevice device, PulseBuffer buffer) { VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(device, VulkanDevice*); diff --git a/Sources/Backends/Vulkan/VulkanBuffer.h b/Sources/Backends/Vulkan/VulkanBuffer.h index 5d9448b..7a8c2dc 100644 --- a/Sources/Backends/Vulkan/VulkanBuffer.h +++ b/Sources/Backends/Vulkan/VulkanBuffer.h @@ -23,7 +23,8 @@ typedef struct VulkanBuffer } VulkanBuffer; PulseBuffer VulkanCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos); -bool VulkanGetBufferMap(PulseBuffer buffer, void** data); +bool VulkanMapBuffer(PulseBuffer buffer, void** data); +void VulkanUnmapBuffer(PulseBuffer buffer); void VulkanDestroyBuffer(PulseDevice device, PulseBuffer buffer); #endif // PULSE_VULKAN_BUFFER_H_ diff --git a/Sources/PulseBuffer.c b/Sources/PulseBuffer.c index 7ae2e71..98ed6d7 100644 --- a/Sources/PulseBuffer.c +++ b/Sources/PulseBuffer.c @@ -21,11 +21,21 @@ PULSE_API PulseBuffer PulseCreateBuffer(PulseDevice device, const PulseBufferCre return device->PFN_CreateBuffer(device, create_infos); } -PULSE_API bool PulseGetBufferMap(PulseBuffer buffer, void** data) +PULSE_API bool PulseMapBuffer(PulseBuffer buffer, void** data) { PULSE_CHECK_HANDLE_RETVAL(buffer, false); PULSE_CHECK_PTR_RETVAL(data, false); - return buffer->device->PFN_GetBufferMap(buffer, data); + bool res = buffer->device->PFN_MapBuffer(buffer, data); + if(res) + buffer->is_mapped = true; + return res; +} + +PULSE_API void PulseUnmapBuffer(PulseBuffer buffer) +{ + PULSE_CHECK_HANDLE(buffer); + buffer->device->PFN_UnmapBuffer(buffer); + buffer->is_mapped = false; } PULSE_API void PulseDestroyBuffer(PulseDevice device, PulseBuffer buffer) diff --git a/Sources/PulseDefs.h b/Sources/PulseDefs.h index db3da4e..845718b 100644 --- a/Sources/PulseDefs.h +++ b/Sources/PulseDefs.h @@ -90,7 +90,8 @@ PULSE_LOAD_DRIVER_DEVICE_FUNCTION(SubmitCommandList, _namespace) \ PULSE_LOAD_DRIVER_DEVICE_FUNCTION(ReleaseCommandList, _namespace) \ PULSE_LOAD_DRIVER_DEVICE_FUNCTION(CreateBuffer, _namespace) \ - PULSE_LOAD_DRIVER_DEVICE_FUNCTION(GetBufferMap, _namespace) \ + PULSE_LOAD_DRIVER_DEVICE_FUNCTION(MapBuffer, _namespace) \ + PULSE_LOAD_DRIVER_DEVICE_FUNCTION(UnmapBuffer, _namespace) \ PULSE_LOAD_DRIVER_DEVICE_FUNCTION(DestroyBuffer, _namespace) \ PULSE_LOAD_DRIVER_DEVICE_FUNCTION(CreateImage, _namespace) \ PULSE_LOAD_DRIVER_DEVICE_FUNCTION(DestroyImage, _namespace) \ diff --git a/Sources/PulseInternal.h b/Sources/PulseInternal.h index eaa576a..62d180c 100644 --- a/Sources/PulseInternal.h +++ b/Sources/PulseInternal.h @@ -34,6 +34,7 @@ typedef struct PulseBufferHandler void* driver_data; PulseBufferUsageFlags usage; PulseDeviceSize size; + bool is_mapped; } PulseBufferHandler; typedef struct PulseCommandListHandler @@ -70,7 +71,8 @@ typedef struct PulseDeviceHandler PulseSubmitCommandListPFN PFN_SubmitCommandList; PulseReleaseCommandListPFN PFN_ReleaseCommandList; PulseCreateBufferPFN PFN_CreateBuffer; - PulseGetBufferMapPFN PFN_GetBufferMap; + PulseMapBufferPFN PFN_MapBuffer; + PulseUnmapBufferPFN PFN_UnmapBuffer; PulseDestroyBufferPFN PFN_DestroyBuffer; PulseCreateImagePFN PFN_CreateImage; PulseDestroyImagePFN PFN_DestroyImage; diff --git a/Sources/PulsePFNs.h b/Sources/PulsePFNs.h index f9a72a1..b19674c 100644 --- a/Sources/PulsePFNs.h +++ b/Sources/PulsePFNs.h @@ -25,7 +25,8 @@ typedef PulseCommandList (*PulseRequestCommandListPFN)(PulseDevice, PulseCommand typedef bool (*PulseSubmitCommandListPFN)(PulseDevice, PulseCommandList, PulseFence); typedef void (*PulseReleaseCommandListPFN)(PulseDevice, PulseCommandList); typedef PulseBuffer (*PulseCreateBufferPFN)(PulseDevice, const PulseBufferCreateInfo*); -typedef bool (*PulseGetBufferMapPFN)(PulseBuffer, void**); +typedef bool (*PulseMapBufferPFN)(PulseBuffer, void**); +typedef void (*PulseUnmapBufferPFN)(PulseBuffer); typedef void (*PulseDestroyBufferPFN)(PulseDevice, PulseBuffer); typedef PulseImage (*PulseCreateImagePFN)(PulseDevice, const PulseImageCreateInfo*); typedef void (*PulseDestroyImagePFN)(PulseDevice, PulseImage); diff --git a/Tests/Vulkan/Buffer.c b/Tests/Vulkan/Buffer.c index 8fe00f5..16c9932 100644 --- a/Tests/Vulkan/Buffer.c +++ b/Tests/Vulkan/Buffer.c @@ -1,5 +1,6 @@ #include "Common.h" +#include #include #include @@ -71,7 +72,44 @@ void TestBufferCreation() CleanupPulse(backend); } +void TestBufferMapping() +{ + PulseBackend backend; + SetupPulse(&backend); + PulseDevice device; + SetupDevice(backend, &device); + + const unsigned char data[8] = { 0xA1, 0xFF, 0xDF, 0x17, 0x5B, 0xCC, 0x00, 0x36 }; + + PulseBufferCreateInfo buffer_create_info = { 0 }; + buffer_create_info.size = 8; + buffer_create_info.usage = PULSE_BUFFER_USAGE_TRANSFER_UPLOAD; + PulseBuffer buffer = PulseCreateBuffer(device, &buffer_create_info); + TEST_ASSERT_NOT_EQUAL_MESSAGE(buffer, PULSE_NULL_HANDLE, PulseVerbaliseErrorType(PulseGetLastErrorType())); + + { + void* ptr; + TEST_ASSERT_NOT_EQUAL_MESSAGE(PulseMapBuffer(buffer, &ptr), false, PulseVerbaliseErrorType(PulseGetLastErrorType())); + TEST_ASSERT_NOT_NULL(ptr); + memcpy(ptr, data, 8); + PulseUnmapBuffer(buffer); + } + { + void* ptr; + TEST_ASSERT_NOT_EQUAL_MESSAGE(PulseMapBuffer(buffer, &ptr), false, PulseVerbaliseErrorType(PulseGetLastErrorType())); + TEST_ASSERT_NOT_NULL(ptr); + TEST_ASSERT_EQUAL(memcmp(ptr, data, 8), 0); + PulseUnmapBuffer(buffer); + } + + PulseDestroyBuffer(device, buffer); + + CleanupDevice(device); + CleanupPulse(backend); +} + void TestBuffer() { RUN_TEST(TestBufferCreation); + RUN_TEST(TestBufferMapping); }