adding buffer mapping

This commit is contained in:
2024-12-05 01:26:53 +01:00
parent cddd08f92f
commit 6868047c76
10 changed files with 60 additions and 16 deletions

View File

@@ -48,6 +48,7 @@ typedef enum PulseBufferUsageBits
PULSE_BUFFER_USAGE_STORAGE_READ = PULSE_BIT(3), PULSE_BUFFER_USAGE_STORAGE_READ = PULSE_BIT(3),
PULSE_BUFFER_USAGE_STORAGE_WRITE = PULSE_BIT(4), PULSE_BUFFER_USAGE_STORAGE_WRITE = PULSE_BIT(4),
PULSE_BUFFER_USAGE_UNIFORM_ACCESS = PULSE_BIT(5), PULSE_BUFFER_USAGE_UNIFORM_ACCESS = PULSE_BIT(5),
PULSE_BUFFER_USAGE_HOST_ACCESS = PULSE_BIT(6),
} PulseShaderFormatBits; } PulseShaderFormatBits;
typedef PulseFlags PulseBufferUsageFlags; typedef PulseFlags PulseBufferUsageFlags;
@@ -106,6 +107,7 @@ typedef enum PulseErrorType
PULSE_ERROR_DEVICE_ALLOCATION_FAILED, PULSE_ERROR_DEVICE_ALLOCATION_FAILED,
PULSE_ERROR_DEVICE_LOST, PULSE_ERROR_DEVICE_LOST,
PULSE_ERROR_INVALID_INTERNAL_POINTER, PULSE_ERROR_INVALID_INTERNAL_POINTER,
PULSE_ERROR_MAP_FAILED,
} PulseErrorType; } PulseErrorType;
typedef enum PulseImageType 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 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 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 PulseBackendFlags PulseGetBackendType(PulseBackend backend);
PULSE_API void PulseSetDebugCallback(PulseBackend backend, PulseDebugCallbackPFN callback); 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 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 PulseBackendBits PulseGetBackendInUseByDevice(PulseDevice device);
PULSE_API bool PulseDeviceSupportsShaderFormats(PulseDevice device, PulseShaderFormatsFlags shader_formats_used); 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 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 void PulseDestroyBuffer(PulseDevice device, PulseBuffer buffer);
PULSE_API PulseCommandList PulseRequestCommandList(PulseDevice device, PulseCommandListUsage usage); PULSE_API PulseCommandList PulseRequestCommandList(PulseDevice device, PulseCommandListUsage usage);

View File

@@ -23,26 +23,20 @@ PulseBuffer VulkanCreateBuffer(PulseDevice device, const PulseBufferCreateInfo*
buffer->usage = create_infos->usage; buffer->usage = create_infos->usage;
if(buffer->usage & PULSE_BUFFER_USAGE_TRANSFER_UPLOAD) if(buffer->usage & PULSE_BUFFER_USAGE_TRANSFER_UPLOAD)
{
vulkan_buffer->usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT; vulkan_buffer->usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
}
if(buffer->usage & PULSE_BUFFER_USAGE_TRANSFER_DOWNLOAD) if(buffer->usage & PULSE_BUFFER_USAGE_TRANSFER_DOWNLOAD)
{
vulkan_buffer->usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT; vulkan_buffer->usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
}
if(buffer->usage & PULSE_BUFFER_USAGE_STORAGE_READ || buffer->usage & PULSE_BUFFER_USAGE_STORAGE_WRITE) if(buffer->usage & PULSE_BUFFER_USAGE_STORAGE_READ || buffer->usage & PULSE_BUFFER_USAGE_STORAGE_WRITE)
{
vulkan_buffer->usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; vulkan_buffer->usage |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
}
if(buffer->usage & PULSE_BUFFER_USAGE_UNIFORM_ACCESS) if(buffer->usage & PULSE_BUFFER_USAGE_UNIFORM_ACCESS)
{
vulkan_buffer->usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; vulkan_buffer->usage |= VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
}
VmaAllocationCreateInfo allocation_create_info = { 0 }; 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; 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 }; VkBufferCreateInfo buffer_create_info = { 0 };
buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buffer_create_info.size = buffer->size; buffer_create_info.size = buffer->size;
@@ -50,10 +44,25 @@ PulseBuffer VulkanCreateBuffer(PulseDevice device, const PulseBufferCreateInfo*
buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 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); 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; 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) void VulkanDestroyBuffer(PulseDevice device, PulseBuffer buffer)
{ {
VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(device, VulkanDevice*); VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(device, VulkanDevice*);

View File

@@ -19,9 +19,11 @@ typedef struct VulkanBuffer
VkBuffer buffer; VkBuffer buffer;
VkBufferUsageFlags usage; VkBufferUsageFlags usage;
VmaAllocation allocation; VmaAllocation allocation;
VmaAllocationInfo allocation_info;
} VulkanBuffer; } VulkanBuffer;
PulseBuffer VulkanCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos); PulseBuffer VulkanCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos);
bool VulkanGetBufferMap(PulseBuffer buffer, void** data);
void VulkanDestroyBuffer(PulseDevice device, PulseBuffer buffer); void VulkanDestroyBuffer(PulseDevice device, PulseBuffer buffer);
#endif // PULSE_VULKAN_BUFFER_H_ #endif // PULSE_VULKAN_BUFFER_H_

