From 6868047c7688b9d77919065a852f8b263f4d5c1b Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Thu, 5 Dec 2024 01:26:53 +0100 Subject: [PATCH] adding buffer mapping --- Includes/Pulse.h | 7 ++++-- Sources/Backends/Vulkan/VulkanBuffer.c | 27 ++++++++++++++-------- Sources/Backends/Vulkan/VulkanBuffer.h | 2 ++ Sources/Backends/Vulkan/VulkanDescriptor.h | 21 +++++++++++++++++ Sources/PulseBackend.c | 3 +++ Sources/PulseBuffer.c | 8 +++++++ Sources/PulseDebug.c | 5 ---- Sources/PulseDefs.h | 1 + Sources/PulseInternal.h | 1 + Sources/PulsePFNs.h | 1 + 10 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 Sources/Backends/Vulkan/VulkanDescriptor.h delete mode 100644 Sources/PulseDebug.c diff --git a/Includes/Pulse.h b/Includes/Pulse.h index 86f5582..c582dfa 100644 --- a/Includes/Pulse.h +++ b/Includes/Pulse.h @@ -48,6 +48,7 @@ typedef enum PulseBufferUsageBits PULSE_BUFFER_USAGE_STORAGE_READ = PULSE_BIT(3), PULSE_BUFFER_USAGE_STORAGE_WRITE = PULSE_BIT(4), PULSE_BUFFER_USAGE_UNIFORM_ACCESS = PULSE_BIT(5), + PULSE_BUFFER_USAGE_HOST_ACCESS = PULSE_BIT(6), } PulseShaderFormatBits; typedef PulseFlags PulseBufferUsageFlags; @@ -106,6 +107,7 @@ typedef enum PulseErrorType PULSE_ERROR_DEVICE_ALLOCATION_FAILED, PULSE_ERROR_DEVICE_LOST, PULSE_ERROR_INVALID_INTERNAL_POINTER, + PULSE_ERROR_MAP_FAILED, } PulseErrorType; typedef enum PulseImageType @@ -260,16 +262,17 @@ typedef void (*PulseDebugCallbackPFN)(PulseDebugMessageSeverity, const char*); PULSE_API bool PulseSupportsBackend(PulseBackendFlags backend_candidates, PulseShaderFormatsFlags shader_formats_used); PULSE_API PulseBackend PulseLoadBackend(PulseBackendFlags backend_candidates, PulseShaderFormatsFlags shader_formats_used, PulseDebugLevel debug_level); -PULSE_API void PulseUnloadBackend(PulseBackend backend); PULSE_API PulseBackendFlags PulseGetBackendType(PulseBackend backend); PULSE_API void PulseSetDebugCallback(PulseBackend backend, PulseDebugCallbackPFN callback); +PULSE_API void PulseUnloadBackend(PulseBackend backend); PULSE_API PulseDevice PulseCreateDevice(PulseBackend backend, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count); -PULSE_API void PulseDestroyDevice(PulseDevice device); PULSE_API PulseBackendBits PulseGetBackendInUseByDevice(PulseDevice device); PULSE_API bool PulseDeviceSupportsShaderFormats(PulseDevice device, PulseShaderFormatsFlags shader_formats_used); +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 void PulseDestroyBuffer(PulseDevice device, PulseBuffer buffer); PULSE_API PulseCommandList PulseRequestCommandList(PulseDevice device, PulseCommandListUsage usage); diff --git a/Sources/Backends/Vulkan/VulkanBuffer.c b/Sources/Backends/Vulkan/VulkanBuffer.c index 7453fd8..adb3cd2 100644 --- a/Sources/Backends/Vulkan/VulkanBuffer.c +++ b/Sources/Backends/Vulkan/VulkanBuffer.c @@ -23,26 +23,20 @@ PulseBuffer VulkanCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* buffer->usage = create_infos->usage; if(buffer->usage & PULSE_BUFFER_USAGE_TRANSFER_UPLOAD) - { vulkan_buffer->usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - } if(buffer->usage & PULSE_BUFFER_USAGE_TRANSFER_DOWNLOAD) - { vulkan_buffer->usage |= VK_BUFFER_USAGE_TRANSFER_DST_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; - } if(buffer->usage & PULSE_BUFFER_USAGE_UNIFORM_ACCESS) - { vulkan_buffer->usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; - } VmaAllocationCreateInfo allocation_create_info = { 0 }; - allocation_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT; allocation_create_info.usage = VMA_MEMORY_USAGE_AUTO; + if(buffer->usage & PULSE_BUFFER_USAGE_HOST_ACCESS) + allocation_create_info.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; + VkBufferCreateInfo buffer_create_info = { 0 }; buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buffer_create_info.size = buffer->size; @@ -50,10 +44,25 @@ PulseBuffer VulkanCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; CHECK_VK_RETVAL(device->backend, vmaCreateBuffer(vulkan_device->allocator, &buffer_create_info, &allocation_create_info, &vulkan_buffer->buffer, &vulkan_buffer->allocation, PULSE_NULLPTR), PULSE_ERROR_INITIALIZATION_FAILED, PULSE_NULL_HANDLE); + vmaGetAllocationInfo(vulkan_device->allocator, vulkan_buffer->allocation, &vulkan_buffer->allocation_info); return buffer; } +bool VulkanGetBufferMap(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; + return true; +} + 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 a72dfdc..5d9448b 100644 --- a/Sources/Backends/Vulkan/VulkanBuffer.h +++ b/Sources/Backends/Vulkan/VulkanBuffer.h @@ -19,9 +19,11 @@ typedef struct VulkanBuffer VkBuffer buffer; VkBufferUsageFlags usage; VmaAllocation allocation; + VmaAllocationInfo allocation_info; } VulkanBuffer; PulseBuffer VulkanCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos); +bool VulkanGetBufferMap(PulseBuffer buffer, void** data); void VulkanDestroyBuffer(PulseDevice device, PulseBuffer buffer); #endif // PULSE_VULKAN_BUFFER_H_ diff --git a/Sources/Backends/Vulkan/VulkanDescriptor.h b/Sources/Backends/Vulkan/VulkanDescriptor.h new file mode 100644 index 0000000..3c72805 --- /dev/null +++ b/Sources/Backends/Vulkan/VulkanDescriptor.h @@ -0,0 +1,21 @@ +// Copyright (C) 2024 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#ifdef PULSE_ENABLE_VULKAN_BACKEND + +#ifndef PULSE_VULKAN_DESCRIPTOR_H_ +#define PULSE_VULKAN_DESCRIPTOR_H_ + +#include + +#include +#include "../../PulseInternal.h" + +typedef struct VulkanDescriptor +{ +} VulkanDescriptor; + +#endif // PULSE_VULKAN_DESCRIPTOR_H_ + +#endif // PULSE_ENABLE_VULKAN_BACKEND diff --git a/Sources/PulseBackend.c b/Sources/PulseBackend.c index 3a5cb76..58b4b77 100644 --- a/Sources/PulseBackend.c +++ b/Sources/PulseBackend.c @@ -155,12 +155,15 @@ PULSE_API const char* PulseVerbaliseErrorType(PulseErrorType error) switch(error) { case PULSE_ERROR_NONE: return "no error"; + case PULSE_ERROR_INVALID_BACKEND: return "invalid backend"; + case PULSE_ERROR_INVALID_HANDLE: return "invalid handle"; case PULSE_ERROR_BACKENDS_CANDIDATES_SHADER_FORMAT_MISMATCH: return "no backend candidates support the required shader formats"; case PULSE_ERROR_INITIALIZATION_FAILED: return "initialization of an object could not be completed for implementation-specific reasons"; case PULSE_ERROR_CPU_ALLOCATION_FAILED: return "an internal CPU allocation failed"; case PULSE_ERROR_DEVICE_ALLOCATION_FAILED: return "a device allocation failed"; case PULSE_ERROR_DEVICE_LOST: return "device has been lost"; case PULSE_ERROR_INVALID_INTERNAL_POINTER: return "invalid internal pointer"; + case PULSE_ERROR_MAP_FAILED: return "memory mapping failed"; default: return "invalid error type"; }; diff --git a/Sources/PulseBuffer.c b/Sources/PulseBuffer.c index 3750b9d..7ae2e71 100644 --- a/Sources/PulseBuffer.c +++ b/Sources/PulseBuffer.c @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in LICENSE #include "Pulse.h" +#include "PulseDefs.h" #include "PulseInternal.h" PULSE_API PulseBuffer PulseCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos) @@ -20,6 +21,13 @@ PULSE_API PulseBuffer PulseCreateBuffer(PulseDevice device, const PulseBufferCre return device->PFN_CreateBuffer(device, create_infos); } +PULSE_API bool PulseGetBufferMap(PulseBuffer buffer, void** data) +{ + PULSE_CHECK_HANDLE_RETVAL(buffer, false); + PULSE_CHECK_PTR_RETVAL(data, false); + return buffer->device->PFN_GetBufferMap(buffer, data); +} + PULSE_API void PulseDestroyBuffer(PulseDevice device, PulseBuffer buffer) { PULSE_CHECK_HANDLE(device); diff --git a/Sources/PulseDebug.c b/Sources/PulseDebug.c deleted file mode 100644 index 0da9104..0000000 --- a/Sources/PulseDebug.c +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (C) 2024 kanel -// This file is part of "Pulse" -// For conditions of distribution and use, see copyright notice in LICENSE - -#include diff --git a/Sources/PulseDefs.h b/Sources/PulseDefs.h index 1d4a554..fd6c222 100644 --- a/Sources/PulseDefs.h +++ b/Sources/PulseDefs.h @@ -63,6 +63,7 @@ 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(DestroyBuffer, _namespace) \ #endif // PULSE_DEFS_H_ diff --git a/Sources/PulseInternal.h b/Sources/PulseInternal.h index 89a1e3c..5a6e4aa 100644 --- a/Sources/PulseInternal.h +++ b/Sources/PulseInternal.h @@ -70,6 +70,7 @@ typedef struct PulseDeviceHandler PulseSubmitCommandListPFN PFN_SubmitCommandList; PulseReleaseCommandListPFN PFN_ReleaseCommandList; PulseCreateBufferPFN PFN_CreateBuffer; + PulseGetBufferMapPFN PFN_GetBufferMap; PulseDestroyBufferPFN PFN_DestroyBuffer; // Attributes diff --git a/Sources/PulsePFNs.h b/Sources/PulsePFNs.h index cfa97a0..6597739 100644 --- a/Sources/PulsePFNs.h +++ b/Sources/PulsePFNs.h @@ -25,6 +25,7 @@ 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 void (*PulseDestroyBufferPFN)(PulseDevice, PulseBuffer); #endif // PULSE_PFNS_H_