From 82eabb5ca2acf4053fa3ed08ff2a2fbc84c2a9f3 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 23 Feb 2021 14:37:48 +0900 Subject: [PATCH] [vulkan] Parse clear values And get the render pass working in general. Note that this is only the render pass and frame buffers: actual commands still have problems. --- include/vid_vulkan.h | 5 ++ libs/video/renderer/vid_render_vulkan.c | 19 ++--- libs/video/renderer/vulkan/deferred.plist | 16 +++- libs/video/renderer/vulkan/vkparse.c | 85 +++++++++++++++++++ libs/video/renderer/vulkan/vkparse.h | 3 + libs/video/renderer/vulkan/vkparse.plist | 13 ++- libs/video/renderer/vulkan/vulkan_draw.c | 1 + .../video/renderer/vulkan/vulkan_vid_common.c | 13 +++ 8 files changed, 140 insertions(+), 15 deletions(-) diff --git a/include/vid_vulkan.h b/include/vid_vulkan.h index dcf4f624b..a672f02d1 100644 --- a/include/vid_vulkan.h +++ b/include/vid_vulkan.h @@ -32,6 +32,9 @@ typedef struct vulkan_matrices_s { typedef struct vulkan_frameset_s DARRAY_TYPE (vulkan_frame_t) vulkan_frameset_t; +typedef struct clearvalueset_s + DARRAY_TYPE (VkClearValue) clearvalueset_t; + typedef struct vulkan_ctx_s { void (*load_vulkan) (struct vulkan_ctx_s *ctx); void (*unload_vulkan) (struct vulkan_ctx_s *ctx); @@ -56,6 +59,7 @@ typedef struct vulkan_ctx_s { struct plitem_s *renderpassDef; VkRenderPass renderpass; + clearvalueset_t *clearValues; struct qfv_imageset_s *attachment_images; struct qfv_imageviewset_s *attachment_views; VkDeviceMemory attachmentMemory; @@ -70,6 +74,7 @@ typedef struct vulkan_ctx_s { struct hashtab_s *samplers; struct hashtab_s *images; struct hashtab_s *imageViews; + struct hashtab_s *renderpasses; struct aliasctx_s *alias_context; struct bspctx_s *bsp_context; diff --git a/libs/video/renderer/vid_render_vulkan.c b/libs/video/renderer/vid_render_vulkan.c index b8f9dc718..84f7b41f9 100644 --- a/libs/video/renderer/vid_render_vulkan.c +++ b/libs/video/renderer/vid_render_vulkan.c @@ -125,9 +125,6 @@ vulkan_R_RenderFrame (SCR_Func scr_3dfunc, SCR_Func *scr_funcs) __auto_type frame = &vulkan_ctx->frames.a[vulkan_ctx->curFrame]; dfunc->vkWaitForFences (dev, 1, &frame->fence, VK_TRUE, 2000000000); - if (frame->framebuffer) { - dfunc->vkDestroyFramebuffer (dev, frame->framebuffer, 0); - } QFV_AcquireNextImage (vulkan_ctx->swapchain, frame->imageAvailableSemaphore, 0, &imageIndex); @@ -145,16 +142,11 @@ vulkan_R_RenderFrame (SCR_Func scr_3dfunc, SCR_Func *scr_funcs) VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; - VkClearValue clearValues[3] = { - { { {0.0, 0.0, 0.0, 1.0} } }, - { { {1.0, 0.0} } }, - { { {0.0, 0.0, 0.0, 1.0} } }, - }; VkRenderPassBeginInfo renderPassInfo = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 0, vulkan_ctx->renderpass, 0, { {0, 0}, vulkan_ctx->swapchain->extent }, - 3, clearValues + vulkan_ctx->clearValues->size, vulkan_ctx->clearValues->a }; dfunc->vkBeginCommandBuffer (frame->cmdBuffer, &beginInfo); @@ -163,12 +155,15 @@ vulkan_R_RenderFrame (SCR_Func scr_3dfunc, SCR_Func *scr_funcs) subpassContents); for (int i = 0; i < frame->cmdSetCount; i++) { - dfunc->vkCmdExecuteCommands (frame->cmdBuffer, frame->cmdSets[i].size, - frame->cmdSets[i].a); + if (frame->cmdSets[i].size) { + dfunc->vkCmdExecuteCommands (frame->cmdBuffer, + frame->cmdSets[i].size, + frame->cmdSets[i].a); + } // reset for next time around frame->cmdSets[i].size = 0; - if (i < frame->cmdSetCount) { + if (i < frame->cmdSetCount - 1) { dfunc->vkCmdNextSubpass (frame->cmdBuffer, subpassContents); } } diff --git a/libs/video/renderer/vulkan/deferred.plist b/libs/video/renderer/vulkan/deferred.plist index e7e7e1f12..c03c30625 100644 --- a/libs/video/renderer/vulkan/deferred.plist +++ b/libs/video/renderer/vulkan/deferred.plist @@ -13,6 +13,7 @@ arrayLayers = 1; tiling = optimal; usage = depth_stencil_attachment|input_attachment; + initialLayout = undefined; }; color = { imageType = VK_IMAGE_TYPE_2D; @@ -27,6 +28,7 @@ arrayLayers = 1; tiling = optimal; usage = color_attachment|input_attachment; + initialLayout = undefined; }; normals = { imageType = VK_IMAGE_TYPE_2D; @@ -41,6 +43,7 @@ arrayLayers = 1; tiling = optimal; usage = color_attachment|input_attachment; + initialLayout = undefined; }; opaque = { imageType = VK_IMAGE_TYPE_2D; @@ -55,6 +58,7 @@ arrayLayers = 1; tiling = optimal; usage = color_attachment|input_attachment; + initialLayout = undefined; }; translucent = { imageType = VK_IMAGE_TYPE_2D; @@ -69,6 +73,7 @@ arrayLayers = 1; tiling = optimal; usage = color_attachment|input_attachment; + initialLayout = undefined; }; }; imageViews = { @@ -154,12 +159,21 @@ }; }; framebuffer = { - renderPass = renderpass; + renderPass = $properties.renderpass; attachments = (depth, color, normals, opaque, translucent, "$swapchain.views[$swapImageIndex]"); width = $swapchain.extent.width; height = $swapchain.extent.height; + layers = 1; }; + clearValues = ( + { depthStencil = { depth = 1; stencil = 0; }; }, + { color = "[0, 0, 0, 1]"; }, // color + { color = "[0, 0, 0, 1]"; }, // normals + { color = "[0, 0, 0, 1]"; }, // opaque + { color = "[0, 0, 0, 0]"; }, // translucent + { color = "[0, 0, 0, 1]"; }, // swapchain + ); renderpass = { attachments = ( { diff --git a/libs/video/renderer/vulkan/vkparse.c b/libs/video/renderer/vulkan/vkparse.c index ee8efb8a4..72ec5abbb 100644 --- a/libs/video/renderer/vulkan/vkparse.c +++ b/libs/video/renderer/vulkan/vkparse.c @@ -413,6 +413,42 @@ QFV_AddHandle (hashtab_t *tab, const char *name, uint64_t handle) Hash_Add (tab, hr); } +static int +parse_VkRenderPass (const plitem_t *item, void **data, + plitem_t *messages, parsectx_t *context) +{ + __auto_type handle = (VkRenderPass *) data[0]; + int ret = 1; + parsectx_t *pctx = context; + exprctx_t ectx = *pctx->ectx; + vulkan_ctx_t *ctx = pctx->vctx; + + const char *name = PL_String (item); + Sys_Printf ("parse_VkRenderPass: %s\n", name); + if (name[0] != '$') { + name = va (ctx->va_ctx, "$"QFV_PROPERTIES".%s", name); + } + + *handle = (VkRenderPass) QFV_GetHandle (ctx->renderpasses, name); + if (*handle) { + return 1; + } + + plitem_t *setItem = 0; + exprval_t result = { &cexpr_plitem, &setItem }; + ectx.symtab = 0; + ectx.result = &result; + ret = !cexpr_eval_string (name, &ectx); + if (ret) { + VkRenderPass setLayout; + setLayout = QFV_ParseRenderPass (ctx, setItem, pctx->properties); + *handle = (VkRenderPass) setLayout; + + QFV_AddHandle (ctx->setLayouts, name, (uint64_t) setLayout); + } + return ret; +} + static int parse_VkShaderModule (const plitem_t *item, void **data, plitem_t *messages, parsectx_t *context) @@ -711,6 +747,21 @@ imageView_free (void *hr, void *_ctx) handleref_free (handleref, ctx); } +static void +renderpass_free (void *hr, void *_ctx) +{ + __auto_type handleref = (handleref_t *) hr; + __auto_type renderpass = (VkRenderPass) handleref->handle; + __auto_type ctx = (vulkan_ctx_t *) _ctx; + qfv_device_t *device = ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + + if (renderpass) { + dfunc->vkDestroyRenderPass (device->dev, renderpass, 0); + }; + handleref_free (handleref, ctx); +} + static hashtab_t *enum_symtab; static int @@ -891,6 +942,7 @@ QFV_InitParse (vulkan_ctx_t *ctx) ctx->samplers = handlref_symtab (sampler_free, ctx); ctx->images = handlref_symtab (image_free, ctx); ctx->imageViews = handlref_symtab (imageView_free, ctx); + ctx->renderpasses = handlref_symtab (renderpass_free, ctx); } } @@ -1262,6 +1314,39 @@ QFV_ParseFramebuffer (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties) VkFramebuffer framebuffer; dfunc->vkCreateFramebuffer (device->dev, &cInfo, 0, &framebuffer); + printf ("framebuffer, renderPass: %p, %p\n", framebuffer, cInfo.renderPass); return framebuffer; } + +static int +parse_clearvalueset (const plfield_t *field, const plitem_t *item, void *data, + plitem_t *messages, void *context) +{ + parsectx_t *parsectx = context; + vulkan_ctx_t *ctx = parsectx->vctx; + + plelement_t element = { + QFDictionary, + sizeof (VkClearValue), + array_alloc, + parse_VkClearValue, + 0, + }; + plfield_t f = { 0, 0, 0, 0, &element }; + + if (!PL_ParseArray (&f, item, &ctx->clearValues, messages, context)) { + return 0; + } + return 1; +} + +int +QFV_ParseClearValues (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties) +{ + if (!parse_object (ctx, plist, parse_clearvalueset, &ctx->clearValues, + properties)) { + return 0; + } + return 1; +} diff --git a/libs/video/renderer/vulkan/vkparse.h b/libs/video/renderer/vulkan/vkparse.h index f8aea8a7f..2550e1b17 100644 --- a/libs/video/renderer/vulkan/vkparse.h +++ b/libs/video/renderer/vulkan/vkparse.h @@ -58,5 +58,8 @@ struct qfv_imageviewset_s *QFV_ParseImageViewSet (vulkan_ctx_t *ctx, plitem_t *properties); VkFramebuffer QFV_ParseFramebuffer (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties); +int QFV_ParseClearValues (vulkan_ctx_t *ctx, plitem_t *plist, + plitem_t *properties); + #endif//__vkparse_h diff --git a/libs/video/renderer/vulkan/vkparse.plist b/libs/video/renderer/vulkan/vkparse.plist index 9eb5e7e04..22d9173dc 100644 --- a/libs/video/renderer/vulkan/vkparse.plist +++ b/libs/video/renderer/vulkan/vkparse.plist @@ -23,6 +23,7 @@ VkImageCreateInfo, VkImageViewCreateInfo, VkFramebufferCreateInfo, + VkClearValue, ); parse = { VkSubpassDescription = { @@ -317,7 +318,7 @@ VkFramebufferCreateInfo = { //flags = auto; reserved for future use (Bits enum does not exist) renderPass = { - type = (custom, QFString, parse_VkShaderModule); + type = (custom, QFString, parse_VkRenderPass); fields = (renderPass); }; attachments = { @@ -328,6 +329,14 @@ width = auto; height = auto; layers = auto; - } + }; + VkClearColorValue = skip; + VkClearValue = { + color = { + type = (custom, QFString, parse_RGBA); + fields = (color); + }; + depthStencil = auto; + }; } } diff --git a/libs/video/renderer/vulkan/vulkan_draw.c b/libs/video/renderer/vulkan/vulkan_draw.c index 4b962edd6..2ab8bd05a 100644 --- a/libs/video/renderer/vulkan/vulkan_draw.c +++ b/libs/video/renderer/vulkan/vulkan_draw.c @@ -718,6 +718,7 @@ Vulkan_FlushText (vulkan_ctx_t *ctx) VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, &inherit, }; + printf ("Vulkan_FlushText: %p %p\n", inherit.renderPass, inherit.framebuffer); dfunc->vkBeginCommandBuffer (cmd, &beginInfo); dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, diff --git a/libs/video/renderer/vulkan/vulkan_vid_common.c b/libs/video/renderer/vulkan/vulkan_vid_common.c index a6f444798..903dc8d19 100644 --- a/libs/video/renderer/vulkan/vulkan_vid_common.c +++ b/libs/video/renderer/vulkan/vulkan_vid_common.c @@ -308,12 +308,25 @@ Vulkan_CreateRenderPass (vulkan_ctx_t *ctx) { const char *name = "renderpass";//FIXME + hashtab_t *tab = ctx->renderpasses; + const char *path; + path = va (ctx->va_ctx, "$"QFV_PROPERTIES".%s", name); + __auto_type renderpass = (VkRenderPass) QFV_GetHandle (tab, path); + if (renderpass) { + ctx->renderpass = renderpass; + return; + } + plitem_t *item = qfv_load_renderpass (ctx, name); ctx->renderpass = QFV_ParseRenderPass (ctx, item, ctx->renderpassDef); + QFV_AddHandle (tab, path, (uint64_t) ctx->renderpass); QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_RENDER_PASS, ctx->renderpass, va (ctx->va_ctx, "renderpass:%s", name)); + item = qfv_load_renderpass (ctx, "clearValues"); + QFV_ParseClearValues (ctx, item, ctx->renderpassDef); + printf ("renderpass: %p\n", ctx->renderpass); } void