[vulkan] Create render passes and pipelines

There are many issues (in particular, shutdown doesn't clean up
properly), but creation passes validation.
This commit is contained in:
Bill Currie 2023-02-27 03:00:14 +09:00
parent 918237507e
commit 0dccce6c51
3 changed files with 127 additions and 40 deletions

View file

@ -32,6 +32,15 @@ typedef struct qfv_descriptorsetinfo_s {
VkDescriptorSetLayout setLayout; VkDescriptorSetLayout setLayout;
} qfv_descriptorsetinfo_t; } 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 { typedef struct qfv_imageinfo_s {
const char *name; const char *name;
VkImageCreateFlags flags; VkImageCreateFlags flags;
@ -158,6 +167,7 @@ typedef struct qfv_renderpassinfo_s {
typedef struct qfv_renderinfo_s { typedef struct qfv_renderinfo_s {
struct memsuper_s *memsuper; struct memsuper_s *memsuper;
struct plitem_s *plitem;
uint32_t num_images; uint32_t num_images;
qfv_imageinfo_t *images; qfv_imageinfo_t *images;
uint32_t num_views; uint32_t num_views;

View file

@ -154,11 +154,15 @@ QFV_LoadRenderInfo (vulkan_ctx_t *ctx)
__auto_type output = get_output (ctx, item); __auto_type output = get_output (ctx, item);
Vulkan_Script_SetOutput (ctx, &output); Vulkan_Script_SetOutput (ctx, &output);
rctx->renderinfo = QFV_ParseRenderInfo (ctx, item, rctx); rctx->renderinfo = QFV_ParseRenderInfo (ctx, item, rctx);
if (rctx->renderinfo) {
rctx->renderinfo->plitem = item;
}
} }
typedef struct { typedef struct {
uint32_t num_images; uint32_t num_images;
uint32_t num_views; uint32_t num_views;
uint32_t num_layouts;
uint32_t num_renderpasses; uint32_t num_renderpasses;
uint32_t num_attachments; uint32_t num_attachments;
@ -298,6 +302,34 @@ create_resources (vulkan_ctx_t *ctx, objcount_t *counts)
QFV_CreateResource (ctx->device, render->resources); 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)) static uint32_t __attribute__((pure))
find_subpass (qfv_dependencyinfo_t *d, uint32_t spind, find_subpass (qfv_dependencyinfo_t *d, uint32_t spind,
qfv_subpassinfo_t *subpasses) 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); 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 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) { if (pli->num_graph_stages) {
plc->stageCount = 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; plc->pDynamicState = pli->dynamic;
} }
if (pli->layout.name) { 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)) static uint32_t __attribute__((pure))
find_attachment (qfv_reference_t *ref, objstate_t *s) 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, .subpass = index,
}; };
if (s->spi->base_pipeline) { 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++; s->inds.num_pipelines++;
} }
@ -556,12 +622,10 @@ create_renderpasses (vulkan_ctx_t *ctx, objcount_t *counts)
__auto_type rinfo = rctx->renderinfo; __auto_type rinfo = rctx->renderinfo;
size_t size = 0; size_t size = 0;
#if 0
size += counts->num_renderpasses * sizeof (VkRenderPass); size += counts->num_renderpasses * sizeof (VkRenderPass);
size += counts->num_pipelines * sizeof (VkPipeline); size += counts->num_pipelines * sizeof (VkPipeline);
__auto_type rp = (VkRenderPass *) malloc (size); __auto_type rp = (VkRenderPass *) malloc (size);
__auto_type pl = (VkPipeline *) &rp[counts->num_renderpasses]; __auto_type pl = (VkPipeline *) &rp[counts->num_renderpasses];
#endif
size = 0; size = 0;
size += counts->num_renderpasses * sizeof (VkRenderPassCreateInfo); 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_preserve * sizeof (uint32_t);
size += counts->num_pipelines * sizeof (VkGraphicsPipelineCreateInfo); size += counts->num_pipelines * sizeof (VkGraphicsPipelineCreateInfo);
size += counts->num_pipelines *sizeof (VkPipelineColorBlendStateCreateInfo); 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 = { objstate_t s = {
.ptr = { .ptr = {
.rpCreate = alloca (size), .rpCreate = alloca (size),
@ -587,7 +655,11 @@ create_renderpasses (vulkan_ctx_t *ctx, objcount_t *counts)
.preserve = (void *) &s.ptr.cbAttach [counts->num_colorblend], .preserve = (void *) &s.ptr.cbAttach [counts->num_colorblend],
.plCreate = (void *) &s.ptr.preserve [counts->num_preserve], .plCreate = (void *) &s.ptr.preserve [counts->num_preserve],
.cbState = (void *) &s.ptr.plCreate [counts->num_pipelines], .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++) { for (uint32_t i = 0; i < rinfo->num_renderpasses; i++) {
init_rpCreate (i, rinfo, &s); 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"); Sys_Error ("create_renderpasses: something was missed");
} }
#if 0
qfv_device_t *device = ctx->device; qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs; qfv_devfuncs_t *dfunc = device->funcs;
uint32_t plInd = 0; uint32_t plInd = 0;
@ -622,7 +693,6 @@ create_renderpasses (vulkan_ctx_t *ctx, objcount_t *counts)
} }
dfunc->vkCreateGraphicsPipelines (device->dev, 0, 1, dfunc->vkCreateGraphicsPipelines (device->dev, 0, 1,
s.ptr.plCreate, 0, pl); s.ptr.plCreate, 0, pl);
#endif
} }
static void static void

