diff --git a/include/QF/Vulkan/buffer.h b/include/QF/Vulkan/buffer.h index ef11ae8b7..9346d0466 100644 --- a/include/QF/Vulkan/buffer.h +++ b/include/QF/Vulkan/buffer.h @@ -1,57 +1,43 @@ #ifndef __QF_Vulkan_buffer_h #define __QF_Vulkan_buffer_h -typedef struct qfv_buffer_s { - struct qfv_device_s *device; - VkBuffer buffer; -} qfv_buffer_t; +#include "QF/darray.h" typedef struct qfv_buffertransition_s { - qfv_buffer_t *buffer; + VkBuffer buffer; VkAccessFlags srcAccess; VkAccessFlags dstAccess; - uint32_t srcQueueFamily; - uint32_t dstQueueFamily; - VkDeviceSize offset; - VkDeviceSize size; -} qfv_buffertransition_t; - -typedef struct qfv_bufferbarrierset_s { - struct qfv_device_s *device; - uint32_t numBarriers; - VkBufferMemoryBarrier *barriers; -} qfv_bufferbarrierset_t; - -typedef struct qfv_bufferview_s { - struct qfv_device_s *device; - VkBufferView view; - qfv_buffer_t *buffer; - VkFormat format; + uint32_t srcQueueFamily; + uint32_t dstQueueFamily; VkDeviceSize offset; VkDeviceSize size; -} qfv_bufferview_t; +} qfv_buffertransition_t; + +typedef struct qfv_buffertransitionset_s + DARRAY_TYPE (qfv_buffertransition_t) qfv_buffertransitionset_t; +typedef struct qfv_bufferbarrierset_s + DARRAY_TYPE (VkBufferMemoryBarrier) qfv_bufferbarrierset_t; struct qfv_device_s; -qfv_buffer_t *QFV_CreateBuffer (struct qfv_device_s *device, - VkDeviceSize size, - VkBufferUsageFlags usage); +VkBuffer QFV_CreateBuffer (struct qfv_device_s *device, + VkDeviceSize size, + VkBufferUsageFlags usage); -struct qfv_memory_s *QFV_AllocBufferMemory (qfv_buffer_t *buffer, - VkMemoryPropertyFlags properties, - VkDeviceSize size, VkDeviceSize offset); +VkDeviceMemory QFV_AllocBufferMemory (struct qfv_device_s *device, + VkBuffer buffer, + VkMemoryPropertyFlags properties, + VkDeviceSize size, VkDeviceSize offset); -int QFV_BindBufferMemory (qfv_buffer_t *buffer, struct qfv_memory_s *memory, +int QFV_BindBufferMemory (struct qfv_device_s *device, + VkBuffer buffer, VkDeviceMemory object, VkDeviceSize offset); qfv_bufferbarrierset_t * -QFV_CreateBufferTransitionSet (qfv_buffertransition_t **transitions, - int numTransitions); +QFV_CreateBufferTransitions (qfv_buffertransition_t *transitions, + int numTransitions); -qfv_bufferview_t *QFV_CreateBufferView (qfv_buffer_t *buffer, VkFormat format, - VkDeviceSize offset, VkDeviceSize size); - -void QFV_DestroyBufferView (qfv_bufferview_t *view); - -void QFV_DestroyBuffer (qfv_buffer_t *buffer); +VkBufferView QFV_CreateBufferView (struct qfv_device_s *device, + VkBuffer buffer, VkFormat format, + VkDeviceSize offset, VkDeviceSize size); #endif//__QF_Vulkan_buffer_h diff --git a/include/QF/Vulkan/command.h b/include/QF/Vulkan/command.h index 7ef36a7f4..046c8b2b3 100644 --- a/include/QF/Vulkan/command.h +++ b/include/QF/Vulkan/command.h @@ -1,128 +1,33 @@ #ifndef __QF_Vulkan_command_h #define __QF_Vulkan_command_h -typedef struct qfv_cmdpool_s { - struct qfv_device_s *device; - VkCommandPool cmdpool; -} qfv_cmdpool_t; +#include "QF/darray.h" -typedef struct qfv_cmdbuffer_s { - struct qfv_device_s *device; - VkCommandBuffer *buffer; -} qfv_cmdbuffer_t; +typedef struct qfv_cmdbufferset_s + DARRAY_TYPE (VkCommandBuffer) qfv_cmdbufferset_t; -typedef struct qfv_cmdbufferset_s { - struct qfv_device_s *device; - qfv_cmdbuffer_t **buffers; - VkCommandBuffer *vkBuffers; - VkCommandPool cmdpool; - int numBuffers; -} qfv_cmdbufferset_t; +typedef struct qfv_semaphoreset_s + DARRAY_TYPE (VkSemaphore) qfv_semaphoreset_t; -typedef struct qfv_semaphore_s { - struct qfv_device_s *device; - VkSemaphore semaphore; -} qfv_semaphore_t; - -typedef struct qfv_semaphoreset_s { - struct qfv_device_s *device; - qfv_semaphore_t **semaphores; - VkSemaphore *vkSemaphores; - VkPipelineStageFlags *stages; - int numSemaphores; -} qfv_semaphoreset_t; - -typedef struct qfv_fence_s { - struct qfv_device_s *device; - VkFence fence; -} qfv_fence_t; - -typedef struct qfv_fenceset_s { - struct qfv_device_s *device; - qfv_fence_t **fences; - VkFence *vkFences; - int numFences; -} qfv_fenceset_t; +typedef struct qfv_fenceset_s + DARRAY_TYPE (VkFence) qfv_fenceset_t; struct qfv_queue_s; -qfv_cmdpool_t *QFV_CreateCommandPool (struct qfv_device_s *device, +struct qfv_device_s; +VkCommandPool QFV_CreateCommandPool (struct qfv_device_s *device, uint32_t queueFamily, int transient, int reset); -int QFV_ResetCommandPool (qfv_cmdpool_t *pool, int release); -void QFV_DestroyCommandPool (qfv_cmdpool_t *pool); -qfv_cmdbufferset_t *QFV_AllocateCommandBuffers (qfv_cmdpool_t *pool, +qfv_cmdbufferset_t *QFV_AllocateCommandBuffers (struct qfv_device_s *device, + VkCommandPool pool, int secondary, int count); -void QFV_FreeCommandBuffers (qfv_cmdbufferset_t *buffer); -int QFV_BeginCommandBuffer (qfv_cmdbuffer_t *buffer, int oneTime, - int rpContinue, int simultaneous, - VkCommandBufferInheritanceInfo *inheritanceInfo); -int QFV_EndCommandBuffer (qfv_cmdbuffer_t *buffer); -int QFV_ResetCommandBuffer (qfv_cmdbuffer_t *buffer, int release); -qfv_semaphore_t *QFV_CreateSemaphore (struct qfv_device_s *device); -qfv_semaphoreset_t *QFV_CreateSemaphoreSet (qfv_semaphore_t **semaphores, - int numSemaphores); -void QFV_DestroySemaphore (qfv_semaphore_t *semaphore); -// NOTE: does not destroy semaphores -void QFV_DestroySemaphoreSet (qfv_semaphoreset_t *semaphores); -qfv_fence_t *QFV_CreateFence (struct qfv_device_s *device, int signaled); -qfv_fenceset_t *QFV_CreateFenceSet (qfv_fence_t **fences, int numFences); -void QFV_DestroyFence (qfv_fence_t *fence); -// NOTE: does not destroy fences -void QFV_DestroyFenceSet (qfv_fenceset_t *fenceset); -int QFV_WaitForFences (qfv_fenceset_t *fenceset, int all, uint64_t timeout); -int QFV_WaitForFence (qfv_fence_t *fence, uint64_t timeout); -int QFV_ResetFences (qfv_fenceset_t *fenceset); -int QFV_ResetFence (qfv_fence_t *fence); +VkSemaphore QFV_CreateSemaphore (struct qfv_device_s *device); +VkFence QFV_CreateFence (struct qfv_device_s *device, int signaled); int QFV_QueueSubmit (struct qfv_queue_s *queue, qfv_semaphoreset_t *waitSemaphores, + VkPipelineStageFlags *stages, qfv_cmdbufferset_t *buffers, - qfv_semaphoreset_t *signalSemaphores, qfv_fence_t *fence); + qfv_semaphoreset_t *signalSemaphores, VkFence fence); int QFV_QueueWaitIdle (struct qfv_queue_s *queue); -struct qfv_memorybarrierset_s; -struct qfv_bufferbarrierset_s; -struct qfv_imagebarrierset_s; -void QFV_CmdPipelineBarrier (qfv_cmdbuffer_t *cmdBuffer, - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags dstStageMask, - VkDependencyFlags dependencyFlags, - struct qfv_memorybarrierset_s *memBarriers, - struct qfv_bufferbarrierset_s *buffBarriers, - struct qfv_imagebarrierset_s *imgBarriers); - -struct qfv_buffer_s; -struct qfv_image_s; -struct qfv_renderpass_s; -struct qfv_framebuffer_s; -void QFV_CmdCopyBuffer (qfv_cmdbuffer_t *cmdBuffer, - struct qfv_buffer_s *src, struct qfv_buffer_s *dst, - VkBufferCopy *regions, uint32_t numRegions); -void QFV_CmdCopyBufferToImage (qfv_cmdbuffer_t *cmdBuffer, - struct qfv_buffer_s *src, - struct qfv_image_s *dst, - VkImageLayout layout, - VkBufferImageCopy *regions, - uint32_t numRegions); -void QFV_CmdCopyImageToBuffer (qfv_cmdbuffer_t *cmdBuffer, - struct qfv_image_s *src, - VkImageLayout layout, - struct qfv_buffer_s *dst, - VkBufferImageCopy *regions, - uint32_t numRegions); -void QFV_CmdBeginRenderPass (qfv_cmdbuffer_t *cmdBuffer, - struct qfv_renderpass_s *renderPass, - struct qfv_framebuffer_s *framebuffer, - VkRect2D renderArea, - uint32_t numClearValues, - VkClearValue *clearValues, - VkSubpassContents subpassContents); -void QFV_CmdNextSubpass (qfv_cmdbuffer_t *cmdBuffer, - VkSubpassContents subpassContents); -void QFV_CmdEndRenderPass (qfv_cmdbuffer_t *cmdBuffer); -struct qfv_pipeline_s; -void QFV_CmdBindPipeline (qfv_cmdbuffer_t *cmdBuffer, - VkPipelineBindPoint bindPoint, - struct qfv_pipeline_s *pipeline); - #endif//__QF_Vulkan_command_h diff --git a/include/QF/Vulkan/device.h b/include/QF/Vulkan/device.h index c05b2ba7e..2ebc7b1d9 100644 --- a/include/QF/Vulkan/device.h +++ b/include/QF/Vulkan/device.h @@ -31,4 +31,9 @@ qfv_device_t *QFV_CreateDevice (struct vulkan_ctx_s *ctx, void QFV_DestroyDevice (qfv_device_t *device); int QFV_DeviceWaitIdle (qfv_device_t *device); +VkFormat QFV_FindSupportedFormat (qfv_device_t *device, VkImageTiling tiling, + VkFormatFeatureFlags features, + int numCandidates, + const VkFormat *candidates); + #endif//__QF_Vulkan_device_h diff --git a/include/QF/Vulkan/funclist.h b/include/QF/Vulkan/funclist.h index 5bacf29eb..426b0fa62 100644 --- a/include/QF/Vulkan/funclist.h +++ b/include/QF/Vulkan/funclist.h @@ -31,6 +31,7 @@ INSTANCE_LEVEL_VULKAN_FUNCTION (vkDestroyInstance) INSTANCE_LEVEL_VULKAN_FUNCTION (vkEnumerateDeviceLayerProperties) INSTANCE_LEVEL_VULKAN_FUNCTION (vkEnumerateDeviceExtensionProperties) INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceMemoryProperties) +INSTANCE_LEVEL_VULKAN_FUNCTION (vkGetPhysicalDeviceFormatProperties) #undef INSTANCE_LEVEL_VULKAN_FUNCTION diff --git a/include/QF/Vulkan/image.h b/include/QF/Vulkan/image.h index 4258fe2e0..8db6ee632 100644 --- a/include/QF/Vulkan/image.h +++ b/include/QF/Vulkan/image.h @@ -1,13 +1,13 @@ #ifndef __QF_Vulkan_image_h #define __QF_Vulkan_image_h -typedef struct qfv_image_s { - struct qfv_device_s *device; - VkImage image; -} qfv_image_t; +#include "QF/darray.h" + +typedef struct qfv_imageset_s DARRAY_TYPE (VkImage) qfv_imageset_t; +typedef struct qfv_imageviewset_s DARRAY_TYPE (VkImageView) qfv_imageviewset_t; typedef struct qfv_imagetransition_s { - qfv_image_t *image; + VkImage image; VkAccessFlags srcAccess; VkAccessFlags dstAccess; VkImageLayout oldLayout; @@ -17,48 +17,32 @@ typedef struct qfv_imagetransition_s { VkImageAspectFlags aspect; } qfv_imagetransition_t; -typedef struct qfv_imagebarrierset_s { - struct qfv_device_s *device; - uint32_t numBarriers; - VkImageMemoryBarrier *barriers; -} qfv_imagebarrierset_t; - -typedef struct qfv_imageview_s { - struct qfv_device_s *device; - VkImageView view; - qfv_image_t *image; - VkImageViewType type; - VkFormat format; - VkImageAspectFlags aspect; -} qfv_imageview_t; +typedef struct qfv_imagetransitionset_s + DARRAY_TYPE (qfv_imagetransition_t) qfv_imagetransitionset_t; +typedef struct qfv_imagebarrierset_s + DARRAY_TYPE (VkImageMemoryBarrier) qfv_imagebarrierset_t; struct qfv_device_s; -qfv_image_t *QFV_CreateImage (struct qfv_device_s *device, int cubemap, - VkImageType type, - VkFormat format, - VkExtent3D size, - uint32_t num_mipmaps, - uint32_t num_layers, - VkSampleCountFlagBits samples, - VkImageUsageFlags usage_scenarios); +VkImage QFV_CreateImage (struct qfv_device_s *device, int cubemap, + VkImageType type, + VkFormat format, + VkExtent3D size, + uint32_t num_mipmaps, + uint32_t num_layers, + VkSampleCountFlagBits samples, + VkImageUsageFlags usage_scenarios); -struct qfv_memory_s *QFV_AllocImageMemory (qfv_image_t *image, +VkDeviceMemory QFV_AllocImageMemory (struct qfv_device_s *device, + VkImage image, VkMemoryPropertyFlags properties, VkDeviceSize size, VkDeviceSize offset); -int QFV_BindImageMemory (qfv_image_t *image, struct qfv_memory_s *memory, - VkDeviceSize offset); - qfv_imagebarrierset_t * -QFV_CreateImageTransitionSet (qfv_imagetransition_t **transitions, +QFV_CreateImageTransitionSet (qfv_imagetransition_t *transitions, int numTransitions); -qfv_imageview_t *QFV_CreateImageView (qfv_image_t *image, VkImageViewType type, - VkFormat format, - VkImageAspectFlags aspect); - -void QFV_DestroyImageView (qfv_imageview_t *view); - -void QFV_DestroyImage (qfv_image_t *image); +VkImageView QFV_CreateImageView (struct qfv_device_s *device, + VkImage image, VkImageViewType type, + VkFormat format, VkImageAspectFlags aspect); #endif//__QF_Vulkan_image_h diff --git a/include/QF/Vulkan/instance.h b/include/QF/Vulkan/instance.h index 6c393d140..0cf5b2226 100644 --- a/include/QF/Vulkan/instance.h +++ b/include/QF/Vulkan/instance.h @@ -37,7 +37,9 @@ typedef struct qfv_instfuncs_s { } qfv_instfuncs_t; typedef struct qfv_physdev_s { + struct qfv_instance_s *instance; VkPhysicalDevice dev; + VkPhysicalDeviceProperties properties; VkPhysicalDeviceMemoryProperties memory_properties; } qfv_physdev_t; diff --git a/include/QF/Vulkan/memory.h b/include/QF/Vulkan/memory.h index 55b87f6c6..91885d31b 100644 --- a/include/QF/Vulkan/memory.h +++ b/include/QF/Vulkan/memory.h @@ -1,21 +1,22 @@ #ifndef __QF_Vulkan_memory_h #define __QF_Vulkan_memory_h -typedef struct qfv_memory_s { - struct qfv_device_s *device; - VkDeviceMemory object; -} qfv_memory_t; +#include "QF/darray.h" typedef struct qfv_mappedmemrange_s { - qfv_memory_t *memory; + VkDeviceMemory object; VkDeviceSize offset; VkDeviceSize size; } qfv_mappedmemrange_t; -void QFV_FreeMemory (qfv_memory_t *memory); -void *QFV_MapMemory (qfv_memory_t *memory, +typedef struct qfv_mappedmemrangeset_s + DARRAY_TYPE (qfv_mappedmemrange_t) qfv_mappedmemrangeset_t; + +struct qfv_device_s; + +void *QFV_MapMemory (struct qfv_device_s *device, VkDeviceMemory object, VkDeviceSize offset, VkDeviceSize size); -void QFV_UnmapMemory (qfv_memory_t *memory); -void QFV_FlushMemory (qfv_mappedmemrange_t *ranges, uint32_t numRanges); +void QFV_FlushMemory (struct qfv_device_s *device, + qfv_mappedmemrangeset_t *ranges); #endif//__QF_Vulkan_memory_h diff --git a/include/QF/Vulkan/renderpass.h b/include/QF/Vulkan/renderpass.h index c8fdc2965..3dd4acc63 100644 --- a/include/QF/Vulkan/renderpass.h +++ b/include/QF/Vulkan/renderpass.h @@ -63,7 +63,7 @@ struct qfv_imageview_s; qfv_framebuffer_t * QFV_CreateFramebuffer (qfv_renderpass_t *renderPass, uint32_t numAttachments, - struct qfv_imageview_s **attachments, + VkImageView *attachments, uint32_t width, uint32_t height, uint32_t layers); void QFV_DestroyFramebuffer (qfv_framebuffer_t *framebuffer); diff --git a/include/QF/Vulkan/swapchain.h b/include/QF/Vulkan/swapchain.h index 1a9abb896..9d04b35e4 100644 --- a/include/QF/Vulkan/swapchain.h +++ b/include/QF/Vulkan/swapchain.h @@ -5,8 +5,11 @@ typedef struct qfv_swapchain_s { struct qfv_device_s *device; VkSurfaceKHR surface; VkSwapchainKHR swapchain; + VkFormat format; + VkExtent2D extent; int32_t numImages; - VkImage *images; + struct qfv_imageset_s *images; + struct qfv_imageviewset_s *imageViews; } qfv_swapchain_t; struct vulkan_ctx_s; @@ -15,8 +18,7 @@ qfv_swapchain_t *QFV_CreateSwapchain (struct vulkan_ctx_s *ctx, void QFV_DestroySwapchain (qfv_swapchain_t *swapchain); struct qfv_semaphore_s; struct qfv_fence_s; -int QFV_AcquireNextImage (qfv_swapchain_t *swapchain, - struct qfv_semaphore_s *semaphore, - struct qfv_fence_s *fence, uint32_t *imageIndex); +int QFV_AcquireNextImage (qfv_swapchain_t *swapchain, VkSemaphore semaphore, + VkFence fence, uint32_t *imageIndex); #endif//__QF_Vulkan_swapchain_h diff --git a/include/vid_vulkan.h b/include/vid_vulkan.h index 5b9a31daf..77718ab9c 100644 --- a/include/vid_vulkan.h +++ b/include/vid_vulkan.h @@ -32,7 +32,7 @@ typedef struct vulkan_ctx_s { struct qfv_swapchain_s *swapchain; VkSurfaceKHR surface; //FIXME surface = window, so "contains" swapchain - struct qfv_cmdpool_s *cmdpool; + VkCommandPool cmdpool; vulkan_frameset_t frameset; #define EXPORTED_VULKAN_FUNCTION(fname) PFN_##fname fname; diff --git a/libs/video/renderer/vid_render_vulkan.c b/libs/video/renderer/vid_render_vulkan.c index de0917310..0373867de 100644 --- a/libs/video/renderer/vid_render_vulkan.c +++ b/libs/video/renderer/vid_render_vulkan.c @@ -33,6 +33,7 @@ //#define NH_DEFINE //#include "vulkan/namehack.h" +#include "QF/darray.h" #include "QF/sys.h" #include "QF/plugin/general.h" @@ -41,6 +42,7 @@ #include "QF/Vulkan/qf_vid.h" #include "QF/Vulkan/command.h" #include "QF/Vulkan/device.h" +#include "QF/Vulkan/image.h" #include "QF/Vulkan/instance.h" #include "QF/Vulkan/swapchain.h" @@ -56,19 +58,24 @@ static vulkan_ctx_t *vulkan_ctx; static void vulkan_R_Init (void) { + qfv_device_t *device = vulkan_ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; qfv_cmdbufferset_t *cmdBuffers; + Vulkan_CreateSwapchain (vulkan_ctx); - cmdBuffers = QFV_AllocateCommandBuffers (vulkan_ctx->cmdpool, 0, + cmdBuffers = QFV_AllocateCommandBuffers (device, vulkan_ctx->cmdpool, 0, vulkan_ctx->swapchain->numImages); vulkan_ctx->frameset.cmdBuffers = cmdBuffers; - for (int i = 0; i < cmdBuffers->numBuffers; i++) { - QFV_BeginCommandBuffer (cmdBuffers->buffers[i], 0, 0, 0, 0); - QFV_EndCommandBuffer (cmdBuffers->buffers[i]); + VkCommandBufferBeginInfo beginInfo + = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; + for (size_t i = 0; i < cmdBuffers->size; i++) { + dfunc->vkBeginCommandBuffer (cmdBuffers->a[i], &beginInfo); + dfunc->vkEndCommandBuffer (cmdBuffers->a[i]); } Sys_Printf ("R_Init %p %d", vulkan_ctx->swapchain->swapchain, vulkan_ctx->swapchain->numImages); for (int32_t i = 0; i < vulkan_ctx->swapchain->numImages; i++) { - Sys_Printf (" %p", vulkan_ctx->swapchain->images[i]); + Sys_Printf (" %p", vulkan_ctx->swapchain->images->a[i]); } Sys_Printf ("\n"); } @@ -79,39 +86,42 @@ vulkan_SCR_UpdateScreen (double time, void (*f)(void), void (**g)(void)) static int count = 0; static double startTime; uint32_t imageIndex = 0; - qfv_devfuncs_t *dfunc = vulkan_ctx->device->funcs; + qfv_device_t *device = vulkan_ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + VkDevice dev = device->dev; qfv_queue_t *queue = &vulkan_ctx->device->queue; vulkan_frameset_t *frameset = &vulkan_ctx->frameset; - QFV_WaitForFence (frameset->fences->fences[frameset->curFrame], - 2000000000); + dfunc->vkWaitForFences (dev, 1, & frameset->fences->a[frameset->curFrame], + VK_TRUE, 2000000000); QFV_AcquireNextImage (vulkan_ctx->swapchain, - frameset->imageSemaphores->semaphores[frameset->curFrame], + frameset->imageSemaphores->a[frameset->curFrame], 0, &imageIndex); - VkPipelineStageFlags waitStage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + VkPipelineStageFlags waitStage + = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO, 0, 1, - &frameset->imageSemaphores->vkSemaphores[frameset->curFrame], + &frameset->imageSemaphores->a[frameset->curFrame], &waitStage, - 1, &frameset->cmdBuffers->vkBuffers[imageIndex], - 1, &frameset->renderDoneSemaphores->vkSemaphores[frameset->curFrame], + 1, &frameset->cmdBuffers->a[imageIndex], + 1, &frameset->renderDoneSemaphores->a[frameset->curFrame], }; - QFV_ResetFence (frameset->fences->fences[frameset->curFrame]); + dfunc->vkResetFences (dev, 1, &frameset->fences->a[frameset->curFrame]); dfunc->vkQueueSubmit (queue->queue, 1, &submitInfo, - frameset->fences->vkFences[frameset->curFrame]); + frameset->fences->a[frameset->curFrame]); VkPresentInfoKHR presentInfo = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, 0, - 1, &frameset->renderDoneSemaphores->vkSemaphores[frameset->curFrame], + 1, &frameset->renderDoneSemaphores->a[frameset->curFrame], 1, &vulkan_ctx->swapchain->swapchain, &imageIndex, 0 }; dfunc->vkQueuePresentKHR (queue->queue, &presentInfo); frameset->curFrame++; - frameset->curFrame %= frameset->fences->numFences; + frameset->curFrame %= frameset->fences->size; if (++count >= 100) { double currenTime = Sys_DoubleTime (); @@ -238,7 +248,7 @@ vulkan_vid_render_choose_visual (void) Sys_Printf ("vk choose visual %p %p %d %p\n", vulkan_ctx->device->dev, vulkan_ctx->device->queue.queue, vulkan_ctx->device->queue.queueFamily, - vulkan_ctx->cmdpool->cmdpool); + vulkan_ctx->cmdpool); } static void @@ -247,19 +257,18 @@ vulkan_vid_render_create_context (void) vulkan_ctx->create_window (vulkan_ctx); vulkan_ctx->surface = vulkan_ctx->create_surface (vulkan_ctx); vulkan_ctx->frameset.curFrame = 0; - qfv_fence_t **fences = alloca (2 * sizeof (*fences)); - qfv_semaphore_t **imageSems = alloca (2 * sizeof (*imageSems)); - qfv_semaphore_t **renderDoneSems = alloca (2 * sizeof (*renderDoneSems)); + qfv_fenceset_t *fences = DARRAY_ALLOCFIXED (*fences, 2, malloc); + qfv_semaphoreset_t *imageSems = DARRAY_ALLOCFIXED (*imageSems, 2, malloc); + qfv_semaphoreset_t *renderDoneSems = DARRAY_ALLOCFIXED (*renderDoneSems, 2, + malloc); for (int i = 0; i < 2; i++) { - fences[i]= QFV_CreateFence (vulkan_ctx->device, 1); - imageSems[i] = QFV_CreateSemaphore (vulkan_ctx->device); - renderDoneSems[i] = QFV_CreateSemaphore (vulkan_ctx->device); + fences->a[i]= QFV_CreateFence (vulkan_ctx->device, 1); + imageSems->a[i] = QFV_CreateSemaphore (vulkan_ctx->device); + renderDoneSems->a[i] = QFV_CreateSemaphore (vulkan_ctx->device); } - vulkan_ctx->frameset.fences = QFV_CreateFenceSet (fences, 2); - vulkan_ctx->frameset.imageSemaphores - = QFV_CreateSemaphoreSet (imageSems, 2); - vulkan_ctx->frameset.renderDoneSemaphores - = QFV_CreateSemaphoreSet (renderDoneSems, 2); + vulkan_ctx->frameset.fences = fences; + vulkan_ctx->frameset.imageSemaphores = imageSems; + vulkan_ctx->frameset.renderDoneSemaphores = renderDoneSems; Sys_Printf ("vk create context %p\n", vulkan_ctx->surface); } @@ -282,15 +291,17 @@ vulkan_vid_render_init (void) static void vulkan_vid_render_shutdown (void) { - QFV_DeviceWaitIdle (vulkan_ctx->device); + qfv_device_t *device = vulkan_ctx->device; + qfv_devfuncs_t *df = device->funcs; + VkDevice dev = device->dev; + QFV_DeviceWaitIdle (device); vulkan_frameset_t *frameset = &vulkan_ctx->frameset; - for (int i = 0; i < frameset->fences->numFences; i++) { - QFV_DestroyFence (frameset->fences->fences[i]); - QFV_DestroySemaphore (frameset->imageSemaphores->semaphores[i]); - QFV_DestroySemaphore (frameset->renderDoneSemaphores->semaphores[i]); + for (size_t i = 0; i < frameset->fences->size; i++) { + df->vkDestroyFence (dev, frameset->fences->a[i], 0); + df->vkDestroySemaphore (dev, frameset->imageSemaphores->a[i], 0); + df->vkDestroySemaphore (dev, frameset->renderDoneSemaphores->a[i], 0); } - QFV_DestroyFenceSet (vulkan_ctx->frameset.fences); - QFV_DestroyCommandPool (vulkan_ctx->cmdpool); + df->vkDestroyCommandPool (dev, vulkan_ctx->cmdpool, 0); Vulkan_Shutdown_Common (vulkan_ctx); } diff --git a/libs/video/renderer/vulkan/buffer.c b/libs/video/renderer/vulkan/buffer.c index e2d598b81..71b094e68 100644 --- a/libs/video/renderer/vulkan/buffer.c +++ b/libs/video/renderer/vulkan/buffer.c @@ -61,7 +61,7 @@ #include "util.h" -qfv_buffer_t * +VkBuffer QFV_CreateBuffer (qfv_device_t *device, VkDeviceSize size, VkBufferUsageFlags usage) { @@ -73,24 +73,23 @@ QFV_CreateBuffer (qfv_device_t *device, VkDeviceSize size, size, usage, VK_SHARING_MODE_EXCLUSIVE, 0, 0 }; - qfv_buffer_t *buffer = malloc (sizeof (*buffer)); - dfunc->vkCreateBuffer (dev, &createInfo, 0, &buffer->buffer); - buffer->device = device; + VkBuffer buffer; + dfunc->vkCreateBuffer (dev, &createInfo, 0, &buffer); return buffer; } -qfv_memory_t * -QFV_AllocBufferMemory (qfv_buffer_t *buffer, VkMemoryPropertyFlags properties, +VkDeviceMemory +QFV_AllocBufferMemory (qfv_device_t *device, + VkBuffer buffer, VkMemoryPropertyFlags properties, VkDeviceSize size, VkDeviceSize offset) { - qfv_device_t *device = buffer->device; VkDevice dev = device->dev; qfv_physdev_t *physdev = device->physDev; VkPhysicalDeviceMemoryProperties *memprops = &physdev->memory_properties; qfv_devfuncs_t *dfunc = device->funcs; VkMemoryRequirements requirements; - dfunc->vkGetBufferMemoryRequirements (dev, buffer->buffer, &requirements); + dfunc->vkGetBufferMemoryRequirements (dev, buffer, &requirements); size = max (size, offset + requirements.size); VkDeviceMemory object = 0; @@ -112,97 +111,55 @@ QFV_AllocBufferMemory (qfv_buffer_t *buffer, VkMemoryPropertyFlags properties, } } - qfv_memory_t *memory = 0; - - if (object) { - memory = malloc (sizeof (*memory)); - memory->device = device; - memory->object = object; - } - return memory; + return object; } int -QFV_BindBufferMemory (qfv_buffer_t *buffer, qfv_memory_t *memory, +QFV_BindBufferMemory (qfv_device_t *device, + VkBuffer buffer, VkDeviceMemory object, VkDeviceSize offset) { - qfv_device_t *device = buffer->device; VkDevice dev = device->dev; qfv_devfuncs_t *dfunc = device->funcs; - VkResult res = dfunc->vkBindBufferMemory (dev, buffer->buffer, - memory->object, offset); + VkResult res = dfunc->vkBindBufferMemory (dev, buffer, object, offset); return res == VK_SUCCESS; } qfv_bufferbarrierset_t * -QFV_CreateBufferTransitionSet (qfv_buffertransition_t **transitions, - int numTransitions) +QFV_CreateBufferTransitions (qfv_buffertransition_t *transitions, + int numTransitions) { - qfv_device_t *device = transitions[0]->buffer->device; - qfv_bufferbarrierset_t *barrierset = malloc (sizeof (*barrierset) - + sizeof (VkBufferMemoryBarrier) * numTransitions); - - barrierset->device = device; - barrierset->numBarriers = numTransitions; - barrierset->barriers = (VkBufferMemoryBarrier *) (barrierset + 1); + qfv_bufferbarrierset_t *barrierset; + barrierset = DARRAY_ALLOCFIXED (*barrierset, numTransitions, malloc); for (int i = 0; i < numTransitions; i++) { - VkBufferMemoryBarrier *barrier = &barrierset->barriers[i]; - barrier->sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; - barrier->pNext = 0; - barrier->srcAccessMask = transitions[i]->srcAccess; - barrier->dstAccessMask = transitions[i]->dstAccess; - barrier->srcQueueFamilyIndex = transitions[i]->srcQueueFamily; - barrier->dstQueueFamilyIndex = transitions[i]->dstQueueFamily; - barrier->buffer = transitions[i]->buffer->buffer; - barrier->offset = transitions[i]->offset; - barrier->size = transitions[i]->size; + barrierset->a[i].sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; + barrierset->a[i].pNext = 0; + barrierset->a[i].srcAccessMask = transitions[i].srcAccess; + barrierset->a[i].dstAccessMask = transitions[i].dstAccess; + barrierset->a[i].srcQueueFamilyIndex = transitions[i].srcQueueFamily; + barrierset->a[i].dstQueueFamilyIndex = transitions[i].dstQueueFamily; + barrierset->a[i].buffer = transitions[i].buffer; + barrierset->a[i].offset = transitions[i].offset; + barrierset->a[i].size = transitions[i].size; } return barrierset; } -qfv_bufferview_t * -QFV_CreateBufferView (qfv_buffer_t *buffer, VkFormat format, +VkBufferView +QFV_CreateBufferView (qfv_device_t *device, VkBuffer buffer, VkFormat format, VkDeviceSize offset, VkDeviceSize size) { - qfv_device_t *device = buffer->device; VkDevice dev = device->dev; qfv_devfuncs_t *dfunc = device->funcs; VkBufferViewCreateInfo createInfo = { VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, 0, 0, - buffer->buffer, format, offset, size, + buffer, format, offset, size, }; - qfv_bufferview_t *view = malloc (sizeof (*view)); - view->device = device; - view->buffer = buffer; - view->format = format; - view->offset = offset; - view->size = size; - dfunc->vkCreateBufferView (dev, &createInfo, 0, &view->view); + VkBufferView view; + dfunc->vkCreateBufferView (dev, &createInfo, 0, &view); return view; } - -void -QFV_DestroyBufferView (qfv_bufferview_t *view) -{ - qfv_device_t *device = view->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkDestroyBufferView (dev, view->view, 0); - free (view); -} - -void -QFV_DestroyBuffer (qfv_buffer_t *buffer) -{ - qfv_device_t *device = buffer->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkDestroyBuffer (dev, buffer->buffer, 0); - free (buffer); -} diff --git a/libs/video/renderer/vulkan/command.c b/libs/video/renderer/vulkan/command.c index fa671fa5d..8ba60ab32 100644 --- a/libs/video/renderer/vulkan/command.c +++ b/libs/video/renderer/vulkan/command.c @@ -64,7 +64,7 @@ #include "util.h" -qfv_cmdpool_t * +VkCommandPool QFV_CreateCommandPool (qfv_device_t *device, uint32_t queueFamily, int transient, int reset) { @@ -82,43 +82,15 @@ QFV_CreateCommandPool (qfv_device_t *device, uint32_t queueFamily, flags, queueFamily }; - qfv_cmdpool_t *cmdpool = malloc (sizeof (*cmdpool)); - dfunc->vkCreateCommandPool (dev, &createInfo, 0, &cmdpool->cmdpool); - cmdpool->device = device; - return cmdpool; -} - -int -QFV_ResetCommandPool (qfv_cmdpool_t *pool, int release) -{ - qfv_device_t *device = pool->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - VkCommandPool cmdpool = pool->cmdpool; - VkCommandPoolResetFlags release_flag = 0; - - if (release) { - release_flag = VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT; - } - - return dfunc->vkResetCommandPool (dev, cmdpool, release_flag) == VK_SUCCESS; -} - -void -QFV_DestroyCommandPool (qfv_cmdpool_t *pool) -{ - qfv_device_t *device = pool->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkDestroyCommandPool (dev, pool->cmdpool, 0); - free (pool); + VkCommandPool pool; + dfunc->vkCreateCommandPool (dev, &createInfo, 0, &pool); + return pool; } qfv_cmdbufferset_t * -QFV_AllocateCommandBuffers (qfv_cmdpool_t *pool, int secondary, int count) +QFV_AllocateCommandBuffers (qfv_device_t *device, VkCommandPool pool, + int secondary, int count) { - qfv_device_t *device = pool->device; VkDevice dev = device->dev; qfv_devfuncs_t *dfunc = device->funcs; uint32_t level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; @@ -127,96 +99,15 @@ QFV_AllocateCommandBuffers (qfv_cmdpool_t *pool, int secondary, int count) } VkCommandBufferAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, 0, - pool->cmdpool, level, count + pool, level, count }; qfv_cmdbufferset_t *cmdbufferset; - cmdbufferset = malloc (sizeof (qfv_cmdbufferset_t) - + count * sizeof (qfv_buffer_t *) - + count * sizeof (qfv_buffer_t) - + count * sizeof (VkCommandBuffer)); - cmdbufferset->buffers = (qfv_cmdbuffer_t **) (cmdbufferset + 1); - cmdbufferset->vkBuffers = (VkCommandBuffer *) (cmdbufferset->buffers - + count); - qfv_cmdbuffer_t *buffer = (qfv_cmdbuffer_t *) (cmdbufferset->vkBuffers - + count); - cmdbufferset->cmdpool = pool->cmdpool; - cmdbufferset->numBuffers = count; - dfunc->vkAllocateCommandBuffers (dev, &allocInfo, cmdbufferset->vkBuffers); - for (int i = 0; i < count; i++) { - buffer->device = device; - buffer->buffer = &cmdbufferset->vkBuffers[i]; - cmdbufferset->buffers[i] = buffer++; - } + cmdbufferset = DARRAY_ALLOCFIXED (*cmdbufferset, count, malloc); + dfunc->vkAllocateCommandBuffers (dev, &allocInfo, cmdbufferset->a); return cmdbufferset; } -void QFV_FreeCommandBuffers (qfv_cmdbufferset_t *bufferset) -{ - qfv_device_t *device = bufferset->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkFreeCommandBuffers (dev, bufferset->cmdpool, - bufferset->numBuffers, - bufferset->vkBuffers); - free (bufferset); -} - -int -QFV_BeginCommandBuffer (qfv_cmdbuffer_t *buffer, int oneTime, int rpContinue, - int simultaneous, - VkCommandBufferInheritanceInfo *inheritanceInfo) -{ - qfv_device_t *device = buffer->device; - qfv_devfuncs_t *dfunc = device->funcs; - VkCommandBuffer buff = *buffer->buffer; - VkCommandBufferUsageFlags usage = 0; - - if (oneTime) { - usage |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - } - if (rpContinue) { - usage |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; - } - if (simultaneous) { - usage |= VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; - } - - VkCommandBufferBeginInfo beginInfo = { - VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 0, - usage, - 0 - }; - - return dfunc->vkBeginCommandBuffer (buff, &beginInfo) == VK_SUCCESS; -} - -int -QFV_EndCommandBuffer (qfv_cmdbuffer_t *buffer) -{ - qfv_device_t *device = buffer->device; - qfv_devfuncs_t *dfunc = device->funcs; - VkCommandBuffer buff = *buffer->buffer; - - return dfunc->vkEndCommandBuffer (buff) == VK_SUCCESS; -} - -int -QFV_ResetCommandBuffer (qfv_cmdbuffer_t *buffer, int release) -{ - qfv_device_t *device = buffer->device; - qfv_devfuncs_t *dfunc = device->funcs; - VkCommandBuffer buff = *buffer->buffer; - VkCommandBufferResetFlags release_flag = 0; - - if (release) { - release_flag = VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT; - } - - return dfunc->vkResetCommandBuffer (buff, release_flag) == VK_SUCCESS; -} - -qfv_semaphore_t * +VkSemaphore QFV_CreateSemaphore (qfv_device_t *device) { VkDevice dev = device->dev; @@ -227,58 +118,12 @@ QFV_CreateSemaphore (qfv_device_t *device) 0 }; - qfv_semaphore_t *semaphore = malloc (sizeof (*semaphore)); - semaphore->device = device; - - dfunc->vkCreateSemaphore (dev, &createInfo, 0, &semaphore->semaphore); + VkSemaphore semaphore; + dfunc->vkCreateSemaphore (dev, &createInfo, 0, &semaphore); return semaphore; } -qfv_semaphoreset_t * -QFV_CreateSemaphoreSet (qfv_semaphore_t **semaphores, int numSemaphores) -{ - qfv_device_t *device = semaphores[0]->device; - qfv_semaphoreset_t *semaphoreset; - semaphoreset = calloc (1, sizeof (*semaphoreset) - + sizeof (qfv_semaphore_t *) * numSemaphores - + sizeof (VkSemaphore) * numSemaphores - + sizeof (VkPipelineStageFlags) * numSemaphores); - - semaphoreset->device = device; - semaphoreset->vkSemaphores = (VkSemaphore *) (semaphoreset + 1); - semaphoreset->stages = (VkPipelineStageFlags *) - &semaphoreset->vkSemaphores[numSemaphores]; - semaphoreset->semaphores = (qfv_semaphore_t **) (semaphoreset->stages - + numSemaphores); - semaphoreset->numSemaphores = numSemaphores; - - if (semaphores) { - for (int i = 0; i < numSemaphores; i++) { - semaphoreset->semaphores[i] = semaphores[i]; - semaphoreset->vkSemaphores[i] = semaphores[i]->semaphore; - } - } - return semaphoreset; -} - -void -QFV_DestroySemaphore (qfv_semaphore_t *semaphore) -{ - qfv_device_t *device = semaphore->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkDestroySemaphore (dev, semaphore->semaphore, 0); - free (semaphore); -} - -void -QFV_DestroySemaphoreSet (qfv_semaphoreset_t *semaphores) -{ - free (semaphores); -} - -qfv_fence_t * +VkFence QFV_CreateFence (qfv_device_t *device, int signaled) { VkDevice dev = device->dev; @@ -289,113 +134,28 @@ QFV_CreateFence (qfv_device_t *device, int signaled) signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0, }; - qfv_fence_t *fence = malloc (sizeof (*fence)); - fence->device = device; - - dfunc->vkCreateFence (dev, &createInfo, 0, &fence->fence); + VkFence fence; + dfunc->vkCreateFence (dev, &createInfo, 0, &fence); return fence; } -qfv_fenceset_t * -QFV_CreateFenceSet (qfv_fence_t **fences, int numFences) -{ - qfv_fenceset_t *fenceset = malloc (sizeof (*fenceset) - + sizeof (qfv_fence_t) * numFences - + sizeof (VkFence) * numFences); - - fenceset->fences = (qfv_fence_t **) (fenceset + 1); - fenceset->vkFences = (VkFence *) (fenceset->fences + numFences); - fenceset->numFences = numFences; - - if (fences) { - fenceset->device = fences[0]->device; - for (int i = 0; i < numFences; i++) { - fenceset->fences[i] = fences[i]; - fenceset->vkFences[i] = fences[i]->fence; - } - } - return fenceset; -} - -void -QFV_DestroyFence (qfv_fence_t *fence) -{ - qfv_device_t *device = fence->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkDestroyFence (dev, fence->fence, 0); - free (fence); -} - -void -QFV_DestroyFenceSet (qfv_fenceset_t *fenceset) -{ - free (fenceset); -} - -int -QFV_WaitForFences (qfv_fenceset_t *fenceset, int all, uint64_t timeout) -{ - qfv_device_t *device = fenceset->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - - VkResult res = dfunc->vkWaitForFences (dev, fenceset->numFences, - fenceset->vkFences, all, timeout); - return res == VK_SUCCESS; -} - -int -QFV_WaitForFence (qfv_fence_t *fence, uint64_t timeout) -{ - qfv_device_t *device = fence->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - - VkResult res = dfunc->vkWaitForFences (dev, 1, &fence->fence, 1, timeout); - return res == VK_SUCCESS; -} - -int -QFV_ResetFences (qfv_fenceset_t *fenceset) -{ - qfv_device_t *device = fenceset->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - - return dfunc->vkResetFences (dev, fenceset->numFences, - fenceset->vkFences) == VK_SUCCESS; -} - -int -QFV_ResetFence (qfv_fence_t *fence) -{ - qfv_device_t *device = fence->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - - return dfunc->vkResetFences (dev, 1, &fence->fence) == VK_SUCCESS; -} - int QFV_QueueSubmit (qfv_queue_t *queue, qfv_semaphoreset_t *waitSemaphores, + VkPipelineStageFlags *stages, qfv_cmdbufferset_t *buffers, - qfv_semaphoreset_t *signalSemaphores, qfv_fence_t *fence) + qfv_semaphoreset_t *signalSemaphores, VkFence fence) { qfv_device_t *device = queue->device; qfv_devfuncs_t *dfunc = device->funcs; VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO, 0, - waitSemaphores->numSemaphores, - waitSemaphores->vkSemaphores, waitSemaphores->stages, - buffers->numBuffers, buffers->vkBuffers, - signalSemaphores->numSemaphores, - signalSemaphores->vkSemaphores + waitSemaphores->size, waitSemaphores->a, stages, + buffers->size, buffers->a, + signalSemaphores->size, signalSemaphores->a }; //FIXME multi-batch - return dfunc->vkQueueSubmit (queue->queue, 1, &submitInfo, - fence->fence) == VK_SUCCESS; + return dfunc->vkQueueSubmit (queue->queue, 1, &submitInfo, fence) + == VK_SUCCESS; } int @@ -405,129 +165,3 @@ QFV_QueueWaitIdle (qfv_queue_t *queue) qfv_devfuncs_t *dfunc = device->funcs; return dfunc->vkQueueWaitIdle (queue->queue) == VK_SUCCESS; } - -void -QFV_CmdPipelineBarrier (qfv_cmdbuffer_t *cmdBuffer, - VkPipelineStageFlags srcStageMask, - VkPipelineStageFlags dstStageMask, - VkDependencyFlags dependencyFlags, - struct qfv_memorybarrierset_s *memBarrierSet, - qfv_bufferbarrierset_t *buffBarrierSet, - qfv_imagebarrierset_t *imgBarrierSet) -{ - qfv_device_t *device = cmdBuffer->device; - qfv_devfuncs_t *dfunc = device->funcs; - uint32_t numMemBarriers = 0; - VkMemoryBarrier *memBarriers = 0; - uint32_t numBuffBarriers = 0; - VkBufferMemoryBarrier *buffBarriers = 0; - uint32_t numImgBarriers = 0; - VkImageMemoryBarrier *imgBarriers = 0; - - if (buffBarrierSet) { - numBuffBarriers = buffBarrierSet->numBarriers; - buffBarriers = buffBarrierSet->barriers; - } - if (imgBarrierSet) { - numImgBarriers = imgBarrierSet->numBarriers; - imgBarriers = imgBarrierSet->barriers; - } - dfunc->vkCmdPipelineBarrier (*cmdBuffer->buffer, - srcStageMask, dstStageMask, dependencyFlags, - numMemBarriers, memBarriers, - numBuffBarriers, buffBarriers, - numImgBarriers, imgBarriers); -} - -void -QFV_CmdCopyBuffer (qfv_cmdbuffer_t *cmdBuffer, - struct qfv_buffer_s *src, struct qfv_buffer_s *dst, - VkBufferCopy *regions, uint32_t numRegions) -{ - qfv_device_t *device = cmdBuffer->device; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkCmdCopyBuffer (*cmdBuffer->buffer, src->buffer, dst->buffer, - numRegions, regions); -} - -void -QFV_CmdCopyBufferToImage (qfv_cmdbuffer_t *cmdBuffer, - struct qfv_buffer_s *src, - struct qfv_image_s *dst, - VkImageLayout layout, - VkBufferImageCopy *regions, uint32_t numRegions) -{ - qfv_device_t *device = cmdBuffer->device; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkCmdCopyBufferToImage (*cmdBuffer->buffer, src->buffer, dst->image, - layout, numRegions, regions); -} - -void -QFV_CmdCopyImageToBuffer (qfv_cmdbuffer_t *cmdBuffer, - struct qfv_image_s *src, - VkImageLayout layout, - struct qfv_buffer_s *dst, - VkBufferImageCopy *regions, uint32_t numRegions) -{ - qfv_device_t *device = cmdBuffer->device; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkCmdCopyImageToBuffer (*cmdBuffer->buffer, src->image, layout, - dst->buffer, numRegions, regions); -} - -void -QFV_CmdBeginRenderPass (qfv_cmdbuffer_t *cmdBuffer, - qfv_renderpass_t *renderPass, - qfv_framebuffer_t *framebuffer, - VkRect2D renderArea, - uint32_t numClearValues, - VkClearValue *clearValues, - VkSubpassContents subpassContents) -{ - qfv_device_t *device = cmdBuffer->device; - qfv_devfuncs_t *dfunc = device->funcs; - - VkRenderPassBeginInfo beginInfo = { - VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 0, - renderPass->renderPass, framebuffer->framebuffer, renderArea, - numClearValues, clearValues, - }; - - dfunc->vkCmdBeginRenderPass (*cmdBuffer->buffer, &beginInfo, - subpassContents); -} - -void -QFV_CmdNextSubpass (qfv_cmdbuffer_t *cmdBuffer, - VkSubpassContents subpassContents) -{ - qfv_device_t *device = cmdBuffer->device; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkCmdNextSubpass (*cmdBuffer->buffer, subpassContents); -} - -void -QFV_CmdEndRenderPass (qfv_cmdbuffer_t *cmdBuffer) -{ - qfv_device_t *device = cmdBuffer->device; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkCmdEndRenderPass (*cmdBuffer->buffer); -} - -void -QFV_CmdBindPipeline (qfv_cmdbuffer_t *cmdBuffer, - VkPipelineBindPoint bindPoint, - qfv_pipeline_t *pipeline) -{ - qfv_device_t *device = cmdBuffer->device; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkCmdBindPipeline (*cmdBuffer->buffer, bindPoint, - pipeline->pipeline); -} diff --git a/libs/video/renderer/vulkan/device.c b/libs/video/renderer/vulkan/device.c index 750534f53..0457d0570 100644 --- a/libs/video/renderer/vulkan/device.c +++ b/libs/video/renderer/vulkan/device.c @@ -211,3 +211,24 @@ QFV_DeviceWaitIdle (qfv_device_t *device) qfv_devfuncs_t *dfunc = device->funcs; return dfunc->vkDeviceWaitIdle (device->dev) == VK_SUCCESS; } + +VkFormat +QFV_FindSupportedFormat (qfv_device_t *device, + VkImageTiling tiling, VkFormatFeatureFlags features, + int numCandidates, const VkFormat *candidates) +{ + VkPhysicalDevice pdev = device->physDev->dev; + qfv_instfuncs_t *ifuncs = device->physDev->instance->funcs; + for (int i = 0; i < numCandidates; i++) { + VkFormat format = candidates[i]; + VkFormatProperties props; + ifuncs->vkGetPhysicalDeviceFormatProperties (pdev, format, &props); + if ((tiling == VK_IMAGE_TILING_LINEAR + && (props.linearTilingFeatures & features) == features) + || (tiling == VK_IMAGE_TILING_OPTIMAL + && (props.optimalTilingFeatures & features) == features)) { + return format; + } + } + Sys_Error ("no supported format"); +} diff --git a/libs/video/renderer/vulkan/image.c b/libs/video/renderer/vulkan/image.c index 63b836be5..65f0dcdd3 100644 --- a/libs/video/renderer/vulkan/image.c +++ b/libs/video/renderer/vulkan/image.c @@ -61,7 +61,7 @@ #include "util.h" -qfv_image_t * +VkImage QFV_CreateImage (qfv_device_t *device, int cubemap, VkImageType type, VkFormat format, @@ -85,24 +85,23 @@ QFV_CreateImage (qfv_device_t *device, int cubemap, 0, 0, VK_IMAGE_LAYOUT_UNDEFINED, }; - qfv_image_t *image = malloc (sizeof (*image)); - dfunc->vkCreateImage (dev, &createInfo, 0, &image->image); - image->device = device; + VkImage image; + dfunc->vkCreateImage (dev, &createInfo, 0, &image); return image; } -qfv_memory_t * -QFV_AllocImageMemory (qfv_image_t *image, VkMemoryPropertyFlags properties, - VkDeviceSize size, VkDeviceSize offset) +VkDeviceMemory +QFV_AllocImageMemory (qfv_device_t *device, + VkImage image, VkMemoryPropertyFlags properties, + VkDeviceSize size, VkDeviceSize offset) { - qfv_device_t *device = image->device; VkDevice dev = device->dev; qfv_physdev_t *physdev = device->physDev; VkPhysicalDeviceMemoryProperties *memprops = &physdev->memory_properties; qfv_devfuncs_t *dfunc = device->funcs; VkMemoryRequirements requirements; - dfunc->vkGetImageMemoryRequirements (dev, image->image, &requirements); + dfunc->vkGetImageMemoryRequirements (dev, image, &requirements); size = max (size, offset + requirements.size); VkDeviceMemory object = 0; @@ -124,72 +123,48 @@ QFV_AllocImageMemory (qfv_image_t *image, VkMemoryPropertyFlags properties, } } - qfv_memory_t *memory = 0; - - if (object) { - memory = malloc (sizeof (*memory)); - memory->device = device; - memory->object = object; - } - return memory; -} - -int -QFV_BindImageMemory (qfv_image_t *image, qfv_memory_t *memory, - VkDeviceSize offset) -{ - qfv_device_t *device = image->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - VkResult res = dfunc->vkBindImageMemory (dev, image->image, - memory->object, offset); - return res == VK_SUCCESS; + return object; } qfv_imagebarrierset_t * -QFV_CreateImageTransitionSet (qfv_imagetransition_t **transitions, +QFV_CreateImageTransitionSet (qfv_imagetransition_t *transitions, int numTransitions) { - qfv_device_t *device = transitions[0]->image->device; - qfv_imagebarrierset_t *barrierset = malloc (sizeof (*barrierset) - + sizeof (VkImageMemoryBarrier) * numTransitions); - - barrierset->device = device; - barrierset->numBarriers = numTransitions; - barrierset->barriers = (VkImageMemoryBarrier *) (barrierset + 1); + qfv_imagebarrierset_t *barrierset; + barrierset = DARRAY_ALLOCFIXED (*barrierset, numTransitions, malloc); for (int i = 0; i < numTransitions; i++) { - VkImageMemoryBarrier *barrier = &barrierset->barriers[i]; - barrier->sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - barrier->pNext = 0; - barrier->srcAccessMask = transitions[i]->srcAccess; - barrier->dstAccessMask = transitions[i]->dstAccess; - barrier->oldLayout = transitions[i]->oldLayout; - barrier->newLayout = transitions[i]->newLayout; - barrier->srcQueueFamilyIndex = transitions[i]->srcQueueFamily; - barrier->dstQueueFamilyIndex = transitions[i]->dstQueueFamily; - barrier->image = transitions[i]->image->image; - barrier->subresourceRange.aspectMask = transitions[i]->aspect; - barrier->subresourceRange.baseMipLevel = 0; - barrier->subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; - barrier->subresourceRange.baseArrayLayer = 0; - barrier->subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + barrierset->a[i].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrierset->a[i].pNext = 0; + barrierset->a[i].srcAccessMask = transitions[i].srcAccess; + barrierset->a[i].dstAccessMask = transitions[i].dstAccess; + barrierset->a[i].oldLayout = transitions[i].oldLayout; + barrierset->a[i].newLayout = transitions[i].newLayout; + barrierset->a[i].srcQueueFamilyIndex = transitions[i].srcQueueFamily; + barrierset->a[i].dstQueueFamilyIndex = transitions[i].dstQueueFamily; + barrierset->a[i].image = transitions[i].image; + barrierset->a[i].subresourceRange.aspectMask = transitions[i].aspect; + barrierset->a[i].subresourceRange.baseMipLevel = 0; + barrierset->a[i].subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; + barrierset->a[i].subresourceRange.baseArrayLayer = 0; + barrierset->a[i].subresourceRange.layerCount + = VK_REMAINING_ARRAY_LAYERS; } return barrierset; } -qfv_imageview_t * -QFV_CreateImageView (qfv_image_t *image, VkImageViewType type, VkFormat format, +VkImageView +QFV_CreateImageView (qfv_device_t *device, VkImage image, + VkImageViewType type, VkFormat format, VkImageAspectFlags aspect) { - qfv_device_t *device = image->device; VkDevice dev = device->dev; qfv_devfuncs_t *dfunc = device->funcs; VkImageViewCreateInfo createInfo = { VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, 0, 0, - image->image, type, format, + image, type, format, { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, @@ -203,34 +178,7 @@ QFV_CreateImageView (qfv_image_t *image, VkImageViewType type, VkFormat format, } }; - qfv_imageview_t *view = malloc (sizeof (*view)); - view->device = device; - view->image = image; - view->type = type; - view->format = format; - view->aspect = aspect; - dfunc->vkCreateImageView (dev, &createInfo, 0, &view->view); + VkImageView view; + dfunc->vkCreateImageView (dev, &createInfo, 0, &view); return view; } - -void -QFV_DestroyImageView (qfv_imageview_t *view) -{ - qfv_device_t *device = view->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkDestroyImageView (dev, view->view, 0); - free (view); -} - -void -QFV_DestroyImage (qfv_image_t *image) -{ - qfv_device_t *device = image->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkDestroyImage (dev, image->image, 0); - free (image); -} diff --git a/libs/video/renderer/vulkan/instance.c b/libs/video/renderer/vulkan/instance.c index a744c2608..234236014 100644 --- a/libs/video/renderer/vulkan/instance.c +++ b/libs/video/renderer/vulkan/instance.c @@ -264,7 +264,9 @@ QFV_CreateInstance (vulkan_ctx_t *ctx, for (uint32_t i = 0; i < inst->numDevices; i++) { VkPhysicalDevice physDev = devices[i]; qfv_physdev_t *dev = &inst->devices[i]; + dev->instance = inst; dev->dev = physDev; + ifunc->vkGetPhysicalDeviceProperties (physDev, &dev->properties); ifunc->vkGetPhysicalDeviceMemoryProperties (physDev, &dev->memory_properties); } diff --git a/libs/video/renderer/vulkan/memory.c b/libs/video/renderer/vulkan/memory.c index c18a8144f..9397f4366 100644 --- a/libs/video/renderer/vulkan/memory.c +++ b/libs/video/renderer/vulkan/memory.c @@ -60,54 +60,32 @@ #include "util.h" -void -QFV_FreeMemory (qfv_memory_t *memory) -{ - qfv_device_t *device = memory->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - - dfunc->vkFreeMemory (dev, memory->object, 0); - free (memory); -} - void * -QFV_MapMemory (qfv_memory_t *memory, VkDeviceSize offset, VkDeviceSize size) +QFV_MapMemory (qfv_device_t *device, VkDeviceMemory object, + VkDeviceSize offset, VkDeviceSize size) { - qfv_device_t *device = memory->device; VkDevice dev = device->dev; qfv_devfuncs_t *dfunc = device->funcs; void *map = 0; - dfunc->vkMapMemory (dev, memory->object, offset, size, 0, &map); + dfunc->vkMapMemory (dev, object, offset, size, 0, &map); return map; } void -QFV_UnmapMemory (qfv_memory_t *memory) +QFV_FlushMemory (qfv_device_t *device, qfv_mappedmemrangeset_t *flushRanges) { - qfv_device_t *device = memory->device; VkDevice dev = device->dev; qfv_devfuncs_t *dfunc = device->funcs; - dfunc->vkUnmapMemory (dev, memory->object); -} + VkMappedMemoryRange *ranges = alloca(sizeof (*ranges) * flushRanges->size); -void -QFV_FlushMemory (qfv_mappedmemrange_t *flushRanges, uint32_t numFlushRanges) -{ - qfv_device_t *device = flushRanges[0].memory->device; - VkDevice dev = device->dev; - qfv_devfuncs_t *dfunc = device->funcs; - - VkMappedMemoryRange *ranges = alloca(sizeof (*ranges) * numFlushRanges); - - for (uint32_t i = 0; i < numFlushRanges; i++) { + for (uint32_t i = 0; i < flushRanges->size; i++) { ranges[i].sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; ranges[i].pNext = 0; - ranges[i].memory = flushRanges[i].memory->object; - ranges[i].offset = flushRanges[i].offset; - ranges[i].size = flushRanges[i].size; + ranges[i].memory = flushRanges->a[i].object; + ranges[i].offset = flushRanges->a[i].offset; + ranges[i].size = flushRanges->a[i].size; } - dfunc->vkFlushMappedMemoryRanges (dev, numFlushRanges, ranges); + dfunc->vkFlushMappedMemoryRanges (dev, flushRanges->size, ranges); } diff --git a/libs/video/renderer/vulkan/renderpass.c b/libs/video/renderer/vulkan/renderpass.c index 9c1064192..7a64d10a3 100644 --- a/libs/video/renderer/vulkan/renderpass.c +++ b/libs/video/renderer/vulkan/renderpass.c @@ -105,21 +105,17 @@ QFV_CreateRenderPass (qfv_device_t *device, qfv_framebuffer_t * QFV_CreateFramebuffer (qfv_renderpass_t *renderPass, - uint32_t numAttachments, qfv_imageview_t **attachments, + uint32_t numAttachments, VkImageView *attachments, uint32_t width, uint32_t height, uint32_t layers) { qfv_device_t *device = renderPass->device; VkDevice dev = device->dev; qfv_devfuncs_t *dfunc = device->funcs; - VkImageView *views = alloca (numAttachments * sizeof (*views)); - for (uint32_t i = 0; i < numAttachments; i++) { - views[i] = attachments[i]->view; - } - VkFramebufferCreateInfo createInfo = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, 0, 0, - renderPass->renderPass, numAttachments, views, width, height, layers, + renderPass->renderPass, numAttachments, attachments, + width, height, layers, }; qfv_framebuffer_t *framebuffer = malloc (sizeof (*framebuffer)); diff --git a/libs/video/renderer/vulkan/swapchain.c b/libs/video/renderer/vulkan/swapchain.c index b32e3b3ed..4ea0a36dc 100644 --- a/libs/video/renderer/vulkan/swapchain.c +++ b/libs/video/renderer/vulkan/swapchain.c @@ -13,6 +13,7 @@ #include "QF/Vulkan/cvars.h" #include "QF/Vulkan/command.h" #include "QF/Vulkan/device.h" +#include "QF/Vulkan/image.h" #include "QF/Vulkan/instance.h" #include "QF/Vulkan/swapchain.h" @@ -84,7 +85,8 @@ QFV_CreateSwapchain (vulkan_ctx_t *ctx, VkSwapchainKHR old_swapchain) VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; imageUsage &= surfCaps.supportedUsageFlags; - VkSurfaceTransformFlagBitsKHR surfTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; + VkSurfaceTransformFlagBitsKHR surfTransform + = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; uint32_t numFormats; ifuncs->vkGetPhysicalDeviceSurfaceFormatsKHR (physDev, @@ -128,24 +130,31 @@ QFV_CreateSwapchain (vulkan_ctx_t *ctx, VkSwapchainKHR old_swapchain) old_swapchain }; - VkDevice device = ctx->device->dev; + VkDevice dev = ctx->device->dev; VkSwapchainKHR swapchain; - dfuncs->vkCreateSwapchainKHR (device, &createInfo, 0, &swapchain); + dfuncs->vkCreateSwapchainKHR (dev, &createInfo, 0, &swapchain); if (old_swapchain != swapchain) { - dfuncs->vkDestroySwapchainKHR (device, old_swapchain, 0); + dfuncs->vkDestroySwapchainKHR (dev, old_swapchain, 0); } - dfuncs->vkGetSwapchainImagesKHR (device, swapchain, &numImages, 0); - qfv_swapchain_t *sc = malloc (sizeof (qfv_swapchain_t) - + numImages * sizeof (VkImage)); + dfuncs->vkGetSwapchainImagesKHR (dev, swapchain, &numImages, 0); + qfv_swapchain_t *sc = malloc (sizeof (qfv_swapchain_t)); sc->device = ctx->device; sc->surface = ctx->surface; sc->swapchain = swapchain; + sc->format = useFormat.format; + sc->extent = imageSize; sc->numImages = numImages; - sc->images = (VkImage *) (sc + 1); - dfuncs->vkGetSwapchainImagesKHR (device, swapchain, &numImages, - sc->images); + sc->images = DARRAY_ALLOCFIXED (qfv_imageset_t, numImages, malloc); + sc->imageViews = DARRAY_ALLOCFIXED (qfv_imageviewset_t, numImages, malloc); + dfuncs->vkGetSwapchainImagesKHR (dev, swapchain, &numImages, sc->images->a); + for (uint32_t i = 0; i < numImages; i++) { + sc->imageViews->a[i] + = QFV_CreateImageView (ctx->device, sc->images->a[i], + VK_IMAGE_VIEW_TYPE_2D, sc->format, + VK_IMAGE_ASPECT_COLOR_BIT); + } return sc; } @@ -155,23 +164,26 @@ QFV_DestroySwapchain (qfv_swapchain_t *swapchain) qfv_device_t *device = swapchain->device; VkDevice dev = device->dev; qfv_devfuncs_t *dfunc = device->funcs; + for (size_t i = 0; i < swapchain->imageViews->size; i++) { + dfunc->vkDestroyImageView (dev, swapchain->imageViews->a[i], 0); + } + free (swapchain->images); + free (swapchain->imageViews); dfunc->vkDestroySwapchainKHR (dev, swapchain->swapchain, 0); free (swapchain); } int -QFV_AcquireNextImage (qfv_swapchain_t *swapchain, qfv_semaphore_t *semaphore, - qfv_fence_t *fence, uint32_t *imageIndex) +QFV_AcquireNextImage (qfv_swapchain_t *swapchain, VkSemaphore semaphore, + VkFence fence, uint32_t *imageIndex) { qfv_device_t *device = swapchain->device; VkDevice dev = device->dev; qfv_devfuncs_t *dfunc = device->funcs; uint64_t timeout = 2000000000; - VkSemaphore sem = semaphore ? semaphore->semaphore : VK_NULL_HANDLE; - VkFence fnc = fence ? fence->fence : VK_NULL_HANDLE; *imageIndex = ~0u; VkResult res = dfunc->vkAcquireNextImageKHR (dev, swapchain->swapchain, - timeout, sem, fnc, + timeout, semaphore, fence, imageIndex); switch (res) { case VK_SUCCESS: