[vulkan] Support multiple render passes

Multiple render passes are needed for supporting shadow mapping, and
this is a huge step towards breaking the Vulkan render free of Quake,
and hopefully will lead the way for breaking the GL renderers free as
well.
This commit is contained in:
Bill Currie 2021-12-02 21:58:29 +09:00
parent 84a24dbb34
commit 928408bad9
21 changed files with 393 additions and 263 deletions

View file

@ -92,8 +92,10 @@ typedef struct aliasctx_s {
} aliasctx_t;
struct vulkan_ctx_s;
struct qfv_renderframe_s;
struct entity_s;
struct mod_alias_ctx_s;
void *Vulkan_Mod_LoadSkin (struct mod_alias_ctx_s *alias_ctx, byte *skin,
int skinsize, int snum, int gnum, qboolean group,
maliasskindesc_t *skindesc,
@ -106,13 +108,13 @@ void Vulkan_Mod_MakeAliasModelDisplayLists (struct mod_alias_ctx_s *alias_ctx,
void *_m, int _s, int extra,
struct vulkan_ctx_s *ctx);
void Vulkan_AliasBegin (struct vulkan_ctx_s *ctx);
void Vulkan_DrawAlias (struct entity_s *ent, struct vulkan_ctx_s *ctx);
void Vulkan_AliasEnd (struct vulkan_ctx_s *ctx);
void Vulkan_AliasBegin (struct qfv_renderframe_s *rFrame);
void Vulkan_DrawAlias (struct entity_s *ent, struct qfv_renderframe_s *rFrame);
void Vulkan_AliasEnd (struct qfv_renderframe_s *rFrame);
void Vulkan_Alias_Init (struct vulkan_ctx_s *ctx);
void Vulkan_Alias_Shutdown (struct vulkan_ctx_s *ctx);
void Vulkan_AliasDepthRange (struct vulkan_ctx_s *ctx, float n, float f);
void Vulkan_AliasDepthRange (struct qfv_renderframe_s *rFrame, float n, float f);
#endif//__QF_Vulkan_qf_alias_h

View file

@ -176,9 +176,11 @@ typedef struct bspctx_s {
} bspctx_t;
struct vulkan_ctx_s;
struct qfv_renderframe_s;
void Vulkan_ClearElements (struct vulkan_ctx_s *ctx);
void Vulkan_DrawWorld (struct vulkan_ctx_s *ctx);
void Vulkan_DrawSky (struct vulkan_ctx_s *ctx);
void Vulkan_DrawWorld (struct qfv_renderframe_s *rFrame);
void Vulkan_DrawSky (struct qfv_renderframe_s *rFrame);
void Vulkan_DrawWaterSurfaces (struct qfv_renderframe_s *rFrame);
void Vulkan_LoadSkys (const char *sky, struct vulkan_ctx_s *ctx);
void Vulkan_RegisterTextures (model_t **models, int num_models,
struct vulkan_ctx_s *ctx);
@ -186,6 +188,5 @@ void Vulkan_BuildDisplayLists (model_t **models, int num_models,
struct vulkan_ctx_s *ctx);
void Vulkan_Bsp_Init (struct vulkan_ctx_s *ctx);
void Vulkan_Bsp_Shutdown (struct vulkan_ctx_s *ctx);
void Vulkan_DrawWaterSurfaces (struct vulkan_ctx_s *ctx);
#endif//__QF_Vulkan_qf_bsp_h

View file

@ -54,9 +54,10 @@ typedef struct composectx_s {
} composectx_t;
struct vulkan_ctx_s;
struct qfv_renderframe_s;
void Vulkan_Compose_Init (struct vulkan_ctx_s *ctx);
void Vulkan_Compose_Shutdown (struct vulkan_ctx_s *ctx);
void Vulkan_Compose_Draw (struct vulkan_ctx_s *ctx);
void Vulkan_Compose_Draw (struct qfv_renderframe_s *fFrame);
#endif//__QF_Vulkan_qf_compose_h

View file

@ -29,6 +29,8 @@
#define __QF_Vulkan_qf_draw_h
struct vulkan_ctx_s;
struct qfv_renderframe_s;
struct qpic_s;
void Vulkan_Draw_Init (struct vulkan_ctx_s *ctx);
void Vulkan_Draw_Shutdown (struct vulkan_ctx_s *ctx);
@ -52,16 +54,19 @@ void Vulkan_Draw_TextBox (int x, int y, int width, int lines, byte alpha,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_FadeScreen (struct vulkan_ctx_s *ctx);
void Vulkan_Draw_BlendScreen (quat_t color, struct vulkan_ctx_s *ctx);
qpic_t *Vulkan_Draw_CachePic (const char *path, qboolean alpha,
struct qpic_s *Vulkan_Draw_CachePic (const char *path, qboolean alpha,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_UncachePic (const char *path, struct vulkan_ctx_s *ctx);
qpic_t *Vulkan_Draw_MakePic (int width, int height, const byte *data,
struct qpic_s *Vulkan_Draw_MakePic (int width, int height, const byte *data,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_DestroyPic (qpic_t *pic, struct vulkan_ctx_s *ctx);
qpic_t *Vulkan_Draw_PicFromWad (const char *name, struct vulkan_ctx_s *ctx);
void Vulkan_Draw_Pic (int x, int y, qpic_t *pic, struct vulkan_ctx_s *ctx);
void Vulkan_Draw_Picf (float x, float y, qpic_t *pic, struct vulkan_ctx_s *ctx);
void Vulkan_Draw_SubPic(int x, int y, qpic_t *pic,
void Vulkan_Draw_DestroyPic (struct qpic_s *pic, struct vulkan_ctx_s *ctx);
struct qpic_s *Vulkan_Draw_PicFromWad (const char *name,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_Pic (int x, int y, struct qpic_s *pic,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_Picf (float x, float y, struct qpic_s *pic,
struct vulkan_ctx_s *ctx);
void Vulkan_Draw_SubPic(int x, int y, struct qpic_s *pic,
int srcx, int srcy, int width, int height,
struct vulkan_ctx_s *ctx);
@ -69,6 +74,6 @@ void Vulkan_Set2D (struct vulkan_ctx_s *ctx);
void Vulkan_Set2DScaled (struct vulkan_ctx_s *ctx);
void Vulkan_End2D (struct vulkan_ctx_s *ctx);
void Vulkan_DrawReset (struct vulkan_ctx_s *ctx);
void Vulkan_FlushText (struct vulkan_ctx_s *ctx);
void Vulkan_FlushText (struct qfv_renderframe_s *rFrame);
#endif//__QF_Vulkan_qf_draw_h

View file

@ -128,10 +128,11 @@ typedef struct lightingctx_s {
} lightingctx_t;
struct vulkan_ctx_s;
struct qfv_renderframe_s;;
void Vulkan_Lighting_Init (struct vulkan_ctx_s *ctx);
void Vulkan_Lighting_Shutdown (struct vulkan_ctx_s *ctx);
void Vulkan_Lighting_Draw (struct vulkan_ctx_s *ctx);
void Vulkan_Lighting_Draw (struct qfv_renderframe_s *fFrame);
void Vulkan_LoadLights (model_t *model, const char *entity_data,
struct vulkan_ctx_s *ctx);

View file

@ -29,9 +29,10 @@
#define __QF_Vulkan_qf_main_h
struct vulkan_ctx_s;
struct qfv_renderframe_s;
void Vulkan_NewMap (model_t *worldmodel, struct model_s **models,
int num_models, struct vulkan_ctx_s *ctx);
void Vulkan_RenderView (struct vulkan_ctx_s *ctx);
void Vulkan_RenderView (struct qfv_renderframe_s *rFrame);
#endif//__QF_Vulkan_qf_main_h

View file

@ -61,10 +61,8 @@ struct vulkan_ctx_s;
void Vulkan_DestroyFrames (struct vulkan_ctx_s *ctx);
void Vulkan_CreateFrames (struct vulkan_ctx_s *ctx);
void Vulkan_CreateCapture (struct vulkan_ctx_s *ctx);
void Vulkan_CreateFramebuffers (struct vulkan_ctx_s *ctx);
void Vulkan_DestroyFramebuffers (struct vulkan_ctx_s *ctx);
void Vulkan_CreateRenderPass (struct vulkan_ctx_s *ctx);
void Vulkan_DestroyRenderPass (struct vulkan_ctx_s *ctx);
void Vulkan_DestroyRenderPasses (struct vulkan_ctx_s *ctx);
void Vulkan_CreateMatrices (struct vulkan_ctx_s *ctx);
void Vulkan_DestroyMatrices (struct vulkan_ctx_s *ctx);
void Vulkan_CalcProjectionMatrices (struct vulkan_ctx_s *ctx);

View file

@ -47,4 +47,33 @@ QFV_CreateFramebuffer (struct qfv_device_s *device,
struct qfv_imageviewset_s *attachments,
VkExtent2D, uint32_t layers);
typedef struct qfv_renderframe_s {
struct vulkan_ctx_s *vulkan_ctx;
struct qfv_renderpass_s *renderpass;
VkSubpassContents subpassContents;
int subpassCount;
struct qfv_cmdbufferset_s *subpassCmdSets;
} qfv_renderframe_t;
typedef struct qfv_renderframeset_s
DARRAY_TYPE (qfv_renderframe_t) qfv_renderframeset_t;
typedef struct clearvalueset_s
DARRAY_TYPE (VkClearValue) clearvalueset_t;
typedef struct qfv_renderpass_s {
struct plitem_s *renderpassDef;
VkRenderPass renderpass;
clearvalueset_t *clearValues;
struct qfv_imageset_s *attachment_images;
struct qfv_imageviewset_s *attachment_views;
VkDeviceMemory attachmentMemory;
qfv_framebufferset_t *framebuffers;
qfv_renderframeset_t frames;
void (*draw) (qfv_renderframe_t *rFrame);
} qfv_renderpass_t;
#endif//__QF_Vulkan_renderpass_h

View file

@ -15,9 +15,6 @@ typedef struct vulkan_frame_s {
VkSemaphore imageAvailableSemaphore;
VkSemaphore renderDoneSemaphore;
VkCommandBuffer cmdBuffer;
int cmdSetCount;
struct qfv_cmdbufferset_s *cmdSets;
} vulkan_frame_t;
typedef struct vulkan_matrices_s {
@ -33,8 +30,8 @@ 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 qfv_renderpassset_s
DARRAY_TYPE (struct qfv_renderpass_s *) qfv_renderpassset_t;
typedef struct vulkan_ctx_s {
void (*load_vulkan) (struct vulkan_ctx_s *ctx);
@ -58,15 +55,7 @@ typedef struct vulkan_ctx_s {
VkSurfaceKHR surface; //FIXME surface = window, so "contains" swapchain
struct plitem_s *pipelineDef;
struct plitem_s *renderpassDef;
VkRenderPass renderpass;
clearvalueset_t *clearValues;
struct qfv_imageset_s *attachment_images;
struct qfv_imageviewset_s *attachment_views;
VkDeviceMemory attachmentMemory;
uint32_t swapImageIndex;
struct qfv_framebufferset_s *framebuffers;
struct hashtab_s *shaderModules;
struct hashtab_s *setLayouts;
@ -92,6 +81,7 @@ typedef struct vulkan_ctx_s {
struct qfv_stagebuf_s *staging;
size_t curFrame;
vulkan_frameset_t frames;
qfv_renderpassset_t renderPasses;
struct qfv_capture_s *capture;
void (*capture_callback) (const byte *data, int width, int height);

View file

@ -98,14 +98,15 @@ vulkan_R_Init (void)
Vulkan_CreateFrames (vulkan_ctx);
Vulkan_CreateCapture (vulkan_ctx);
Vulkan_CreateRenderPass (vulkan_ctx);
Vulkan_CreateFramebuffers (vulkan_ctx);
Vulkan_Texture_Init (vulkan_ctx);
Vulkan_Alias_Init (vulkan_ctx);
Vulkan_Bsp_Init (vulkan_ctx);
Vulkan_Draw_Init (vulkan_ctx);
Vulkan_Particles_Init (vulkan_ctx);
Vulkan_Lighting_Init (vulkan_ctx);
Vulkan_Compose_Init (vulkan_ctx);
Skin_Init ();
SCR_Init ();
@ -114,8 +115,6 @@ vulkan_R_Init (void)
static void
vulkan_R_RenderFrame (SCR_Func *scr_funcs)
{
const VkSubpassContents subpassContents
= VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
uint32_t imageIndex = 0;
qfv_device_t *device = vulkan_ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
@ -130,52 +129,61 @@ vulkan_R_RenderFrame (SCR_Func *scr_funcs)
0, &imageIndex);
vulkan_ctx->swapImageIndex = imageIndex;
frame->framebuffer = vulkan_ctx->framebuffers->a[imageIndex];
view_draw (vr_data.scr_view);
while (*scr_funcs) {
(*scr_funcs) ();
scr_funcs++;
}
Vulkan_RenderView (vulkan_ctx);
Vulkan_FlushText (vulkan_ctx);
Vulkan_Lighting_Draw (vulkan_ctx);
Vulkan_Compose_Draw (vulkan_ctx);
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];
rp->draw (rpFrame);
}
VkCommandBufferBeginInfo beginInfo
= { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
VkRenderPassBeginInfo renderPassInfo = {
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 0,
vulkan_ctx->renderpass, 0,
{ {0, 0}, vulkan_ctx->swapchain->extent },
vulkan_ctx->clearValues->size, vulkan_ctx->clearValues->a
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderArea = { {0, 0}, vulkan_ctx->swapchain->extent },
};
dfunc->vkBeginCommandBuffer (frame->cmdBuffer, &beginInfo);
renderPassInfo.framebuffer = frame->framebuffer;
dfunc->vkCmdBeginRenderPass (frame->cmdBuffer, &renderPassInfo,
subpassContents);
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];
for (int i = 0; i < frame->cmdSetCount; i++) {
if (frame->cmdSets[i].size) {
frame->framebuffer = rp->framebuffers->a[imageIndex];
renderPassInfo.framebuffer = frame->framebuffer,
renderPassInfo.renderPass = rp->renderpass;
renderPassInfo.clearValueCount = rp->clearValues->size;
renderPassInfo.pClearValues = rp->clearValues->a;
dfunc->vkCmdBeginRenderPass (frame->cmdBuffer, &renderPassInfo,
rpFrame->subpassContents);
for (int j = 0; j < rpFrame->subpassCount; j++) {
__auto_type cmdSet = &rpFrame->subpassCmdSets[j];
if (cmdSet->size) {
dfunc->vkCmdExecuteCommands (frame->cmdBuffer,
frame->cmdSets[i].size,
frame->cmdSets[i].a);
cmdSet->size, cmdSet->a);
}
// reset for next time around
frame->cmdSets[i].size = 0;
cmdSet->size = 0;
//Regardless of whether any commands were submitted for this subpass,
//must step through each and every subpass, otherwise the attachments
//won't be transitioned correctly.
if (i < frame->cmdSetCount - 1) {
dfunc->vkCmdNextSubpass (frame->cmdBuffer, subpassContents);
//Regardless of whether any commands were submitted for this
//subpass, must step through each and every subpass, otherwise
//the attachments won't be transitioned correctly.
if (j < rpFrame->subpassCount - 1) {
dfunc->vkCmdNextSubpass (frame->cmdBuffer,
rpFrame->subpassContents);
}
}
dfunc->vkCmdEndRenderPass (frame->cmdBuffer);
}
if (vulkan_ctx->capture_callback) {
VkImage srcImage = vulkan_ctx->swapchain->images->a[imageIndex];
VkCommandBuffer cmd = QFV_CaptureImage (vulkan_ctx->capture, srcImage,
@ -615,15 +623,16 @@ vulkan_vid_render_shutdown (void)
QFV_DeviceWaitIdle (device);
df->vkDestroyFence (dev, vulkan_ctx->fence, 0);
df->vkDestroyCommandPool (dev, vulkan_ctx->cmdpool, 0);
Vulkan_Compose_Shutdown (vulkan_ctx);
Vulkan_Lighting_Shutdown (vulkan_ctx);
Vulkan_Draw_Shutdown (vulkan_ctx);
Vulkan_Bsp_Shutdown (vulkan_ctx);
Vulkan_Alias_Shutdown (vulkan_ctx);
Mod_ClearAll ();
Vulkan_Texture_Shutdown (vulkan_ctx);
Vulkan_DestroyFramebuffers (vulkan_ctx);
Vulkan_DestroyRenderPass (vulkan_ctx);
Vulkan_DestroyRenderPasses (vulkan_ctx);
Vulkan_Shutdown_Common (vulkan_ctx);
}

View file

@ -595,7 +595,7 @@
dynamicState = ( viewport, scissor );
};
layout = quakebsp_layout;
//renderPass = renderpass;
renderPass = renderpass;
};
alias_depth = {
subpass = 0;
@ -629,7 +629,7 @@
dynamicState = ( viewport, scissor );
};
layout = alias_layout;
//renderPass = renderpass;
renderPass = renderpass;
};
alias_gbuf = {
subpass = 2;
@ -670,7 +670,7 @@
dynamicState = ( viewport, scissor, blend_constants );
};
layout = alias_layout;
//renderPass = renderpass;
renderPass = renderpass;
};
bsp_depth = {
subpass = 0;
@ -699,7 +699,7 @@
dynamicState = ( viewport, scissor );
};
layout = quakebsp_layout;
//renderPass = renderpass;
renderPass = renderpass;
};
bsp_gbuf = {
subpass = 2;
@ -748,7 +748,7 @@
dynamicState = ( viewport, scissor, blend_constants );
};
layout = quakebsp_layout;
//renderPass = renderpass;
renderPass = renderpass;
};
bsp_skybox = {
subpass = 1;
@ -785,7 +785,7 @@
dynamicState = ( viewport, scissor );
};
layout = quakebsp_layout;
//renderPass = renderpass;
renderPass = renderpass;
};
bsp_skysheet = {
subpass = 1;
@ -822,7 +822,7 @@
dynamicState = ( viewport, scissor );
};
layout = quakebsp_layout;
//renderPass = renderpass;
renderPass = renderpass;
};
bsp_turb = {
subpass = 1;
@ -859,7 +859,7 @@
dynamicState = ( viewport, scissor );
};
layout = quakebsp_layout;
//renderPass = renderpass;
renderPass = renderpass;
};
twod = {
subpass = 1;
@ -889,7 +889,7 @@
dynamicState = ( viewport, scissor );
};
layout = twod_layout;
//renderPass = renderpass;
renderPass = renderpass;
};
lighting = {
subpass = 3;
@ -916,7 +916,7 @@
dynamicState = ( viewport, scissor );
};
layout = lighting_layout;
//renderPass = renderpass;
renderPass = renderpass;
};
compose = {
subpass = 4;
@ -943,7 +943,7 @@
dynamicState = ( viewport, scissor );
};
layout = compose_layout;
//renderPass = renderpass;
renderPass = renderpass;
};
};
}

