diff --git a/include/QF/Vulkan/command.h b/include/QF/Vulkan/command.h index 9326617ca..ffb462b98 100644 --- a/include/QF/Vulkan/command.h +++ b/include/QF/Vulkan/command.h @@ -92,6 +92,8 @@ void QFV_CmdPipelineBarrier (qfv_cmdbuffer_t *cmdBuffer, 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); @@ -107,5 +109,15 @@ void QFV_CmdCopyImageToBuffer (qfv_cmdbuffer_t *cmdBuffer, 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); #endif//__QF_Vulkan_command_h diff --git a/include/QF/Vulkan/funclist.h b/include/QF/Vulkan/funclist.h index e25188999..f51e53478 100644 --- a/include/QF/Vulkan/funclist.h +++ b/include/QF/Vulkan/funclist.h @@ -139,10 +139,18 @@ DEVICE_LEVEL_VULKAN_FUNCTION (vkDestroyDescriptorPool) DEVICE_LEVEL_VULKAN_FUNCTION (vkDestroyDescriptorSetLayout) DEVICE_LEVEL_VULKAN_FUNCTION (vkDestroySampler) +DEVICE_LEVEL_VULKAN_FUNCTION (vkCreateRenderPass) +DEVICE_LEVEL_VULKAN_FUNCTION (vkCreateFramebuffer) +DEVICE_LEVEL_VULKAN_FUNCTION (vkDestroyRenderPass) +DEVICE_LEVEL_VULKAN_FUNCTION (vkDestroyFramebuffer) + DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdPipelineBarrier) DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdCopyBuffer) DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdCopyBufferToImage) DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdCopyImageToBuffer) +DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdBeginRenderPass) +DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdNextSubpass) +DEVICE_LEVEL_VULKAN_FUNCTION (vkCmdEndRenderPass) #undef DEVICE_LEVEL_VULKAN_FUNCTION diff --git a/include/QF/Vulkan/renderpass.h b/include/QF/Vulkan/renderpass.h new file mode 100644 index 000000000..c8fdc2965 --- /dev/null +++ b/include/QF/Vulkan/renderpass.h @@ -0,0 +1,72 @@ +#ifndef __QF_Vulkan_renderpass_h +#define __QF_Vulkan_renderpass_h + +typedef struct qfv_attachmentdescription_s { + uint32_t numAttachments; + VkAttachmentDescription attachments[]; +} qfv_attachmentdescription_t; + +#define QFV_AllocAttachmentDescription(num, allocator) \ + allocator (field_offset (qfv_attachmentdescription_t, attachments[num])) + +typedef struct qfv_attachmentreference_s { + uint32_t numReferences; + VkAttachmentReference references[]; +} qfv_attachmentreference_t; + +#define QFV_AllocAttachmentReference(num, allocator) \ + allocator (field_offset (qfv_attachmentreference_t, references[num])) + +typedef struct qfv_subpassparameters_s { + VkPipelineBindPoint pipelineBindPoint; + qfv_attachmentreference_t *inputAttachments; + qfv_attachmentreference_t *colorAttachments; + qfv_attachmentreference_t *resolveAttachments; + VkAttachmentReference *depthStencilAttachment; + uint32_t numPreserve; + uint32_t *preserveAttachments; +} qfv_subpassparameters_t; + +typedef struct qfv_subpassparametersset_s { + uint32_t numSubpasses; + qfv_subpassparameters_t subpasses[]; +} qfv_subpassparametersset_t; + +#define QFV_AllocSubpassParametersSet(num, allocator) \ + allocator (field_offset (qfv_subpassparametersset_t, subpasses[num])) + +typedef struct qfv_subpassdependency_s { + uint32_t numDependencies; + VkSubpassDependency dependencies[]; +} qfv_subpassdependency_t; + +#define QFV_AllocSubpassDependencies(num, allocator) \ + allocator (field_offset (qfv_subpassdependency_t, dependencies[num])) + +typedef struct qfv_renderpass_s { + struct qfv_device_s *device; + VkRenderPass renderPass; +} qfv_renderpass_t; + +typedef struct qfv_framebuffer_s { + struct qfv_device_s *device; + VkFramebuffer framebuffer; +} qfv_framebuffer_t; + +qfv_renderpass_t * +QFV_CreateRenderPass (struct qfv_device_s *device, + qfv_attachmentdescription_t *attachments, + qfv_subpassparametersset_t *subpasses, + qfv_subpassdependency_t *dependencies); + +struct qfv_imageview_s; +qfv_framebuffer_t * +QFV_CreateFramebuffer (qfv_renderpass_t *renderPass, + uint32_t numAttachments, + struct qfv_imageview_s **attachments, + uint32_t width, uint32_t height, uint32_t layers); + +void QFV_DestroyFramebuffer (qfv_framebuffer_t *framebuffer); +void QFV_DestroyRenderPass (qfv_renderpass_t *renderPass); + +#endif//__QF_Vulkan_renderpass_h diff --git a/libs/video/renderer/vulkan/Makefile.am b/libs/video/renderer/vulkan/Makefile.am index ec888d6cd..936dd504d 100644 --- a/libs/video/renderer/vulkan/Makefile.am +++ b/libs/video/renderer/vulkan/Makefile.am @@ -11,6 +11,7 @@ vulkan_src = \ image.c \ instance.c \ memory.c \ + renderpass.c \ swapchain.c \ util.c \ vulkan_draw.c \ diff --git a/libs/video/renderer/vulkan/command.c b/libs/video/renderer/vulkan/command.c index 46c2ed83f..15e884b64 100644 --- a/libs/video/renderer/vulkan/command.c +++ b/libs/video/renderer/vulkan/command.c @@ -51,6 +51,7 @@ #include "QF/Vulkan/qf_vid.h" #include "QF/Vulkan/buffer.h"//FIXME should QFV_CmdPipelineBarrier be here? #include "QF/Vulkan/image.h"//FIXME should QFV_CmdPipelineBarrier be here? +#include "QF/Vulkan/renderpass.h"//FIXME should QFV_CmdPipelineBarrier be here? #include "QF/Vulkan/command.h" #include "QF/Vulkan/device.h" #include "QF/Vulkan/instance.h" @@ -462,3 +463,44 @@ QFV_CmdCopyImageToBuffer (qfv_cmdbuffer_t *cmdBuffer, 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); +} diff --git a/libs/video/renderer/vulkan/renderpass.c b/libs/video/renderer/vulkan/renderpass.c new file mode 100644 index 000000000..9c1064192 --- /dev/null +++ b/libs/video/renderer/vulkan/renderpass.c @@ -0,0 +1,151 @@ +/* + descriptor.c + + Vulkan descriptor functions + + Copyright (C) 1996-1997 Id Software, Inc. + Copyright (C) 2020 Bill Currie + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + +*/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_MATH_H +# include +#endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + +#include "QF/cvar.h" +#include "QF/dstring.h" +#include "QF/hash.h" +#include "QF/input.h" +#include "QF/mathlib.h" +#include "QF/qargs.h" +#include "QF/quakefs.h" +#include "QF/sys.h" +#include "QF/va.h" +#include "QF/vid.h" +#include "QF/Vulkan/qf_vid.h" +#include "QF/Vulkan/device.h" +#include "QF/Vulkan/image.h" +#include "QF/Vulkan/instance.h" +#include "QF/Vulkan/renderpass.h" + +#include "compat.h" +#include "d_iface.h" +#include "r_internal.h" +#include "vid_vulkan.h" + +#include "util.h" + +qfv_renderpass_t * +QFV_CreateRenderPass (qfv_device_t *device, + qfv_attachmentdescription_t *attachments, + qfv_subpassparametersset_t *subpassparams, + qfv_subpassdependency_t *dependencies) +{ + VkDevice dev = device->dev; + qfv_devfuncs_t *dfunc = device->funcs; + + VkSubpassDescription *subpasses = alloca (subpassparams->numSubpasses + * sizeof (*subpasses)); + + for (uint32_t i = 0; i < subpassparams->numSubpasses; i++) { + qfv_subpassparameters_t *params = &subpassparams->subpasses[i]; + subpasses[i].flags = 0; + subpasses[i].pipelineBindPoint = params->pipelineBindPoint; + subpasses[i].inputAttachmentCount = params->inputAttachments->numReferences; + subpasses[i].pInputAttachments = params->inputAttachments->references; + subpasses[i].colorAttachmentCount = params->colorAttachments->numReferences; + subpasses[i].pColorAttachments = params->colorAttachments->references; + if (params->resolveAttachments) { + subpasses[i].pResolveAttachments = params->resolveAttachments->references; + } + subpasses[i].pDepthStencilAttachment = params->depthStencilAttachment; + subpasses[i].preserveAttachmentCount = params->numPreserve; + subpasses[i].pPreserveAttachments = params->preserveAttachments; + } + + VkRenderPassCreateInfo createInfo = { + VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, 0, 0, + attachments->numAttachments, attachments->attachments, + subpassparams->numSubpasses, subpasses, + dependencies->numDependencies, dependencies->dependencies, + }; + + qfv_renderpass_t *renderpass = malloc (sizeof (*renderpass)); + renderpass->device = device; + dfunc->vkCreateRenderPass (dev, &createInfo, 0, &renderpass->renderPass); + return renderpass; +} + +qfv_framebuffer_t * +QFV_CreateFramebuffer (qfv_renderpass_t *renderPass, + uint32_t numAttachments, qfv_imageview_t **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, + }; + + qfv_framebuffer_t *framebuffer = malloc (sizeof (*framebuffer)); + framebuffer->device = device; + dfunc->vkCreateFramebuffer (dev, &createInfo, 0, &framebuffer->framebuffer); + return framebuffer; +} + +void +QFV_DestroyFramebuffer (qfv_framebuffer_t *framebuffer) +{ + qfv_device_t *device = framebuffer->device; + VkDevice dev = device->dev; + qfv_devfuncs_t *dfunc = device->funcs; + + dfunc->vkDestroyFramebuffer (dev, framebuffer->framebuffer, 0); + free (framebuffer); +} + +void +QFV_DestroyRenderPass (qfv_renderpass_t *renderPass) +{ + qfv_device_t *device = renderPass->device; + VkDevice dev = device->dev; + qfv_devfuncs_t *dfunc = device->funcs; + + dfunc->vkDestroyRenderPass (dev, renderPass->renderPass, 0); + free (renderPass); +}