21
Sources/Backends/Vulkan/VulkanDescriptor.h git.filemode.normal_file
View File

@@ -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 <vulkan/vulkan_core.h>
#include <Pulse.h>
#include "../../PulseInternal.h"
typedef struct VulkanDescriptor
{
} VulkanDescriptor;
#endif // PULSE_VULKAN_DESCRIPTOR_H_
#endif // PULSE_ENABLE_VULKAN_BACKEND

View File

@@ -155,12 +155,15 @@ PULSE_API const char* PulseVerbaliseErrorType(PulseErrorType error)
switch(error) switch(error)
{ {
case PULSE_ERROR_NONE: return "no 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_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_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_CPU_ALLOCATION_FAILED: return "an internal CPU allocation failed";
case PULSE_ERROR_DEVICE_ALLOCATION_FAILED: return "a device 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_DEVICE_LOST: return "device has been lost";
case PULSE_ERROR_INVALID_INTERNAL_POINTER: return "invalid internal pointer"; case PULSE_ERROR_INVALID_INTERNAL_POINTER: return "invalid internal pointer";
case PULSE_ERROR_MAP_FAILED: return "memory mapping failed";
default: return "invalid error type"; default: return "invalid error type";
}; };

View File

@@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in LICENSE // For conditions of distribution and use, see copyright notice in LICENSE
#include "Pulse.h" #include "Pulse.h"
#include "PulseDefs.h"
#include "PulseInternal.h" #include "PulseInternal.h"
PULSE_API PulseBuffer PulseCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos) 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); 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_API void PulseDestroyBuffer(PulseDevice device, PulseBuffer buffer)
{ {
PULSE_CHECK_HANDLE(device); PULSE_CHECK_HANDLE(device);

View File

@@ -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 <PulseProfile.h>

View File

@@ -63,6 +63,7 @@
PULSE_LOAD_DRIVER_DEVICE_FUNCTION(SubmitCommandList, _namespace) \ PULSE_LOAD_DRIVER_DEVICE_FUNCTION(SubmitCommandList, _namespace) \
PULSE_LOAD_DRIVER_DEVICE_FUNCTION(ReleaseCommandList, _namespace) \ PULSE_LOAD_DRIVER_DEVICE_FUNCTION(ReleaseCommandList, _namespace) \
PULSE_LOAD_DRIVER_DEVICE_FUNCTION(CreateBuffer, _namespace) \ PULSE_LOAD_DRIVER_DEVICE_FUNCTION(CreateBuffer, _namespace) \
PULSE_LOAD_DRIVER_DEVICE_FUNCTION(GetBufferMap, _namespace) \
PULSE_LOAD_DRIVER_DEVICE_FUNCTION(DestroyBuffer, _namespace) \ PULSE_LOAD_DRIVER_DEVICE_FUNCTION(DestroyBuffer, _namespace) \
#endif // PULSE_DEFS_H_ #endif // PULSE_DEFS_H_

View File

@@ -70,6 +70,7 @@ typedef struct PulseDeviceHandler
PulseSubmitCommandListPFN PFN_SubmitCommandList; PulseSubmitCommandListPFN PFN_SubmitCommandList;
PulseReleaseCommandListPFN PFN_ReleaseCommandList; PulseReleaseCommandListPFN PFN_ReleaseCommandList;
PulseCreateBufferPFN PFN_CreateBuffer; PulseCreateBufferPFN PFN_CreateBuffer;
PulseGetBufferMapPFN PFN_GetBufferMap;
PulseDestroyBufferPFN PFN_DestroyBuffer; PulseDestroyBufferPFN PFN_DestroyBuffer;
// Attributes // Attributes

View File

@@ -25,6 +25,7 @@ typedef PulseCommandList (*PulseRequestCommandListPFN)(PulseDevice, PulseCommand
typedef bool (*PulseSubmitCommandListPFN)(PulseDevice, PulseCommandList, PulseFence); typedef bool (*PulseSubmitCommandListPFN)(PulseDevice, PulseCommandList, PulseFence);
typedef void (*PulseReleaseCommandListPFN)(PulseDevice, PulseCommandList); typedef void (*PulseReleaseCommandListPFN)(PulseDevice, PulseCommandList);
typedef PulseBuffer (*PulseCreateBufferPFN)(PulseDevice, const PulseBufferCreateInfo*); typedef PulseBuffer (*PulseCreateBufferPFN)(PulseDevice, const PulseBufferCreateInfo*);
typedef bool (*PulseGetBufferMapPFN)(PulseBuffer, void**);
typedef void (*PulseDestroyBufferPFN)(PulseDevice, PulseBuffer); typedef void (*PulseDestroyBufferPFN)(PulseDevice, PulseBuffer);
#endif // PULSE_PFNS_H_ #endif // PULSE_PFNS_H_