View file

@ -938,11 +938,11 @@ exprtype_t vulkan_frameset_t_type = {
&vulkan_frameset_t_symtab,
};
typedef struct qfv_renderpass_s {
typedef struct {
qfv_attachmentdescription_t *attachments;
qfv_subpassparametersset_t *subpasses;
qfv_subpassdependency_t *dependencies;
} qfv_renderpass_t;
} vkparse_renderpass_t;
static plelement_t parse_qfv_renderpass_attachments_data = {
QFDictionary,
@ -969,11 +969,11 @@ static plelement_t parse_qfv_renderpass_dependencies_data = {
};
static plfield_t renderpass_fields[] = {
{ "attachments", field_offset (qfv_renderpass_t, attachments), QFArray,
{ "attachments", field_offset(vkparse_renderpass_t,attachments), QFArray,
PL_ParseArray, &parse_qfv_renderpass_attachments_data },
{ "subpasses", field_offset (qfv_renderpass_t, subpasses), QFArray,
{ "subpasses", field_offset(vkparse_renderpass_t,subpasses), QFArray,
PL_ParseArray, &parse_qfv_renderpass_subpasses_data },
{ "dependencies", field_offset (qfv_renderpass_t, dependencies), QFArray,
{ "dependencies", field_offset(vkparse_renderpass_t,dependencies), QFArray,
PL_ParseArray, &parse_qfv_renderpass_dependencies_data },
{}
};
@ -1073,7 +1073,7 @@ QFV_ParseRenderPass (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
memsuper_t *memsuper = new_memsuper ();
qfv_device_t *device = ctx->device;
qfv_renderpass_t renderpass_data = {};
vkparse_renderpass_t renderpass_data = {};
if (!parse_object (ctx, memsuper, plist, parse_qfv_renderpass,
&renderpass_data, properties)) {
@ -1108,8 +1108,9 @@ QFV_ParsePipeline (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
return 0;
}
cInfo->a[0].renderPass = ctx->renderpass;
qfvPushDebug (ctx, va (ctx->va_ctx, "QFV_ParsePipeline: %d", PL_Line (plist)));
qfvPushDebug (ctx, va (ctx->va_ctx,
"QFV_ParsePipeline: %d", PL_Line (plist)));
__auto_type plSet = QFV_CreateGraphicsPipelines (device, 0, cInfo);
qfvPopDebug (ctx);
VkPipeline pipeline = plSet->a[0];
@ -1462,22 +1463,18 @@ parse_clearvalueset (const plfield_t *field, const plitem_t *item, void *data,
return 1;
}
int
clearvalueset_t *
QFV_ParseClearValues (vulkan_ctx_t *ctx, plitem_t *plist, plitem_t *properties)
{
int ret = 0;
clearvalueset_t *cv = 0;
memsuper_t *memsuper = new_memsuper ();
clearvalueset_t *clearValues = 0;
ctx->clearValues = 0;
if (parse_object (ctx, memsuper, plist, parse_clearvalueset, &clearValues,
properties)) {
ret = 1;
ctx->clearValues = DARRAY_ALLOCFIXED (clearvalueset_t,
clearValues->size, malloc);
memcpy (ctx->clearValues->a, clearValues->a,
clearValues->size * sizeof (clearValues->a[0]));
cv = DARRAY_ALLOCFIXED (clearvalueset_t, clearValues->size, malloc);
memcpy (cv->a, clearValues->a, cv->size * sizeof (cv->a[0]));
}
delete_memsuper (memsuper);
return ret;
return cv;
}

View file

@ -58,7 +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,
struct clearvalueset_s *QFV_ParseClearValues (vulkan_ctx_t *ctx,
plitem_t *plist,
plitem_t *properties);

View file

@ -282,6 +282,10 @@
type = (custom, QFString, parse_VkPipelineLayout);
fields = (layout);
};
renderPass = {
type = (custom, QFString, parse_VkRenderPass);
fields = (renderPass);
};
subpass = auto;
basePipelineHandle = {
type = (custom, QFString, parse_BasePipeline);

View file

@ -60,6 +60,7 @@
#include "QF/Vulkan/debug.h"
#include "QF/Vulkan/descriptor.h"
#include "QF/Vulkan/device.h"
#include "QF/Vulkan/renderpass.h"
#include "r_internal.h"
#include "vid_vulkan.h"
@ -81,8 +82,9 @@ emit_commands (VkCommandBuffer cmd, int pose1, int pose2,
qfv_alias_skin_t *skin,
void *vert_constants, int vert_size,
void *frag_constants, int frag_size,
aliashdr_t *hdr, vulkan_ctx_t *ctx)
aliashdr_t *hdr, qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
aliasctx_t *actx = ctx->alias_context;
@ -123,8 +125,9 @@ emit_commands (VkCommandBuffer cmd, int pose1, int pose2,
}
void
Vulkan_DrawAlias (entity_t *ent, vulkan_ctx_t *ctx)
Vulkan_DrawAlias (entity_t *ent, qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
aliasctx_t *actx = ctx->alias_context;
aliasframe_t *aframe = &actx->frames.a[ctx->curFrame];
model_t *model = ent->renderer.model;
@ -159,18 +162,19 @@ Vulkan_DrawAlias (entity_t *ent, vulkan_ctx_t *ctx)
ent->animation.pose1, ent->animation.pose2,
0, &vertex_constants, 17 * sizeof (float),
fragment_constants, sizeof (fragment_constants),
hdr, ctx);
hdr, rFrame);
emit_commands (aframe->cmdSet.a[QFV_aliasGBuffer],
ent->animation.pose1, ent->animation.pose2,
skin, &vertex_constants, 17 * sizeof (float),
fragment_constants, sizeof (fragment_constants),
hdr, ctx);
hdr, rFrame);
}
static void
alias_begin_subpass (QFV_AliasSubpass subpass, VkPipeline pipeline,
vulkan_ctx_t *ctx)
qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
aliasctx_t *actx = ctx->alias_context;
@ -181,7 +185,7 @@ alias_begin_subpass (QFV_AliasSubpass subpass, VkPipeline pipeline,
dfunc->vkResetCommandBuffer (cmd, 0);
VkCommandBufferInheritanceInfo inherit = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
ctx->renderpass, subpass_map[subpass],
rFrame->renderpass->renderpass, subpass_map[subpass],
cframe->framebuffer,
0, 0, 0,
};
@ -226,28 +230,29 @@ alias_end_subpass (VkCommandBuffer cmd, vulkan_ctx_t *ctx)
}
void
Vulkan_AliasBegin (vulkan_ctx_t *ctx)
Vulkan_AliasBegin (qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
aliasctx_t *actx = ctx->alias_context;
__auto_type cframe = &ctx->frames.a[ctx->curFrame];
aliasframe_t *aframe = &actx->frames.a[ctx->curFrame];
//XXX quat_t fog;
DARRAY_APPEND (&cframe->cmdSets[QFV_passDepth],
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passDepth],
aframe->cmdSet.a[QFV_aliasDepth]);
DARRAY_APPEND (&cframe->cmdSets[QFV_passGBuffer],
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passGBuffer],
aframe->cmdSet.a[QFV_aliasGBuffer]);
//FIXME need per frame matrices
aframe->bufferInfo[0].buffer = ctx->matrices.buffer_3d;
alias_begin_subpass (QFV_aliasDepth, actx->depth, ctx);
alias_begin_subpass (QFV_aliasGBuffer, actx->gbuf, ctx);
alias_begin_subpass (QFV_aliasDepth, actx->depth, rFrame);
alias_begin_subpass (QFV_aliasGBuffer, actx->gbuf, rFrame);
}
void
Vulkan_AliasEnd (vulkan_ctx_t *ctx)
Vulkan_AliasEnd (qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
aliasctx_t *actx = ctx->alias_context;
aliasframe_t *aframe = &actx->frames.a[ctx->curFrame];
@ -256,8 +261,10 @@ Vulkan_AliasEnd (vulkan_ctx_t *ctx)
}
void
Vulkan_AliasDepthRange (vulkan_ctx_t *ctx, float minDepth, float maxDepth)
Vulkan_AliasDepthRange (qfv_renderframe_t *rFrame,
float minDepth, float maxDepth)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
aliasctx_t *actx = ctx->alias_context;

