mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 20:41:20 +00:00
[vulkan] Support creating render passes with no render pass
Sounds odd, but it's part of the problem with calling two different things with essentially the same name. The "high level" render pass in question may be a compute pass, or a complex series of (Vulkan) render passes and so won't create a Vulkan render pass for the "high level" render pass (I do need to come up with a better name for it).
This commit is contained in:
parent
3058a5103f
commit
71813af090
3 changed files with 49 additions and 22 deletions
|
@ -49,7 +49,7 @@ typedef struct qfv_renderpass_s {
|
|||
VkViewport viewport;
|
||||
VkRect2D scissor;
|
||||
int order;
|
||||
|
||||
int primary_commands;
|
||||
size_t subpassCount;
|
||||
qfv_subpassset_t *subpass_info;
|
||||
qfv_renderframeset_t frames;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/darray.h"
|
||||
|
@ -111,6 +112,7 @@ vulkan_R_Init (void)
|
|||
static void
|
||||
vulkan_R_ClearState (void)
|
||||
{
|
||||
QFV_DeviceWaitIdle (vulkan_ctx->device);
|
||||
r_refdef.worldmodel = 0;
|
||||
R_ClearEfrags ();
|
||||
R_ClearDlights ();
|
||||
|
@ -287,7 +289,9 @@ vulkan_render_view (void)
|
|||
for (size_t i = 0; i < vulkan_ctx->renderPasses.size; i++) {
|
||||
__auto_type rp = vulkan_ctx->renderPasses.a[i];
|
||||
__auto_type rpFrame = &rp->frames.a[vulkan_ctx->curFrame];
|
||||
frame->framebuffer = rp->framebuffers->a[imageIndex];
|
||||
if (rp->framebuffers) {
|
||||
frame->framebuffer = rp->framebuffers->a[imageIndex];
|
||||
}
|
||||
rp->draw (rpFrame);
|
||||
}
|
||||
}
|
||||
|
@ -339,13 +343,27 @@ vulkan_end_frame (void)
|
|||
.renderArea = { {0, 0}, vulkan_ctx->swapchain->extent },
|
||||
};
|
||||
|
||||
__auto_type cmdBufs = (qfv_cmdbufferset_t) DARRAY_STATIC_INIT (4);
|
||||
DARRAY_APPEND (&cmdBufs, frame->cmdBuffer);
|
||||
|
||||
dfunc->vkBeginCommandBuffer (frame->cmdBuffer, &beginInfo);
|
||||
for (size_t i = 0; i < vulkan_ctx->renderPasses.size; i++) {
|
||||
__auto_type rp = vulkan_ctx->renderPasses.a[i];
|
||||
__auto_type rpFrame = &rp->frames.a[vulkan_ctx->curFrame];
|
||||
|
||||
if (rp->primary_commands) {
|
||||
for (int j = 0; j < rpFrame->subpassCount; j++) {
|
||||
__auto_type cmdSet = &rpFrame->subpassCmdSets[j];
|
||||
size_t base = cmdBufs.size;
|
||||
DARRAY_RESIZE (&cmdBufs, base + cmdSet->size);
|
||||
memcpy (&cmdBufs.a[base], cmdSet->a,
|
||||
cmdSet->size * sizeof (VkCommandBuffer));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
QFV_CmdBeginLabel (device, frame->cmdBuffer, rp->name, rp->color);
|
||||
if (rpFrame->renderpass) {
|
||||
if (rpFrame->renderpass && rp->renderpass) {
|
||||
renderPassInfo.framebuffer = frame->framebuffer,
|
||||
renderPassInfo.renderPass = rp->renderpass;
|
||||
renderPassInfo.clearValueCount = rp->clearValues->size;
|
||||
|
@ -403,12 +421,14 @@ vulkan_end_frame (void)
|
|||
VkSubmitInfo submitInfo = {
|
||||
VK_STRUCTURE_TYPE_SUBMIT_INFO, 0,
|
||||
1, &frame->imageAvailableSemaphore, &waitStage,
|
||||
1, &frame->cmdBuffer,
|
||||
cmdBufs.size, cmdBufs.a,
|
||||
1, &frame->renderDoneSemaphore,
|
||||
};
|
||||
dfunc->vkResetFences (dev, 1, &frame->fence);
|
||||
dfunc->vkQueueSubmit (queue->queue, 1, &submitInfo, frame->fence);
|
||||
|
||||
DARRAY_CLEAR (&cmdBufs);
|
||||
|
||||
if (vulkan_ctx->capture_callback) {
|
||||
//FIXME look into "threading" this rather than waiting here
|
||||
dfunc->vkWaitForFences (device->dev, 1, &frame->fence, VK_TRUE,
|
||||
|
|
|
@ -51,9 +51,9 @@ get_rp_item (vulkan_ctx_t *ctx, qfv_renderpass_t *rp, const char *name)
|
|||
}
|
||||
|
||||
plitem_t *item = rp->renderpassDef;
|
||||
if (!item || !(item = PL_ObjectForKey (item, name))) {
|
||||
Sys_Printf ("error loading %s\n", name);
|
||||
} else {
|
||||
if (!item) {
|
||||
Sys_Printf ("error loading %s\n", rp->name);
|
||||
} else if ((item = PL_ObjectForKey (item, name))) {
|
||||
Sys_MaskPrintf (SYS_vulkan_parse, "Found %s def\n", name);
|
||||
}
|
||||
return item;
|
||||
|
@ -201,31 +201,38 @@ Vulkan_CreateRenderPass (vulkan_ctx_t *ctx, const char *name,
|
|||
rp->name = name;
|
||||
|
||||
plitem_t *rp_cfg = get_rp_item (ctx, rp, "renderpass");
|
||||
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) {
|
||||
rp->renderpass = renderpass;
|
||||
} else {
|
||||
ctx->output = *output;
|
||||
rp->renderpass = QFV_ParseRenderPass (ctx, rp_cfg, rp->renderpassDef);
|
||||
QFV_AddHandle (tab, path, (uint64_t) rp->renderpass);
|
||||
QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_RENDER_PASS,
|
||||
rp->renderpass, va (ctx->va_ctx, "renderpass:%s",
|
||||
name));
|
||||
if (rp_cfg) {
|
||||
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) {
|
||||
rp->renderpass = renderpass;
|
||||
} else {
|
||||
ctx->output = *output;
|
||||
rp->renderpass = QFV_ParseRenderPass (ctx, rp_cfg,
|
||||
rp->renderpassDef);
|
||||
QFV_AddHandle (tab, path, (uint64_t) rp->renderpass);
|
||||
QFV_duSetObjectName (ctx->device, VK_OBJECT_TYPE_RENDER_PASS,
|
||||
rp->renderpass, va (ctx->va_ctx,
|
||||
"renderpass:%s", name));
|
||||
}
|
||||
rp->subpassCount = PL_A_NumObjects (PL_ObjectForKey (rp_cfg,
|
||||
"subpasses"));
|
||||
}
|
||||
rp->subpassCount = PL_A_NumObjects (PL_ObjectForKey (rp_cfg, "subpasses"));
|
||||
plitem_t *rp_info = get_rp_item (ctx, rp, "info");
|
||||
if (rp_info) {
|
||||
plitem_t *subpass_info = PL_ObjectForKey (rp_info, "subpass_info");
|
||||
if (subpass_info) {
|
||||
rp->subpass_info = QFV_ParseSubpasses (ctx, subpass_info,
|
||||
rp->renderpassDef);
|
||||
if (rp->subpass_info->size > rp->subpassCount) {
|
||||
if (rp->subpass_info->size < rp->subpassCount) {
|
||||
Sys_Printf ("warning:%s:%d: insufficient entries in "
|
||||
"subpass_info\n", name, PL_Line (subpass_info));
|
||||
}
|
||||
if (!rp->subpassCount) {
|
||||
rp->subpassCount = rp->subpass_info->size;
|
||||
}
|
||||
}
|
||||
|
||||
plitem_t *color = PL_ObjectForKey (rp_info, "color");
|
||||
|
|
Loading…
Reference in a new issue