diff --git a/include/QF/Vulkan/render.h b/include/QF/Vulkan/render.h index 6b057d210..efb468811 100644 --- a/include/QF/Vulkan/render.h +++ b/include/QF/Vulkan/render.h @@ -32,6 +32,15 @@ typedef struct qfv_descriptorsetinfo_s { VkDescriptorSetLayout setLayout; } qfv_descriptorsetinfo_t; +typedef struct qfv_layoutinfo_s { + const char *name; + uint32_t num_sets; + qfv_reference_t *sets; + uint32_t num_ranges; + VkPushConstantRange *ranges; + VkPipelineLayout layout; +} qfv_layoutinfo_t; + typedef struct qfv_imageinfo_s { const char *name; VkImageCreateFlags flags; @@ -158,6 +167,7 @@ typedef struct qfv_renderpassinfo_s { typedef struct qfv_renderinfo_s { struct memsuper_s *memsuper; + struct plitem_s *plitem; uint32_t num_images; qfv_imageinfo_t *images; uint32_t num_views; diff --git a/libs/video/renderer/vulkan/render.c b/libs/video/renderer/vulkan/render.c index 2cf423430..dd3a3f505 100644 --- a/libs/video/renderer/vulkan/render.c +++ b/libs/video/renderer/vulkan/render.c @@ -154,11 +154,15 @@ QFV_LoadRenderInfo (vulkan_ctx_t *ctx) __auto_type output = get_output (ctx, item); Vulkan_Script_SetOutput (ctx, &output); rctx->renderinfo = QFV_ParseRenderInfo (ctx, item, rctx); + if (rctx->renderinfo) { + rctx->renderinfo->plitem = item; + } } typedef struct { uint32_t num_images; uint32_t num_views; + uint32_t num_layouts; uint32_t num_renderpasses; uint32_t num_attachments; @@ -298,6 +302,34 @@ create_resources (vulkan_ctx_t *ctx, objcount_t *counts) QFV_CreateResource (ctx->device, render->resources); } +typedef struct { + VkRenderPassCreateInfo *rpCreate; + VkAttachmentDescription *attach; + VkClearValue *clear; + VkSubpassDescription *subpass; + VkSubpassDependency *depend; + VkAttachmentReference *attachref; + VkPipelineColorBlendAttachmentState *cbAttach; + uint32_t *preserve; + VkGraphicsPipelineCreateInfo *plCreate; + VkPipelineColorBlendStateCreateInfo *cbState; + qfv_layoutinfo_t *layouts; +} objptr_t; + +typedef struct { + objcount_t inds; + objptr_t ptr; + vulkan_ctx_t *ctx; + qfv_renderinfo_t *rinfo; + exprtab_t *symtab; + qfv_renderpassinfo_t *rpi; + VkRenderPassCreateInfo *rpc; + qfv_subpassinfo_t *spi; + VkSubpassDescription *spc; + qfv_pipelineinfo_t *pli; + VkGraphicsPipelineCreateInfo *plc; +} objstate_t; + static uint32_t __attribute__((pure)) find_subpass (qfv_dependencyinfo_t *d, uint32_t spind, qfv_subpassinfo_t *subpasses) @@ -314,8 +346,66 @@ find_subpass (qfv_dependencyinfo_t *d, uint32_t spind, Sys_Error ("invalid dependency: [%d] %s", spind, d->name); } +static VkDescriptorSetLayout +find_descriptorSet (const qfv_reference_t *ref, objstate_t *s) +{ + for (uint32_t i = 0; i < s->rinfo->num_descriptorsets; i++) { + __auto_type ds = &s->rinfo->descriptorsets[i]; + if (strcmp (ds->name, ref->name) == 0) { + if (!ds->setLayout) { + VkDescriptorSetLayoutCreateInfo cInfo = { + .sType=VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .flags = ds->flags, + .bindingCount = ds->num_bindings, + .pBindings = ds->bindings, + }; + qfv_device_t *device = s->ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + dfunc->vkCreateDescriptorSetLayout (device->dev, &cInfo, 0, + &ds->setLayout); + } + return ds->setLayout; + } + } + Sys_Error ("%s.%s:%d: invalid descriptor set layout: %s", + s->rpi->name, s->spi->name, ref->line, ref->name); +} + +static VkPipelineLayout +find_layout (const qfv_reference_t *ref, objstate_t *s) +{ + for (uint32_t i = 0; i < s->inds.num_layouts; i++) { + if (strcmp (s->ptr.layouts[i].name, ref->name) == 0) { + return s->ptr.layouts[i].layout; + } + } + if (!QFV_ParseLayoutInfo (s->ctx, s->rinfo->memsuper, s->symtab, ref->name, + &s->ptr.layouts[s->inds.num_layouts])) { + Sys_Error ("%s.%s:%d: invalid layout: %s", + s->rpi->name, s->spi->name, ref->line, ref->name); + } + __auto_type li = &s->ptr.layouts[s->inds.num_layouts++]; + li->name = ref->name; + VkDescriptorSetLayout sets[li->num_sets]; + for (uint32_t i = 0; i < li->num_sets; i++) { + sets[i] = find_descriptorSet (&li->sets[i], s); + } + VkPipelineLayoutCreateInfo cInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .setLayoutCount = li->num_sets, + .pSetLayouts = sets, + .pushConstantRangeCount = li->num_ranges, + .pPushConstantRanges = li->ranges, + }; + qfv_device_t *device = s->ctx->device; + qfv_devfuncs_t *dfunc = device->funcs; + dfunc->vkCreatePipelineLayout (device->dev, &cInfo, 0, &li->layout); + return li->layout; +} + static void -init_plCreate (VkGraphicsPipelineCreateInfo *plc, const qfv_pipelineinfo_t *pli) +init_plCreate (VkGraphicsPipelineCreateInfo *plc, const qfv_pipelineinfo_t *pli, + objstate_t *s) { if (pli->num_graph_stages) { plc->stageCount = pli->num_graph_stages; @@ -353,34 +443,10 @@ init_plCreate (VkGraphicsPipelineCreateInfo *plc, const qfv_pipelineinfo_t *pli) plc->pDynamicState = pli->dynamic; } if (pli->layout.name) { - //plc->layout = find_layout (&pli->layoyout); + plc->layout = find_layout (&pli->layout, s); } } -typedef struct { - VkRenderPassCreateInfo *rpCreate; - VkAttachmentDescription *attach; - VkClearValue *clear; - VkSubpassDescription *subpass; - VkSubpassDependency *depend; - VkAttachmentReference *attachref; - VkPipelineColorBlendAttachmentState *cbAttach; - uint32_t *preserve; - VkGraphicsPipelineCreateInfo *plCreate; - VkPipelineColorBlendStateCreateInfo *cbState; -} objptr_t; - -typedef struct { - objcount_t inds; - objptr_t ptr; - qfv_renderpassinfo_t *rpi; - VkRenderPassCreateInfo *rpc; - qfv_subpassinfo_t *spi; - VkSubpassDescription *spc; - qfv_pipelineinfo_t *pli; - VkGraphicsPipelineCreateInfo *plc; -} objstate_t; - static uint32_t __attribute__((pure)) find_attachment (qfv_reference_t *ref, objstate_t *s) { @@ -448,9 +514,9 @@ init_spCreate (uint32_t index, qfv_subpassinfo_t *sub, objstate_t *s) .subpass = index, }; if (s->spi->base_pipeline) { - init_plCreate (&s->plc[i], s->spi->base_pipeline); + init_plCreate (&s->plc[i], s->spi->base_pipeline, s); } - init_plCreate (&s->plc[i], &s->spi->pipelines[i]); + init_plCreate (&s->plc[i], &s->spi->pipelines[i], s); s->inds.num_pipelines++; } @@ -556,12 +622,10 @@ create_renderpasses (vulkan_ctx_t *ctx, objcount_t *counts) __auto_type rinfo = rctx->renderinfo; size_t size = 0; -#if 0 size += counts->num_renderpasses * sizeof (VkRenderPass); size += counts->num_pipelines * sizeof (VkPipeline); __auto_type rp = (VkRenderPass *) malloc (size); __auto_type pl = (VkPipeline *) &rp[counts->num_renderpasses]; -#endif size = 0; size += counts->num_renderpasses * sizeof (VkRenderPassCreateInfo); @@ -574,7 +638,11 @@ create_renderpasses (vulkan_ctx_t *ctx, objcount_t *counts) size += counts->num_preserve * sizeof (uint32_t); size += counts->num_pipelines * sizeof (VkGraphicsPipelineCreateInfo); size += counts->num_pipelines *sizeof (VkPipelineColorBlendStateCreateInfo); + size += counts->num_pipelines *sizeof (qfv_layoutinfo_t); + exprctx_t ectx = { + .hashctx = &ctx->script_context->hashctx, + }; objstate_t s = { .ptr = { .rpCreate = alloca (size), @@ -587,7 +655,11 @@ create_renderpasses (vulkan_ctx_t *ctx, objcount_t *counts) .preserve = (void *) &s.ptr.cbAttach [counts->num_colorblend], .plCreate = (void *) &s.ptr.preserve [counts->num_preserve], .cbState = (void *) &s.ptr.plCreate [counts->num_pipelines], + .layouts = (void *) &s.ptr.cbState [counts->num_pipelines], }, + .ctx = ctx, + .rinfo = rinfo, + .symtab = QFV_CreateSymtab (rinfo->plitem, "properties", 0, 0, &ectx), }; for (uint32_t i = 0; i < rinfo->num_renderpasses; i++) { init_rpCreate (i, rinfo, &s); @@ -604,7 +676,6 @@ create_renderpasses (vulkan_ctx_t *ctx, objcount_t *counts) Sys_Error ("create_renderpasses: something was missed"); } -#if 0 qfv_device_t *device = ctx->device; qfv_devfuncs_t *dfunc = device->funcs; uint32_t plInd = 0; @@ -622,7 +693,6 @@ create_renderpasses (vulkan_ctx_t *ctx, objcount_t *counts) } dfunc->vkCreateGraphicsPipelines (device->dev, 0, 1, s.ptr.plCreate, 0, pl); -#endif } static void diff --git a/libs/video/renderer/vulkan/rp_main_def.plist b/libs/video/renderer/vulkan/rp_main_def.plist index 4205b7c8a..59e5d71d5 100644 --- a/libs/video/renderer/vulkan/rp_main_def.plist +++ b/libs/video/renderer/vulkan/rp_main_def.plist @@ -240,7 +240,7 @@ properties = { primitiveRestartEnable = true; }; layout = { - setLayouts = (matrix_set, entity_set, oit_set, texture_set, texture_set); + descriptorSets = (matrix_set, entity_set, oit_set, texture_set, texture_set); pushConstantRanges = ( { stageFlags = fragment; @@ -287,7 +287,7 @@ properties = { primitiveRestartEnable = false; }; layout = { - setLayouts = (matrix_set, texture_set, texture_set); + descriptorSets = (matrix_set, texture_set, texture_set); pushConstantRanges = ( { stageFlags = vertex; @@ -358,7 +358,7 @@ properties = { primitiveRestartEnable = false; }; layout = { - setLayouts = (matrix_set, texture_set, bone_set); + descriptorSets = (matrix_set, texture_set, bone_set); pushConstantRanges = ( { stageFlags = vertex; @@ -406,7 +406,7 @@ properties = { primitiveRestartEnable = false; }; layout = { - setLayouts = (matrix_set, sprite_set); + descriptorSets = (matrix_set, sprite_set); pushConstantRanges = ( { stageFlags = vertex; @@ -457,7 +457,7 @@ properties = { primitiveRestartEnable = false; }; layout = { - setLayouts = (matrix_set, texture_set, oit_set); + descriptorSets = (matrix_set, texture_set, oit_set); pushConstantRanges = ( { stageFlags = vertex; @@ -484,6 +484,10 @@ properties = { module = $builtin/lighting.frag; }; }; + layout = { + descriptorSets = (lighting_attach, lighting_lights, + lighting_shadow); + }; }; compose = { shader = { @@ -493,6 +497,9 @@ properties = { module = $builtin/compose.frag; }; }; + layout = { + descriptorSets = (compose_attach, oit_set); + }; } }; descriptorSetLayouts = { @@ -837,7 +844,7 @@ renderpasses = { ); attributes = ( "$brush.vertexInput.attributes[0]", - "$brush.vertexInput.attributes[1]", + "$brush.vertexInput.attributes[2]", ); }; inputAssembly = $brush.inputAssembly; @@ -1103,7 +1110,7 @@ renderpasses = { $fstriangle.shader.vertex, $lighting.shader.fragment, ); - layout = lighting.layout; + layout = $lighting.layout; }; }; }; @@ -1134,7 +1141,7 @@ renderpasses = { $fstriangle.shader.vertex, $compose.shader.fragment, ); - layout = compose.layout; + layout = $compose.layout; }; }; };