View file

@ -63,6 +63,7 @@
#include "QF/Vulkan/device.h"
#include "QF/Vulkan/image.h"
#include "QF/Vulkan/instance.h"
#include "QF/Vulkan/renderpass.h"
#include "QF/Vulkan/scrap.h"
#include "QF/Vulkan/staging.h"
@ -825,8 +826,9 @@ get_view (qfv_tex_t *tex, qfv_tex_t *default_tex)
static void
bsp_begin_subpass (QFV_BspSubpass subpass, VkPipeline pipeline,
vulkan_ctx_t *ctx)
qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
bspctx_t *bctx = ctx->bsp_context;
@ -837,7 +839,7 @@ bsp_begin_subpass (QFV_BspSubpass subpass, VkPipeline pipeline,
dfunc->vkResetCommandBuffer (cmd, 0);
VkCommandBufferInheritanceInfo inherit = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
ctx->renderpass, subpass_map[subpass],
rFrame->renderpass->renderpass, subpass_map[subpass],
cframe->framebuffer,
0, 0, 0,
};
@ -886,20 +888,20 @@ bsp_end_subpass (VkCommandBuffer cmd, vulkan_ctx_t *ctx)
}
static void
bsp_begin (vulkan_ctx_t *ctx)
bsp_begin (qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
bspctx_t *bctx = ctx->bsp_context;
//XXX quat_t fog;
bctx->default_color[3] = 1;
QuatCopy (bctx->default_color, bctx->last_color);
__auto_type cframe = &ctx->frames.a[ctx->curFrame];
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
DARRAY_APPEND (&cframe->cmdSets[QFV_passDepth],
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passDepth],
bframe->cmdSet.a[QFV_bspDepth]);
DARRAY_APPEND (&cframe->cmdSets[QFV_passGBuffer],
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passGBuffer],
bframe->cmdSet.a[QFV_bspGBuffer]);
//FIXME need per frame matrices
@ -912,8 +914,8 @@ bsp_begin (vulkan_ctx_t *ctx)
bframe->imageInfo[4].imageView = get_view (bctx->skybox_tex,
bctx->default_skybox);
bsp_begin_subpass (QFV_bspDepth, bctx->depth, ctx);
bsp_begin_subpass (QFV_bspGBuffer, bctx->gbuf, ctx);
bsp_begin_subpass (QFV_bspDepth, bctx->depth, rFrame);
bsp_begin_subpass (QFV_bspGBuffer, bctx->gbuf, rFrame);
}
static void
@ -927,18 +929,18 @@ bsp_end (vulkan_ctx_t *ctx)
}
static void
turb_begin (vulkan_ctx_t *ctx)
turb_begin (qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
bspctx_t *bctx = ctx->bsp_context;
bctx->default_color[3] = bound (0, r_wateralpha->value, 1);
QuatCopy (bctx->default_color, bctx->last_color);
__auto_type cframe = &ctx->frames.a[ctx->curFrame];
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
DARRAY_APPEND (&cframe->cmdSets[QFV_passTranslucent],
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucent],
bframe->cmdSet.a[QFV_bspTurb]);
//FIXME need per frame matrices
@ -949,7 +951,7 @@ turb_begin (vulkan_ctx_t *ctx)
bframe->imageInfo[3].imageView = bctx->default_skysheet->view;
bframe->imageInfo[4].imageView = bctx->default_skybox->view;
bsp_begin_subpass (QFV_bspTurb, bctx->turb, ctx);
bsp_begin_subpass (QFV_bspTurb, bctx->turb, rFrame);
}
static void
@ -985,8 +987,9 @@ spin (mat4f_t mat, bspctx_t *bctx)
}
static void
sky_begin (vulkan_ctx_t *ctx)
sky_begin (qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
bspctx_t *bctx = ctx->bsp_context;
bctx->default_color[3] = 1;
@ -994,10 +997,9 @@ sky_begin (vulkan_ctx_t *ctx)
spin (ctx->matrices.sky_3d, bctx);
__auto_type cframe = &ctx->frames.a[ctx->curFrame];
bspframe_t *bframe = &bctx->frames.a[ctx->curFrame];
DARRAY_APPEND (&cframe->cmdSets[QFV_passTranslucent],
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucent],
bframe->cmdSet.a[QFV_bspSky]);
//FIXME need per frame matrices
@ -1011,9 +1013,9 @@ sky_begin (vulkan_ctx_t *ctx)
bctx->default_skybox);
if (bctx->skybox_tex) {
bsp_begin_subpass (QFV_bspSky, bctx->skybox, ctx);
bsp_begin_subpass (QFV_bspSky, bctx->skybox, rFrame);
} else {
bsp_begin_subpass (QFV_bspSky, bctx->skysheet, ctx);
bsp_begin_subpass (QFV_bspSky, bctx->skysheet, rFrame);
}
}
@ -1068,8 +1070,9 @@ build_tex_elechain (vulktex_t *tex, bspctx_t *bctx, bspframe_t *bframe)
}
void
Vulkan_DrawWorld (vulkan_ctx_t *ctx)
Vulkan_DrawWorld (qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
bspctx_t *bctx = ctx->bsp_context;
@ -1098,7 +1101,7 @@ Vulkan_DrawWorld (vulkan_ctx_t *ctx)
}
}
bsp_begin (ctx);
bsp_begin (rFrame);
push_transform (identity, bctx->layout, dfunc,
bframe->cmdSet.a[QFV_bspDepth]);
@ -1152,8 +1155,9 @@ Vulkan_DrawWorld (vulkan_ctx_t *ctx)
}
void
Vulkan_DrawWaterSurfaces (vulkan_ctx_t *ctx)
Vulkan_DrawWaterSurfaces (qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
bspctx_t *bctx = ctx->bsp_context;
@ -1166,7 +1170,7 @@ Vulkan_DrawWaterSurfaces (vulkan_ctx_t *ctx)
if (!bctx->waterchain)
return;
turb_begin (ctx);
turb_begin (rFrame);
push_transform (identity, bctx->layout, dfunc,
bframe->cmdSet.a[QFV_bspTurb]);
fragconst_t frag_constants = { time: vr_data.realtime };
@ -1214,8 +1218,9 @@ Vulkan_DrawWaterSurfaces (vulkan_ctx_t *ctx)
}
void
Vulkan_DrawSky (vulkan_ctx_t *ctx)
Vulkan_DrawSky (qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
bspctx_t *bctx = ctx->bsp_context;
@ -1228,7 +1233,7 @@ Vulkan_DrawSky (vulkan_ctx_t *ctx)
if (!bctx->sky_chain)
return;
sky_begin (ctx);
sky_begin (rFrame);
push_transform (identity, bctx->layout, dfunc,
bframe->cmdSet.a[QFV_bspSky]);
fragconst_t frag_constants = { time: vr_data.realtime };

View file

@ -48,27 +48,30 @@
#include "QF/Vulkan/descriptor.h"
#include "QF/Vulkan/device.h"
#include "QF/Vulkan/image.h"
#include "QF/Vulkan/renderpass.h"
#include "r_internal.h"
#include "vid_vulkan.h"
void
Vulkan_Compose_Draw (vulkan_ctx_t *ctx)
Vulkan_Compose_Draw (qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
qfv_renderpass_t *renderpass = rFrame->renderpass;
composectx_t *cctx = ctx->compose_context;
__auto_type frame = &ctx->frames.a[ctx->curFrame];
composeframe_t *cframe = &cctx->frames.a[ctx->curFrame];
VkCommandBuffer cmd = cframe->cmd;
DARRAY_APPEND (&frame->cmdSets[QFV_passCompose], cmd);
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passCompose], cmd);
dfunc->vkResetCommandBuffer (cmd, 0);
VkCommandBufferInheritanceInfo inherit = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
ctx->renderpass, QFV_passCompose,
renderpass->renderpass, QFV_passCompose,
frame->framebuffer,
0, 0, 0,
};
@ -85,9 +88,9 @@ Vulkan_Compose_Draw (vulkan_ctx_t *ctx)
cctx->pipeline);
cframe->imageInfo[0].imageView
= ctx->attachment_views->a[QFV_attachOpaque];
= renderpass->attachment_views->a[QFV_attachOpaque];
cframe->imageInfo[1].imageView
= ctx->attachment_views->a[QFV_attachTranslucent];
= renderpass->attachment_views->a[QFV_attachTranslucent];
dfunc->vkUpdateDescriptorSets (device->dev, COMPOSE_IMAGE_INFOS,
cframe->descriptors, 0, 0);

