mirror of
https://github.com/Kbz-8/Pulse.git
synced 2026-01-11 23:43:34 +00:00
adding command list Vulkan support
This commit is contained in:
@@ -55,6 +55,39 @@ void VulkanUnloadBackend(PulseBackend backend)
|
||||
VulkanLoaderShutdown();
|
||||
}
|
||||
|
||||
const char* VulkanVerbaliseResult(VkResult res)
|
||||
{
|
||||
switch(res)
|
||||
{
|
||||
case VK_SUCCESS: return "Success";
|
||||
case VK_NOT_READY: return "A fence or query has not yet completed";
|
||||
case VK_TIMEOUT: return "A wait operation has not completed in the specified time";
|
||||
case VK_EVENT_SET: return "An event is signaled";
|
||||
case VK_EVENT_RESET: return "An event is unsignaled";
|
||||
case VK_INCOMPLETE: return "A return array was too small for the result";
|
||||
case VK_ERROR_OUT_OF_HOST_MEMORY: return "A host memory allocation has failed";
|
||||
case VK_ERROR_OUT_OF_DEVICE_MEMORY: return "A device memory allocation has failed";
|
||||
case VK_ERROR_INITIALIZATION_FAILED: return "Initialization of an object could not be completed for implementation-specific reasons";
|
||||
case VK_ERROR_DEVICE_LOST: return "The logical or physical device has been lost";
|
||||
case VK_ERROR_MEMORY_MAP_FAILED: return "Mapping of a memory object has failed";
|
||||
case VK_ERROR_LAYER_NOT_PRESENT: return "A requested layer is not present or could not be loaded";
|
||||
case VK_ERROR_EXTENSION_NOT_PRESENT: return "A requested extension is not supported";
|
||||
case VK_ERROR_FEATURE_NOT_PRESENT: return "A requested feature is not supported";
|
||||
case VK_ERROR_INCOMPATIBLE_DRIVER: return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible";
|
||||
case VK_ERROR_TOO_MANY_OBJECTS: return "Too many objects of the type have already been created";
|
||||
case VK_ERROR_FORMAT_NOT_SUPPORTED: return "A requested format is not supported on this device";
|
||||
case VK_ERROR_SURFACE_LOST_KHR: return "A surface is no longer available";
|
||||
case VK_SUBOPTIMAL_KHR: return "A swapchain no longer matches the surface properties exactly, but can still be used";
|
||||
case VK_ERROR_OUT_OF_DATE_KHR: return "A surface has changed in such a way that it is no longer compatible with the swapchain";
|
||||
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: return "The display used by a swapchain does not use the same presentable image layout";
|
||||
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API";
|
||||
case VK_ERROR_VALIDATION_FAILED_EXT: return "A validation layer found an error";
|
||||
|
||||
default: return "Unknown Vulkan error";
|
||||
}
|
||||
return "Unknown Vulkan error"; // Just to avoid warnings
|
||||
}
|
||||
|
||||
PulseBackendHandler VulkanDriver = {
|
||||
.PFN_LoadBackend = VulkanLoadBackend,
|
||||
.PFN_UnloadBackend = VulkanUnloadBackend,
|
||||
|
||||
@@ -16,14 +16,16 @@
|
||||
|
||||
#define VULKAN_RETRIEVE_DRIVER_DATA_AS(handle, cast) ((cast)handle->driver_data)
|
||||
|
||||
#define CHECK_VK_RETVAL(res, error, retval) \
|
||||
#define CHECK_VK_RETVAL(backend, res, error, retval) \
|
||||
if((res) != VK_SUCCESS) \
|
||||
{ \
|
||||
if(backend != PULSE_NULL_HANDLE && PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(backend)) \
|
||||
PulseLogErrorFmt(backend, "(Vulkan) Call to Vulkan function failed due to %s", VulkanVerbaliseResult(res)); \
|
||||
PulseSetInternalError(error); \
|
||||
return retval; \
|
||||
}
|
||||
|
||||
#define CHECK_VK(res, error) CHECK_VK_RETVAL(res, error, )
|
||||
#define CHECK_VK(backend, res, error) CHECK_VK_RETVAL(backend, res, error, )
|
||||
|
||||
typedef struct VulkanGlobal
|
||||
{
|
||||
@@ -39,6 +41,8 @@ typedef struct VulkanDriverData
|
||||
|
||||
VulkanGlobal* VulkanGetGlobal();
|
||||
|
||||
const char* VulkanVerbaliseResult(VkResult res);
|
||||
|
||||
PulseBackendFlags VulkanCheckSupport(PulseBackendFlags candidates, PulseShaderFormatsFlags shader_formats_used); // Return PULSE_BACKEND_VULKAN in case of success and PULSE_BACKEND_INVALID otherwise
|
||||
|
||||
#endif // PULSE_VULKAN_H_
|
||||
|
||||
171
Sources/Backends/Vulkan/VulkanCommandList.c
git.filemode.normal_file
171
Sources/Backends/Vulkan/VulkanCommandList.c
git.filemode.normal_file
@@ -0,0 +1,171 @@
|
||||
// Copyright (C) 2024 kanel
|
||||
// This file is part of "Pulse"
|
||||
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||
|
||||
#include "Pulse.h"
|
||||
#include "Vulkan.h"
|
||||
#include "VulkanCommandList.h"
|
||||
#include "VulkanCommandPool.h"
|
||||
#include "VulkanDevice.h"
|
||||
#include "VulkanQueue.h"
|
||||
|
||||
static void VulkanInitCommandList(VulkanCommandPool* pool, PulseCommandList cmd)
|
||||
{
|
||||
PULSE_CHECK_PTR(pool);
|
||||
PULSE_CHECK_PTR(cmd);
|
||||
|
||||
VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(pool->device, VulkanDevice*);
|
||||
VulkanCommandList* vulkan_cmd = VULKAN_RETRIEVE_DRIVER_DATA_AS(cmd, VulkanCommandList*);
|
||||
|
||||
vulkan_cmd->pool = pool;
|
||||
|
||||
VkCommandBufferAllocateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
info.commandPool = pool->pool;
|
||||
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
info.commandBufferCount = 1;
|
||||
CHECK_VK(pool->device->backend, vulkan_device->vkAllocateCommandBuffers(vulkan_device->device, &info, &vulkan_cmd->cmd), PULSE_ERROR_INITIALIZATION_FAILED);
|
||||
|
||||
if(pool->available_command_lists_size == pool->available_command_lists_capacity)
|
||||
{
|
||||
pool->available_command_lists_capacity += 5;
|
||||
pool->available_command_lists = (PulseCommandList*)realloc(pool->available_command_lists, pool->available_command_lists_capacity * sizeof(PulseCommandList));
|
||||
PULSE_CHECK_ALLOCATION(pool->available_command_lists);
|
||||
}
|
||||
pool->available_command_lists[pool->available_command_lists_size] = cmd;
|
||||
pool->available_command_lists_size++;
|
||||
}
|
||||
|
||||
PulseCommandList VulkanRequestCommandList(PulseDevice device, PulseCommandListUsage usage)
|
||||
{
|
||||
PULSE_CHECK_HANDLE_RETVAL(device, PULSE_NULL_HANDLE);
|
||||
|
||||
VulkanCommandPool* pool;
|
||||
switch(usage)
|
||||
{
|
||||
case PULSE_COMMAND_LIST_TRANSFER_ONLY: pool = VulkanRequestCmdPoolFromDevice(device, VULKAN_QUEUE_TRANSFER); break;
|
||||
case PULSE_COMMAND_LIST_GENERAL: // fallthrough
|
||||
default: pool = VulkanRequestCmdPoolFromDevice(device, VULKAN_QUEUE_COMPUTE); break;
|
||||
}
|
||||
|
||||
PULSE_CHECK_PTR_RETVAL(pool, PULSE_NULL_HANDLE);
|
||||
|
||||
PulseCommandList cmd = PULSE_NULL_HANDLE;
|
||||
|
||||
for(uint32_t i = 0; i < pool->available_command_lists_size; i++)
|
||||
{
|
||||
if(pool->available_command_lists[i]->is_available)
|
||||
{
|
||||
cmd = pool->available_command_lists[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(cmd == PULSE_NULL_HANDLE)
|
||||
{
|
||||
cmd = (PulseCommandList)calloc(1, sizeof(PulseCommandListHandler));
|
||||
PULSE_CHECK_ALLOCATION_RETVAL(cmd, PULSE_NULL_HANDLE);
|
||||
|
||||
VulkanCommandList* vulkan_cmd = (VulkanCommandList*)calloc(1, sizeof(VulkanCommandList));
|
||||
PULSE_CHECK_ALLOCATION_RETVAL(vulkan_cmd, PULSE_NULL_HANDLE);
|
||||
|
||||
cmd->usage = usage;
|
||||
cmd->device = device;
|
||||
cmd->driver_data = vulkan_cmd;
|
||||
cmd->thread_id = pool->thread_id;
|
||||
|
||||
VulkanInitCommandList(pool, cmd);
|
||||
}
|
||||
|
||||
cmd->compute_pipelines_bound_size = 0;
|
||||
cmd->state = PULSE_COMMAND_LIST_STATE_EMPTY;
|
||||
cmd->is_available = false;
|
||||
cmd->is_compute_pipeline_bound = false;
|
||||
|
||||
VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(device, VulkanDevice*);
|
||||
VulkanCommandList* vulkan_cmd = VULKAN_RETRIEVE_DRIVER_DATA_AS(cmd, VulkanCommandList*);
|
||||
|
||||
CHECK_VK_RETVAL(device->backend, vulkan_device->vkResetCommandBuffer(vulkan_cmd->cmd, 0), PULSE_ERROR_DEVICE_ALLOCATION_FAILED, PULSE_NULL_HANDLE);
|
||||
|
||||
VkCommandBufferBeginInfo begin_info = {};
|
||||
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
begin_info.flags = 0;
|
||||
VkResult res = vulkan_device->vkBeginCommandBuffer(vulkan_cmd->cmd, &begin_info);
|
||||
switch(res)
|
||||
{
|
||||
case VK_SUCCESS: break;
|
||||
case VK_ERROR_OUT_OF_HOST_MEMORY: PulseSetInternalError(PULSE_ERROR_CPU_ALLOCATION_FAILED); return PULSE_NULL_HANDLE;
|
||||
case VK_ERROR_OUT_OF_DEVICE_MEMORY: PulseSetInternalError(PULSE_ERROR_DEVICE_ALLOCATION_FAILED); return PULSE_NULL_HANDLE;
|
||||
default: break;
|
||||
}
|
||||
return cmd;
|
||||
}
|
||||
|
||||
bool VulkanSubmitCommandList(PulseDevice device, PulseCommandList cmd, PulseFence fence)
|
||||
{
|
||||
PULSE_UNUSED(device);
|
||||
PULSE_CHECK_HANDLE_RETVAL(cmd, false);
|
||||
|
||||
VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(device, VulkanDevice*);
|
||||
VulkanCommandList* vulkan_cmd = VULKAN_RETRIEVE_DRIVER_DATA_AS(cmd, VulkanCommandList*);
|
||||
|
||||
VkResult res = vulkan_device->vkEndCommandBuffer(vulkan_cmd->cmd);
|
||||
switch(res)
|
||||
{
|
||||
case VK_SUCCESS: break;
|
||||
case VK_ERROR_OUT_OF_HOST_MEMORY: PulseSetInternalError(PULSE_ERROR_CPU_ALLOCATION_FAILED); return false;
|
||||
case VK_ERROR_OUT_OF_DEVICE_MEMORY: PulseSetInternalError(PULSE_ERROR_DEVICE_ALLOCATION_FAILED); return false;
|
||||
default: break;
|
||||
}
|
||||
|
||||
VkFence vulkan_fence;
|
||||
if(fence != PULSE_NULL_HANDLE)
|
||||
{
|
||||
vulkan_fence = VULKAN_RETRIEVE_DRIVER_DATA_AS(device, VkFence);
|
||||
vulkan_device->vkResetFences(vulkan_device->device, 1, &vulkan_fence);
|
||||
}
|
||||
|
||||
VulkanQueue* vulkan_queue;
|
||||
switch(cmd->usage)
|
||||
{
|
||||
case PULSE_COMMAND_LIST_TRANSFER_ONLY: vulkan_queue = vulkan_device->queues[VULKAN_QUEUE_TRANSFER]; break;
|
||||
case PULSE_COMMAND_LIST_GENERAL: // fallthrough
|
||||
default: vulkan_queue = vulkan_device->queues[VULKAN_QUEUE_COMPUTE]; break;
|
||||
}
|
||||
|
||||
PULSE_CHECK_PTR_RETVAL(vulkan_queue, false);
|
||||
|
||||
VkSubmitInfo submit_info = {};
|
||||
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submit_info.commandBufferCount = 1;
|
||||
submit_info.pCommandBuffers = &vulkan_cmd->cmd;
|
||||
res = vulkan_device->vkQueueSubmit(vulkan_queue->queue, 1, &submit_info, vulkan_fence);
|
||||
switch(res)
|
||||
{
|
||||
case VK_SUCCESS: return true;
|
||||
|
||||
case VK_ERROR_OUT_OF_HOST_MEMORY: PulseSetInternalError(PULSE_ERROR_CPU_ALLOCATION_FAILED); return false;
|
||||
case VK_ERROR_OUT_OF_DEVICE_MEMORY: PulseSetInternalError(PULSE_ERROR_DEVICE_ALLOCATION_FAILED); return false;
|
||||
case VK_ERROR_DEVICE_LOST: PulseSetInternalError(PULSE_ERROR_DEVICE_LOST); return false;
|
||||
|
||||
default: return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void VulkanReleaseCommandList(PulseDevice device, PulseCommandList cmd)
|
||||
{
|
||||
PULSE_CHECK_HANDLE(device);
|
||||
|
||||
VulkanCommandList* vulkan_cmd = VULKAN_RETRIEVE_DRIVER_DATA_AS(cmd, VulkanCommandList*);
|
||||
|
||||
for(uint32_t i = 0; i < vulkan_cmd->pool->available_command_lists_size; i++)
|
||||
{
|
||||
if(vulkan_cmd->pool->available_command_lists[i] == cmd)
|
||||
{
|
||||
cmd->is_available = true;
|
||||
cmd->state = PULSE_COMMAND_LIST_STATE_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,22 +10,17 @@
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include <Pulse.h>
|
||||
#include "../../PulseInternal.h"
|
||||
#include "VulkanCommandPool.h"
|
||||
|
||||
typedef struct VulkanCommandList
|
||||
{
|
||||
PulseDevice device;
|
||||
VulkanCommandPool* pool;
|
||||
PulseThreadID thread_id;
|
||||
VkCommandBuffer cmd;
|
||||
|
||||
PulseComputePipeline* compute_pipelines_bound;
|
||||
uint32_t compute_pipelines_bound_capacity;
|
||||
uint32_t compute_pipelines_bound_size;
|
||||
} VulkanCommandList;
|
||||
|
||||
void VulkanInitCommandList(VulkanCommandPool* pool);
|
||||
PulseCommandList VulkanRequestCommandList(PulseDevice device, PulseCommandListUsage usage);
|
||||
bool VulkanSubmitCommandList(PulseDevice device, PulseCommandList cmd, PulseFence fence);
|
||||
void VulkanReleaseCommandList(PulseDevice device, PulseCommandList cmd);
|
||||
|
||||
#endif // PULSE_VULKAN_COMMAND_LIST_H_
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ bool VulkanInitCommandPool(PulseDevice device, VulkanCommandPool* pool, VulkanQu
|
||||
create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||
create_info.queueFamilyIndex = vulkan_device->queues[queue_type]->queue_family_index;
|
||||
create_info.pNext = PULSE_NULLPTR;
|
||||
CHECK_VK_RETVAL(vulkan_device->vkCreateCommandPool(vulkan_device->device, &create_info, PULSE_NULLPTR, &pool->pool), PULSE_ERROR_INITIALIZATION_FAILED, false);
|
||||
CHECK_VK_RETVAL(device->backend, vulkan_device->vkCreateCommandPool(vulkan_device->device, &create_info, PULSE_NULLPTR, &pool->pool), PULSE_ERROR_INITIALIZATION_FAILED, false);
|
||||
|
||||
pool->thread_id = PulseGetThreadID();
|
||||
|
||||
|
||||
17
Sources/Backends/Vulkan/VulkanComputePipeline.c
git.filemode.normal_file
17
Sources/Backends/Vulkan/VulkanComputePipeline.c
git.filemode.normal_file
@@ -0,0 +1,17 @@
|
||||
// Copyright (C) 2024 kanel
|
||||
// This file is part of "Pulse"
|
||||
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||
|
||||
#include "VulkanComputePipeline.h"
|
||||
|
||||
PulseComputePipeline VulkanCreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info)
|
||||
{
|
||||
}
|
||||
|
||||
void VulkanBindComputePipeline(PulseComputePass pass, PulseComputePipeline pipeline)
|
||||
{
|
||||
}
|
||||
|
||||
void VulkanDestroyComputePipeline(PulseDevice device, PulseComputePipeline pipeline)
|
||||
{
|
||||
}
|
||||
@@ -16,7 +16,7 @@ typedef struct VulkanComputePipeline
|
||||
} VulkanComputePipeline;
|
||||
|
||||
PulseComputePipeline VulkanCreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info);
|
||||
void VulkanBindComputePipeline(PulseComputePass pass, PulseComputePipeline pipeline);
|
||||
void VulkanBindComputePipeline(PulseComputePipeline pipeline);
|
||||
void VulkanDestroyComputePipeline(PulseDevice device, PulseComputePipeline pipeline);
|
||||
|
||||
#endif // PULSE_VULKAN_COMPUTE_PIPELINE_H_
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Pulse.h"
|
||||
#include "Vulkan.h"
|
||||
#include "VulkanComputePipeline.h"
|
||||
#include "VulkanCommandList.h"
|
||||
#include "VulkanDevice.h"
|
||||
#include "VulkanFence.h"
|
||||
#include "VulkanInstance.h"
|
||||
@@ -175,9 +176,11 @@ PulseDevice VulkanCreateDevice(PulseBackend backend, PulseDevice* forbiden_devic
|
||||
create_info.flags = 0;
|
||||
create_info.pNext = PULSE_NULLPTR;
|
||||
|
||||
CHECK_VK_RETVAL(instance->vkCreateDevice(device->physical, &create_info, PULSE_NULLPTR, &device->device), PULSE_ERROR_INITIALIZATION_FAILED, PULSE_NULLPTR);
|
||||
CHECK_VK_RETVAL(backend, instance->vkCreateDevice(device->physical, &create_info, PULSE_NULLPTR, &device->device), PULSE_ERROR_INITIALIZATION_FAILED, PULSE_NULLPTR);
|
||||
if(!VulkanLoadDevice(instance, device))
|
||||
{
|
||||
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(backend))
|
||||
PulseLogInfoFmt(backend, "(Vulkan) Could not load device functions from %s", device->properties.deviceName);
|
||||
PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED);
|
||||
return PULSE_NULLPTR;
|
||||
}
|
||||
@@ -217,11 +220,14 @@ PulseDevice VulkanCreateDevice(PulseBackend backend, PulseDevice* forbiden_devic
|
||||
allocator_create_info.instance = instance->instance;
|
||||
allocator_create_info.pVulkanFunctions = &vma_vulkan_func;
|
||||
|
||||
CHECK_VK_RETVAL(vmaCreateAllocator(&allocator_create_info, &device->allocator), PULSE_ERROR_INITIALIZATION_FAILED, PULSE_NULLPTR);
|
||||
CHECK_VK_RETVAL(backend, vmaCreateAllocator(&allocator_create_info, &device->allocator), PULSE_ERROR_INITIALIZATION_FAILED, PULSE_NULLPTR);
|
||||
|
||||
pulse_device->driver_data = device;
|
||||
pulse_device->backend = backend;
|
||||
PULSE_LOAD_DRIVER_DEVICE(Vulkan);
|
||||
|
||||
if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(backend))
|
||||
PulseLogInfoFmt(backend, "(Vulkan) Created device from %s", device->properties.deviceName);
|
||||
return pulse_device;
|
||||
}
|
||||
|
||||
@@ -230,8 +236,35 @@ void VulkanDestroyDevice(PulseDevice device)
|
||||
VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(device, VulkanDevice*);
|
||||
if(vulkan_device == PULSE_NULLPTR || vulkan_device->device == VK_NULL_HANDLE)
|
||||
return;
|
||||
for(uint32_t i = 0; i < vulkan_device->cmd_pools_size; i++)
|
||||
vulkan_device->vkDestroyCommandPool(vulkan_device->device, vulkan_device->cmd_pools[i].pool, PULSE_NULLPTR);
|
||||
vmaDestroyAllocator(vulkan_device->allocator);
|
||||
vulkan_device->vkDestroyDevice(vulkan_device->device, PULSE_NULLPTR);
|
||||
if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(device->backend))
|
||||
PulseLogInfoFmt(device->backend, "(Vulkan) Destroyed device created from %s", vulkan_device->properties.deviceName);
|
||||
free(vulkan_device->cmd_pools);
|
||||
free(vulkan_device);
|
||||
free(device);
|
||||
}
|
||||
|
||||
VulkanCommandPool* VulkanRequestCmdPoolFromDevice(PulseDevice device, VulkanQueueType queue_type)
|
||||
{
|
||||
PULSE_CHECK_HANDLE_RETVAL(device, PULSE_NULLPTR);
|
||||
VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(device, VulkanDevice*);
|
||||
if(vulkan_device == PULSE_NULLPTR || vulkan_device->device == VK_NULL_HANDLE)
|
||||
return PULSE_NULLPTR;
|
||||
|
||||
PulseThreadID thread_id = PulseGetThreadID();
|
||||
|
||||
for(uint32_t i = 0; i < vulkan_device->cmd_pools_size; i++)
|
||||
{
|
||||
if(thread_id == vulkan_device->cmd_pools[i].thread_id && queue_type == vulkan_device->cmd_pools[i].queue_type)
|
||||
return &vulkan_device->cmd_pools[i];
|
||||
}
|
||||
|
||||
vulkan_device->cmd_pools_size++;
|
||||
vulkan_device->cmd_pools = (VulkanCommandPool*)realloc(vulkan_device->cmd_pools, vulkan_device->cmd_pools_size * sizeof(VulkanCommandPool));
|
||||
if(!VulkanInitCommandPool(device, &vulkan_device->cmd_pools[vulkan_device->cmd_pools_size - 1], queue_type))
|
||||
return PULSE_NULLPTR;
|
||||
return &vulkan_device->cmd_pools[vulkan_device->cmd_pools_size - 1];
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ struct VulkanQueue;
|
||||
typedef struct VulkanDevice
|
||||
{
|
||||
VulkanCommandPool* cmd_pools;
|
||||
uint32_t cmd_pools_size;
|
||||
|
||||
struct VulkanQueue* queues[VULKAN_QUEUE_END_ENUM];
|
||||
|
||||
@@ -43,6 +44,7 @@ typedef struct VulkanDevice
|
||||
|
||||
PulseDevice VulkanCreateDevice(PulseBackend backend, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count);
|
||||
void VulkanDestroyDevice(PulseDevice device);
|
||||
VulkanCommandPool* VulkanRequestCmdPoolFromDevice(PulseDevice device, VulkanQueueType queue_type);
|
||||
|
||||
#endif // PULSE_VULKAN_DEVICE_H_
|
||||
|
||||
|
||||
@@ -10,12 +10,14 @@
|
||||
|
||||
PulseFence VulkanCreateFence(PulseDevice device)
|
||||
{
|
||||
PULSE_CHECK_HANDLE_RETVAL(device, PULSE_NULL_HANDLE);
|
||||
|
||||
VkFenceCreateInfo fence_info = {};
|
||||
fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||
VkFence vulkan_fence;
|
||||
VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(device, VulkanDevice*);
|
||||
CHECK_VK_RETVAL(vulkan_device->vkCreateFence(vulkan_device->device, &fence_info, PULSE_NULLPTR, &vulkan_fence), PULSE_ERROR_INITIALIZATION_FAILED, PULSE_NULL_HANDLE);
|
||||
CHECK_VK_RETVAL(device->backend, vulkan_device->vkCreateFence(vulkan_device->device, &fence_info, PULSE_NULLPTR, &vulkan_fence), PULSE_ERROR_INITIALIZATION_FAILED, PULSE_NULL_HANDLE);
|
||||
|
||||
PulseFenceHandler* fence = (PulseFenceHandler*)malloc(sizeof(PulseFenceHandler));
|
||||
PULSE_CHECK_ALLOCATION_RETVAL(fence, PULSE_NULL_HANDLE);
|
||||
@@ -25,6 +27,15 @@ PulseFence VulkanCreateFence(PulseDevice device)
|
||||
|
||||
void VulkanDestroyFence(PulseDevice device, PulseFence fence)
|
||||
{
|
||||
PULSE_CHECK_HANDLE(device);
|
||||
|
||||
if(fence == PULSE_NULL_HANDLE)
|
||||
{
|
||||
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend))
|
||||
PulseLogWarning(device->backend, "fence is NULL, this may be a bug in your application");
|
||||
return;
|
||||
}
|
||||
|
||||
VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(device, VulkanDevice*);
|
||||
if(vulkan_device == PULSE_NULLPTR || vulkan_device->device == VK_NULL_HANDLE)
|
||||
return;
|
||||
@@ -37,6 +48,9 @@ void VulkanDestroyFence(PulseDevice device, PulseFence fence)
|
||||
|
||||
bool VulkanIsFenceReady(PulseDevice device, PulseFence fence)
|
||||
{
|
||||
PULSE_CHECK_HANDLE_RETVAL(device, false);
|
||||
PULSE_CHECK_HANDLE_RETVAL(fence, false);
|
||||
|
||||
VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(device, VulkanDevice*);
|
||||
if(vulkan_device == PULSE_NULLPTR || vulkan_device->device == VK_NULL_HANDLE)
|
||||
return false;
|
||||
@@ -66,7 +80,7 @@ bool VulkanWaitForFences(PulseDevice device, const PulseFence* fences, uint32_t
|
||||
VkFence* vulkan_fences = (VkFence*)calloc(fences_count, sizeof(VkFence));
|
||||
PULSE_CHECK_ALLOCATION_RETVAL(vulkan_fences, false);
|
||||
for(uint32_t i = 0; i < fences_count; i++)
|
||||
vulkan_fences[i] = VULKAN_RETRIEVE_DRIVER_DATA_AS(((PulseFence)fences + i), VkFence);
|
||||
vulkan_fences[i] = VULKAN_RETRIEVE_DRIVER_DATA_AS(((PulseFence)fences[i]), VkFence);
|
||||
VkResult result = vulkan_device->vkWaitForFences(vulkan_device->device, fences_count, vulkan_fences, wait_for_all, UINT64_MAX);
|
||||
free(vulkan_fences);
|
||||
switch(result)
|
||||
|
||||
@@ -36,7 +36,7 @@ static VkInstance VulkanCreateInstance(const char** extensions_enabled, uint32_t
|
||||
create_info.flags = 0;
|
||||
#endif
|
||||
|
||||
CHECK_VK_RETVAL(VulkanGetGlobal()->vkCreateInstance(&create_info, PULSE_NULLPTR, &instance), PULSE_ERROR_INITIALIZATION_FAILED, VK_NULL_HANDLE);
|
||||
CHECK_VK_RETVAL(PULSE_NULL_HANDLE, VulkanGetGlobal()->vkCreateInstance(&create_info, PULSE_NULLPTR, &instance), PULSE_ERROR_INITIALIZATION_FAILED, VK_NULL_HANDLE);
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user