View file

@ -240,7 +240,7 @@ properties = {
primitiveRestartEnable = true; primitiveRestartEnable = true;
}; };
layout = { layout = {
setLayouts = (matrix_set, entity_set, oit_set, texture_set, texture_set); descriptorSets = (matrix_set, entity_set, oit_set, texture_set, texture_set);
pushConstantRanges = ( pushConstantRanges = (
{ {
stageFlags = fragment; stageFlags = fragment;
@ -287,7 +287,7 @@ properties = {
primitiveRestartEnable = false; primitiveRestartEnable = false;
}; };
layout = { layout = {
setLayouts = (matrix_set, texture_set, texture_set); descriptorSets = (matrix_set, texture_set, texture_set);
pushConstantRanges = ( pushConstantRanges = (
{ {
stageFlags = vertex; stageFlags = vertex;
@ -358,7 +358,7 @@ properties = {
primitiveRestartEnable = false; primitiveRestartEnable = false;
}; };
layout = { layout = {
setLayouts = (matrix_set, texture_set, bone_set); descriptorSets = (matrix_set, texture_set, bone_set);
pushConstantRanges = ( pushConstantRanges = (
{ {
stageFlags = vertex; stageFlags = vertex;
@ -406,7 +406,7 @@ properties = {
primitiveRestartEnable = false; primitiveRestartEnable = false;
}; };
layout = { layout = {
setLayouts = (matrix_set, sprite_set); descriptorSets = (matrix_set, sprite_set);
pushConstantRanges = ( pushConstantRanges = (
{ {
stageFlags = vertex; stageFlags = vertex;
@ -457,7 +457,7 @@ properties = {
primitiveRestartEnable = false; primitiveRestartEnable = false;
}; };
layout = { layout = {
setLayouts = (matrix_set, texture_set, oit_set); descriptorSets = (matrix_set, texture_set, oit_set);
pushConstantRanges = ( pushConstantRanges = (
{ {
stageFlags = vertex; stageFlags = vertex;
@ -484,6 +484,10 @@ properties = {
module = $builtin/lighting.frag; module = $builtin/lighting.frag;
}; };
}; };
layout = {
descriptorSets = (lighting_attach, lighting_lights,
lighting_shadow);
};
}; };
compose = { compose = {
shader = { shader = {
@ -493,6 +497,9 @@ properties = {
module = $builtin/compose.frag; module = $builtin/compose.frag;
}; };
}; };
layout = {
descriptorSets = (compose_attach, oit_set);
};
} }
}; };
descriptorSetLayouts = { descriptorSetLayouts = {
@ -837,7 +844,7 @@ renderpasses = {
); );
attributes = ( attributes = (
"$brush.vertexInput.attributes[0]", "$brush.vertexInput.attributes[0]",
"$brush.vertexInput.attributes[1]", "$brush.vertexInput.attributes[2]",
); );
}; };
inputAssembly = $brush.inputAssembly; inputAssembly = $brush.inputAssembly;
@ -1103,7 +1110,7 @@ renderpasses = {
$fstriangle.shader.vertex, $fstriangle.shader.vertex,
$lighting.shader.fragment, $lighting.shader.fragment,
); );
layout = lighting.layout; layout = $lighting.layout;
}; };
}; };
}; };
@ -1134,7 +1141,7 @@ renderpasses = {
$fstriangle.shader.vertex, $fstriangle.shader.vertex,
$compose.shader.fragment, $compose.shader.fragment,
); );
layout = compose.layout; layout = $compose.layout;
}; };
}; };
}; };