View file

@ -59,6 +59,7 @@
#include "QF/Vulkan/descriptor.h"
#include "QF/Vulkan/device.h"
#include "QF/Vulkan/image.h"
#include "QF/Vulkan/renderpass.h"
#include "QF/Vulkan/scrap.h"
#include "QF/Vulkan/staging.h"
#include "QF/ui/view.h"
@ -748,8 +749,9 @@ Vulkan_DrawReset (vulkan_ctx_t *ctx)
}
void
Vulkan_FlushText (vulkan_ctx_t *ctx)
Vulkan_FlushText (qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
flush_draw_scrap (ctx);
qfv_device_t *device = ctx->device;
@ -760,7 +762,7 @@ Vulkan_FlushText (vulkan_ctx_t *ctx)
VkCommandBuffer cmd = dframe->cmd;
//FIXME which pass?
DARRAY_APPEND (&cframe->cmdSets[QFV_passTranslucent], cmd);
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passTranslucent], cmd);
VkMappedMemoryRange range = {
VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
@ -772,7 +774,7 @@ Vulkan_FlushText (vulkan_ctx_t *ctx)
dfunc->vkResetCommandBuffer (cmd, 0);
VkCommandBufferInheritanceInfo inherit = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
ctx->renderpass, QFV_passTranslucent,
rFrame->renderpass->renderpass, QFV_passTranslucent,
cframe->framebuffer,
0, 0, 0
};

