Rework much of the Vulkan array handling

So much for all those little wrappers hiding the device. Some survived,
but mostly just the bigger things like device, swapchain, etc.
This commit is contained in:
Bill Currie 2020-02-17 20:29:35 +09:00
parent 65890dd2fb
commit 94565c2382
19 changed files with 282 additions and 837 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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");
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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));

View file

@ -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: