[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.
This commit is contained in:
Bill Currie 2021-02-23 14:37:48 +09:00
parent 0cd2ece38e
commit 82eabb5ca2
8 changed files with 140 additions and 15 deletions

View file

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

View file

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

View file

@ -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 = (
{

View file

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

View file

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

View file

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

View file

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

View file

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