View file

@ -59,6 +59,7 @@
#include "QF/Vulkan/image.h"
#include "QF/Vulkan/instance.h"
#include "QF/Vulkan/projection.h"
#include "QF/Vulkan/renderpass.h"
#include "QF/Vulkan/staging.h"
#include "compat.h"
@ -197,10 +198,12 @@ update_lights (vulkan_ctx_t *ctx)
}
void
Vulkan_Lighting_Draw (vulkan_ctx_t *ctx)
Vulkan_Lighting_Draw (qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
qfv_renderpass_t *renderpass = rFrame->renderpass;
update_lights (ctx);
@ -209,12 +212,12 @@ Vulkan_Lighting_Draw (vulkan_ctx_t *ctx)
lightingframe_t *lframe = &lctx->frames.a[ctx->curFrame];
VkCommandBuffer cmd = lframe->cmd;
DARRAY_APPEND (&cframe->cmdSets[QFV_passLighting], cmd);
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passLighting], cmd);
dfunc->vkResetCommandBuffer (cmd, 0);
VkCommandBufferInheritanceInfo inherit = {
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
ctx->renderpass, QFV_passLighting,
renderpass->renderpass, QFV_passLighting,
cframe->framebuffer,
0, 0, 0,
};
@ -231,14 +234,16 @@ Vulkan_Lighting_Draw (vulkan_ctx_t *ctx)
lctx->pipeline);
lframe->bufferInfo[0].buffer = lframe->light_buffer;
lframe->attachInfo[0].imageView = ctx->attachment_views->a[QFV_attachDepth];
lframe->attachInfo[1].imageView = ctx->attachment_views->a[QFV_attachColor];
lframe->attachInfo[0].imageView
= renderpass->attachment_views->a[QFV_attachDepth];
lframe->attachInfo[1].imageView
= renderpass->attachment_views->a[QFV_attachColor];
lframe->attachInfo[2].imageView
= ctx->attachment_views->a[QFV_attachEmission];
= renderpass->attachment_views->a[QFV_attachEmission];
lframe->attachInfo[3].imageView
= ctx->attachment_views->a[QFV_attachNormal];
= renderpass->attachment_views->a[QFV_attachNormal];
lframe->attachInfo[4].imageView
= ctx->attachment_views->a[QFV_attachPosition];
= renderpass->attachment_views->a[QFV_attachPosition];
dfunc->vkUpdateDescriptorSets (device->dev,
LIGHTING_DESCRIPTORS,
lframe->descriptors, 0, 0);

View file

@ -54,6 +54,7 @@
#include "QF/Vulkan/qf_main.h"
#include "QF/Vulkan/qf_particles.h"
//#include "QF/Vulkan/qf_textures.h"
#include "QF/Vulkan/renderpass.h"
#include "mod_internal.h"
#include "r_internal.h"
@ -103,7 +104,7 @@ setup_view (vulkan_ctx_t *ctx)
}
static void
Vulkan_RenderEntities (vulkan_ctx_t *ctx)
Vulkan_RenderEntities (qfv_renderframe_t *rFrame)
{
if (!r_drawentities->int_val)
return;
@ -115,22 +116,22 @@ Vulkan_RenderEntities (vulkan_ctx_t *ctx)
if (ent->renderer.model->type != mod_##type_name) \
continue; \
if (!begun) { \
Vulkan_##Type##Begin (ctx); \
Vulkan_##Type##Begin (rFrame); \
begun = 1; \
} \
/* hack the depth range to prevent view model */\
/* from poking into walls */\
if (ent == vr_data.view_model) { \
Vulkan_AliasDepthRange (ctx, 0, 0.3); \
Vulkan_AliasDepthRange (rFrame, 0, 0.3); \
} \
Vulkan_Draw##Type (ent, ctx); \
Vulkan_Draw##Type (ent, rFrame); \
/* unhack in case the view_model is not the last */\
if (ent == vr_data.view_model) { \
Vulkan_AliasDepthRange (ctx, 0, 1); \
Vulkan_AliasDepthRange (rFrame, 0, 1); \
} \
} \
if (begun) \
Vulkan_##Type##End (ctx); \
Vulkan_##Type##End (rFrame); \
} while (0)
RE_LOOP (alias, Alias);
@ -152,8 +153,9 @@ Vulkan_DrawViewModel (vulkan_ctx_t *ctx)
}
void
Vulkan_RenderView (vulkan_ctx_t *ctx)
Vulkan_RenderView (qfv_renderframe_t *rFrame)
{
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
double t[9] = {};
int speeds = r_speeds->int_val;
@ -173,17 +175,17 @@ Vulkan_RenderView (vulkan_ctx_t *ctx)
R_PushDlights (vec3_origin);
if (speeds)
t[3] = Sys_DoubleTime ();
Vulkan_DrawWorld (ctx);
Vulkan_DrawWorld (rFrame);
if (speeds)
t[4] = Sys_DoubleTime ();
Vulkan_DrawSky (ctx);
Vulkan_DrawSky (rFrame);
if (speeds)
t[5] = Sys_DoubleTime ();
Vulkan_DrawViewModel (ctx);
Vulkan_RenderEntities (ctx);
Vulkan_RenderEntities (rFrame);
if (speeds)
t[6] = Sys_DoubleTime ();
Vulkan_DrawWaterSurfaces (ctx);
Vulkan_DrawWaterSurfaces (rFrame);
if (speeds)
t[7] = Sys_DoubleTime ();
Vulkan_DrawParticles (ctx);

View file

@ -66,6 +66,13 @@
#include "QF/Vulkan/staging.h"
#include "QF/Vulkan/swapchain.h"
#include "QF/Vulkan/qf_alias.h"
#include "QF/Vulkan/qf_bsp.h"
#include "QF/Vulkan/qf_compose.h"
#include "QF/Vulkan/qf_draw.h"
#include "QF/Vulkan/qf_lighting.h"
#include "QF/Vulkan/qf_main.h"
#include "compat.h"
#include "d_iface.h"
#include "r_internal.h"
@ -212,7 +219,6 @@ void
Vulkan_Shutdown_Common (vulkan_ctx_t *ctx)
{
PL_Free (ctx->pipelineDef);
PL_Free (ctx->renderpassDef);
if (ctx->capture) {
QFV_DestroyCapture (ctx->capture);
}
@ -297,14 +303,14 @@ qfv_load_pipeline (vulkan_ctx_t *ctx, const char *name)
}
static plitem_t *
qfv_load_renderpass (vulkan_ctx_t *ctx, const char *name)
qfv_load_renderpass (vulkan_ctx_t *ctx, qfv_renderpass_t *rp, const char *name)
{
if (!ctx->renderpassDef) {
ctx->renderpassDef = PL_GetPropertyList (quakeforge_renderpass,
if (!rp->renderpassDef) {
rp->renderpassDef = PL_GetPropertyList (quakeforge_renderpass,
&ctx->hashlinks);
}
plitem_t *item = ctx->renderpassDef;
plitem_t *item = rp->renderpassDef;
if (!item || !(item = PL_ObjectForKey (item, name))) {
Sys_Printf ("error loading %s\n", name);
} else {
@ -328,29 +334,121 @@ get_image_size (VkImage image, qfv_device_t *device)
return size;
}
static void
renderpass_draw (qfv_renderframe_t *rFrame)
{
Vulkan_RenderView (rFrame);
Vulkan_FlushText (rFrame);
Vulkan_Lighting_Draw (rFrame);
Vulkan_Compose_Draw (rFrame);
}
static void
create_attachements (vulkan_ctx_t *ctx, qfv_renderpass_t *rp)
{
qfv_device_t *device = ctx->device;
plitem_t *item = qfv_load_renderpass (ctx, rp, "images");
if (!item) {
return;
}
__auto_type images = QFV_ParseImageSet (ctx, item, rp->renderpassDef);
rp->attachment_images = images;
size_t memSize = 0;
for (size_t i = 0; i < images->size; i++) {
memSize += get_image_size (images->a[i], device);
}
VkDeviceMemory mem;
mem = QFV_AllocImageMemory (device, images->a[0],
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
memSize, 0);
rp->attachmentMemory = mem;
QFV_duSetObjectName (device, VK_OBJECT_TYPE_DEVICE_MEMORY,
mem, "memory:framebuffers");
size_t offset = 0;
for (size_t i = 0; i < images->size; i++) {
QFV_BindImageMemory (device, images->a[i], mem, offset);
offset += get_image_size (images->a[i], device);
}
item = qfv_load_renderpass (ctx, rp, "imageViews");
if (!item) {
return;
}
__auto_type views = QFV_ParseImageViewSet (ctx, item, rp->renderpassDef);
rp->attachment_views = views;
item = qfv_load_renderpass (ctx, rp, "framebuffer");
if (!item) {
return;
}
rp->framebuffers = QFV_AllocFrameBuffers (ctx->swapchain->numImages,
malloc);
for (size_t i = 0; i < rp->framebuffers->size; i++) {
ctx->swapImageIndex = i; // for $swapImageIndex in the config
rp->framebuffers->a[i] = QFV_ParseFramebuffer (ctx, item,
rp->renderpassDef);
}
}
static void
init_renderframe (vulkan_ctx_t *ctx, qfv_renderpass_t *rp,
qfv_renderframe_t *rFrame)
{
rFrame->subpassContents = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
rFrame->vulkan_ctx = ctx;
rFrame->renderpass = rp;
rFrame->subpassCount = QFV_NumPasses;
rFrame->subpassCmdSets = malloc (QFV_NumPasses
* sizeof (qfv_cmdbufferset_t));
for (int j = 0; j < QFV_NumPasses; j++) {
DARRAY_INIT (&rFrame->subpassCmdSets[j], 4);
}
}
void
Vulkan_CreateRenderPass (vulkan_ctx_t *ctx)
{
const char *name = "renderpass";//FIXME
plitem_t *item;
qfv_renderpass_t *rp = calloc (1, sizeof (qfv_renderpass_t));
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;
rp->renderpass = renderpass;
} else {
item = qfv_load_renderpass (ctx, rp, name);
rp->renderpass = QFV_ParseRenderPass (ctx, item, 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));
}
plitem_t *item = qfv_load_renderpass (ctx, name);
DARRAY_INIT (&rp->frames, 4);
DARRAY_RESIZE (&rp->frames, ctx->frames.size);
for (size_t i = 0; i < rp->frames.size; i++) {
init_renderframe (ctx, rp, &rp->frames.a[i]);
}
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);
create_attachements (ctx, rp);
item = qfv_load_renderpass (ctx, rp, "clearValues");
rp->clearValues = QFV_ParseClearValues (ctx, item, rp->renderpassDef);
rp->draw = renderpass_draw;
if (!ctx->renderPasses.grow) {
DARRAY_INIT (&ctx->renderPasses, 4);
}
DARRAY_APPEND (&ctx->renderPasses, rp);
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
@ -390,13 +488,63 @@ Vulkan_CreateRenderPass (vulkan_ctx_t *ctx)
QFV_PacketSubmit (packet);
}
void
Vulkan_DestroyRenderPass (vulkan_ctx_t *ctx)
static void
destroy_attachments (vulkan_ctx_t *ctx, qfv_renderpass_t *rp)
{
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
dfunc->vkDestroyRenderPass (device->dev, ctx->renderpass, 0);
for (size_t i = 0; i < rp->attachment_views->size; i++) {
dfunc->vkDestroyImageView (device->dev, rp->attachment_views->a[i], 0);
}
for (size_t i = 0; i < rp->attachment_images->size; i++) {
dfunc->vkDestroyImage (device->dev, rp->attachment_images->a[i], 0);
}
dfunc->vkFreeMemory (device->dev, rp->attachmentMemory, 0);
}
static void
destroy_renderframes (vulkan_ctx_t *ctx, qfv_renderpass_t *rp)
{
for (size_t i = 0; i < rp->frames.size; i++) {
__auto_type rFrame = &rp->frames.a[i];
for (int j = 0; j < rFrame->subpassCount; j++) {
DARRAY_CLEAR (&rFrame->subpassCmdSets[j]);
}
free (rFrame->subpassCmdSets);
}
}
static void
destroy_framebuffers (vulkan_ctx_t *ctx, qfv_renderpass_t *rp)
{
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
for (size_t i = 0; i < rp->framebuffers->size; i++) {
dfunc->vkDestroyFramebuffer (device->dev, rp->framebuffers->a[i], 0);
}
free (rp->framebuffers);
}
void
Vulkan_DestroyRenderPasses (vulkan_ctx_t *ctx)
{
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
for (size_t i = 0; i < ctx->renderPasses.size; i++) {
__auto_type rp = ctx->renderPasses.a[i];
PL_Free (rp->renderpassDef);
destroy_attachments (ctx, rp);
dfunc->vkDestroyRenderPass (device->dev, rp->renderpass, 0);
destroy_renderframes (ctx, rp);
destroy_framebuffers (ctx, rp);
free (rp);
}
dfunc->vkFreeMemory (device->dev, ctx->quad_memory, 0);
dfunc->vkDestroyBuffer (device->dev, ctx->quad_buffer, 0);
@ -544,12 +692,6 @@ Vulkan_CreateFrames (vulkan_ctx_t *ctx)
frame->imageAvailableSemaphore = QFV_CreateSemaphore (device);
frame->renderDoneSemaphore = QFV_CreateSemaphore (device);
frame->cmdBuffer = cmdBuffers->a[i];
frame->cmdSetCount = QFV_NumPasses;
frame->cmdSets = malloc (QFV_NumPasses * sizeof (qfv_cmdbufferset_t));
for (int j = 0; j < QFV_NumPasses; j++) {
DARRAY_INIT (&frame->cmdSets[j], 4);
}
}
}
@ -573,82 +715,7 @@ Vulkan_DestroyFrames (vulkan_ctx_t *ctx)
df->vkDestroySemaphore (dev, frame->imageAvailableSemaphore, 0);
df->vkDestroySemaphore (dev, frame->renderDoneSemaphore, 0);
frame->framebuffer = 0;
for (int j = 0; j < frame->cmdSetCount; j++) {
DARRAY_CLEAR (&frame->cmdSets[j]);
}
free (frame->cmdSets);
}
DARRAY_CLEAR (&ctx->frames);
for (size_t i = 0; i < ctx->framebuffers->size; i++) {
df->vkDestroyFramebuffer (dev, ctx->framebuffers->a[i], 0);
}
free (ctx->framebuffers);
}
void
Vulkan_CreateFramebuffers (vulkan_ctx_t *ctx)
{
qfv_device_t *device = ctx->device;
plitem_t *item = qfv_load_renderpass (ctx, "images");
if (!item) {
return;
}
__auto_type images = QFV_ParseImageSet (ctx, item, ctx->renderpassDef);
ctx->attachment_images = images;
size_t memSize = 0;
for (size_t i = 0; i < images->size; i++) {
memSize += get_image_size (images->a[i], device);
}
VkDeviceMemory mem;
mem = QFV_AllocImageMemory (device, images->a[0],
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
memSize, 0);
ctx->attachmentMemory = mem;
QFV_duSetObjectName (device, VK_OBJECT_TYPE_DEVICE_MEMORY,
mem, "memory:framebuffers");
size_t offset = 0;
for (size_t i = 0; i < images->size; i++) {
QFV_BindImageMemory (device, images->a[i], mem, offset);
offset += get_image_size (images->a[i], device);
}
item = qfv_load_renderpass (ctx, "imageViews");
if (!item) {
return;
}
__auto_type views = QFV_ParseImageViewSet (ctx, item, ctx->renderpassDef);
ctx->attachment_views = views;
item = qfv_load_renderpass (ctx, "framebuffer");
if (!item) {
return;
}
ctx->framebuffers = QFV_AllocFrameBuffers (ctx->swapchain->numImages,
malloc);
for (size_t i = 0; i < ctx->framebuffers->size; i++) {
ctx->swapImageIndex = i;
ctx->framebuffers->a[i] = QFV_ParseFramebuffer (ctx, item,
ctx->renderpassDef);
}
}
void
Vulkan_DestroyFramebuffers (vulkan_ctx_t *ctx)
{
qfv_device_t *device = ctx->device;
qfv_devfuncs_t *dfunc = device->funcs;
for (size_t i = 0; i < ctx->attachment_views->size; i++) {
dfunc->vkDestroyImageView (device->dev, ctx->attachment_views->a[i], 0);
}
for (size_t i = 0; i < ctx->attachment_images->size; i++) {
dfunc->vkDestroyImage (device->dev, ctx->attachment_images->a[i], 0);
}
dfunc->vkFreeMemory (device->dev, ctx->attachmentMemory, 0);
}