mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-20 18:52:28 +00:00
[vulkan] Get lighting mostly working
Lights seem to be good in renderdoc, but still need to get the compose subpass working.
This commit is contained in:
parent
2122d923d9
commit
942b503486
6 changed files with 72 additions and 94 deletions
|
@ -122,7 +122,6 @@ struct qfv_orenderframe_s;
|
|||
void Vulkan_Lighting_CreateRenderPasses (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Lighting_Init (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Lighting_Shutdown (struct vulkan_ctx_s *ctx);
|
||||
void Vulkan_Lighting_Draw (struct qfv_orenderframe_s *rFrame);
|
||||
void Vulkan_LoadLights (struct scene_s *scene, struct vulkan_ctx_s *ctx);
|
||||
|
||||
#endif//__QF_Vulkan_qf_lighting_h
|
||||
|
|
|
@ -300,6 +300,14 @@ typedef struct qfv_subpass_s {
|
|||
qfv_pipeline_t *pipelines;
|
||||
} qfv_subpass_t;
|
||||
|
||||
typedef struct qfv_framebuffer_s {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t layers;
|
||||
uint32_t num_attachments;
|
||||
VkImageView *views;
|
||||
} qfv_framebuffer_t;
|
||||
|
||||
typedef struct qfv_renderpass_s {
|
||||
struct vulkan_ctx_s *vulkan_ctx;
|
||||
qfv_label_t label; // for debugging
|
||||
|
@ -307,10 +315,11 @@ typedef struct qfv_renderpass_s {
|
|||
VkRenderPassBeginInfo beginInfo;
|
||||
VkSubpassContents subpassContents;
|
||||
|
||||
qfv_framebufferinfo_t *framebufferinfo;
|
||||
|
||||
uint32_t subpass_count;
|
||||
qfv_subpass_t *subpasses;
|
||||
|
||||
qfv_framebuffer_t framebuffer;
|
||||
qfv_framebufferinfo_t *framebufferinfo;
|
||||
} qfv_renderpass_t;
|
||||
|
||||
typedef struct qfv_render_s {
|
||||
|
@ -378,6 +387,7 @@ typedef struct qfv_renderctx_s {
|
|||
typedef struct qfv_taskctx_s {
|
||||
struct vulkan_ctx_s *ctx;
|
||||
qfv_pipeline_t *pipeline;
|
||||
qfv_renderpass_t *renderpass;
|
||||
VkCommandBuffer cmd;
|
||||
} qfv_taskctx_t;
|
||||
|
||||
|
|
|
@ -78,20 +78,17 @@ run_tasks (uint32_t task_count, qfv_taskinfo_t *tasks, qfv_taskctx_t *ctx)
|
|||
}
|
||||
|
||||
static void
|
||||
run_pipeline (qfv_pipeline_t *pipeline, VkCommandBuffer cmd, vulkan_ctx_t *ctx)
|
||||
run_pipeline (qfv_pipeline_t *pipeline, qfv_taskctx_t *taskctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_device_t *device = taskctx->ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
auto cmd = taskctx->cmd;
|
||||
dfunc->vkCmdBindPipeline (cmd, pipeline->bindPoint, pipeline->pipeline);
|
||||
dfunc->vkCmdSetViewport (cmd, 0, 1, &pipeline->viewport);
|
||||
dfunc->vkCmdSetScissor (cmd, 0, 1, &pipeline->scissor);
|
||||
|
||||
qfv_taskctx_t taskctx = {
|
||||
.ctx = ctx,
|
||||
.pipeline = pipeline,
|
||||
.cmd = cmd,
|
||||
};
|
||||
run_tasks (pipeline->task_count, pipeline->tasks, &taskctx);
|
||||
taskctx->pipeline = pipeline;
|
||||
run_tasks (pipeline->task_count, pipeline->tasks, taskctx);
|
||||
|
||||
if (pipeline->num_descriptorsets) {
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, pipeline->bindPoint,
|
||||
|
@ -105,18 +102,18 @@ run_pipeline (qfv_pipeline_t *pipeline, VkCommandBuffer cmd, vulkan_ctx_t *ctx)
|
|||
|
||||
// https://themaister.net/blog/2019/08/14/yet-another-blog-explaining-vulkan-synchronization/
|
||||
static void
|
||||
run_subpass (qfv_subpass_t *sp, VkCommandBuffer cmd, vulkan_ctx_t *ctx)
|
||||
run_subpass (qfv_subpass_t *sp, qfv_taskctx_t *taskctx)
|
||||
{
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_device_t *device = taskctx->ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
dfunc->vkBeginCommandBuffer (cmd, &sp->beginInfo);
|
||||
dfunc->vkBeginCommandBuffer (taskctx->cmd, &sp->beginInfo);
|
||||
|
||||
for (uint32_t i = 0; i < sp->pipeline_count; i++) {
|
||||
__auto_type pipeline = &sp->pipelines[i];
|
||||
run_pipeline (pipeline, cmd, ctx);
|
||||
run_pipeline (pipeline, taskctx);
|
||||
}
|
||||
|
||||
dfunc->vkEndCommandBuffer (cmd);
|
||||
dfunc->vkEndCommandBuffer (taskctx->cmd);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -139,11 +136,15 @@ run_renderpass (qfv_renderpass_t *rp, vulkan_ctx_t *ctx)
|
|||
dfunc->vkCmdBeginRenderPass (cmd, &rp->beginInfo, rp->subpassContents);
|
||||
for (uint32_t i = 0; i < rp->subpass_count; i++) {
|
||||
__auto_type sp = &rp->subpasses[i];
|
||||
VkCommandBuffer subcmd = QFV_GetCmdBuffer (ctx, true);
|
||||
QFV_duCmdBeginLabel (device, cmd, sp->label.name,
|
||||
{VEC4_EXP (sp->label.color)});
|
||||
run_subpass (sp, subcmd, ctx);
|
||||
dfunc->vkCmdExecuteCommands (cmd, 1, &subcmd);
|
||||
qfv_taskctx_t taskctx = {
|
||||
.ctx = ctx,
|
||||
.renderpass = rp,
|
||||
.cmd = QFV_GetCmdBuffer (ctx, true),
|
||||
};
|
||||
run_subpass (sp, &taskctx);
|
||||
dfunc->vkCmdExecuteCommands (cmd, 1, &taskctx.cmd);
|
||||
QFV_duCmdEndLabel (device, cmd);
|
||||
//FIXME comment is a bit off as exactly one buffer is always submitted
|
||||
//
|
||||
|
@ -295,7 +296,7 @@ QFV_CreateFramebuffer (vulkan_ctx_t *ctx, qfv_renderpass_t *rp)
|
|||
__auto_type rctx = ctx->render_context;
|
||||
|
||||
auto fb = rp->framebufferinfo;
|
||||
VkImageView attachments[fb->num_attachments];
|
||||
auto attachments = rp->framebuffer.views;
|
||||
VkFramebufferCreateInfo cInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
.attachmentCount = fb->num_attachments,
|
||||
|
|
|
@ -723,6 +723,7 @@ typedef struct {
|
|||
qfv_pipeline_t *pipelines;
|
||||
qfv_taskinfo_t *tasks;
|
||||
VkDescriptorSet *descriptorsets;
|
||||
VkImageView *attachment_views;
|
||||
} jobptr_t;
|
||||
|
||||
static void
|
||||
|
@ -796,10 +797,11 @@ init_renderpass (qfv_renderpass_t *rp, qfv_renderpassinfo_t *rpinfo,
|
|||
.clearValueCount = rpinfo->framebuffer.num_attachments,
|
||||
.pClearValues = &jp->clearvalues[s->inds.num_attachments],
|
||||
},
|
||||
.framebufferinfo = &rpinfo->framebuffer,
|
||||
.subpassContents = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS,
|
||||
.subpass_count = rpinfo->num_subpasses,
|
||||
.subpasses = &jp->subpasses[s->inds.num_subpasses],
|
||||
.framebuffer.views = &jp->attachment_views[s->inds.num_attachments],
|
||||
.framebufferinfo = &rpinfo->framebuffer,
|
||||
};
|
||||
s->inds.num_attachments += rpinfo->framebuffer.num_attachments;
|
||||
for (uint32_t i = 0; i < rpinfo->num_subpasses; i++) {
|
||||
|
@ -908,6 +910,7 @@ init_job (vulkan_ctx_t *ctx, objcount_t *counts, objstate_t s)
|
|||
size += sizeof (VkPipeline [counts->num_comp_pipelines]);
|
||||
size += sizeof (VkPipelineLayout [s.inds.num_layouts]);
|
||||
size += sizeof (VkDescriptorSet [counts->num_descriptorsets]);
|
||||
size += sizeof (VkImageView [counts->num_attachments]);
|
||||
|
||||
rctx->job = malloc (size);
|
||||
auto job = rctx->job;
|
||||
|
@ -933,6 +936,7 @@ init_job (vulkan_ctx_t *ctx, objcount_t *counts, objstate_t s)
|
|||
job->pipelines = (VkPipeline *) &job->renderpasses[job->num_renderpasses];
|
||||
job->layouts = (VkPipelineLayout *) &job->pipelines[job->num_pipelines];
|
||||
auto ds = (VkDescriptorSet *) &job->layouts[job->num_layouts];
|
||||
auto av = (VkImageView *) &ds[counts->num_descriptorsets];
|
||||
jobptr_t jp = {
|
||||
.steps = job->steps,
|
||||
.renders = rn,
|
||||
|
@ -944,6 +948,7 @@ init_job (vulkan_ctx_t *ctx, objcount_t *counts, objstate_t s)
|
|||
.pipelines = pl,
|
||||
.tasks = ti,
|
||||
.descriptorsets = ds,
|
||||
.attachment_views = av,
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < job->num_renderpasses; i++) {
|
||||
|
|
|
@ -147,78 +147,6 @@ update_lights (vulkan_ctx_t *ctx)
|
|||
QFV_PacketSubmit (packet);
|
||||
}
|
||||
|
||||
void
|
||||
Vulkan_Lighting_Draw (qfv_orenderframe_t *rFrame)
|
||||
{
|
||||
vulkan_ctx_t *ctx = rFrame->vulkan_ctx;
|
||||
qfv_device_t *device = ctx->device;
|
||||
qfv_devfuncs_t *dfunc = device->funcs;
|
||||
qfv_orenderpass_t *renderpass = rFrame->renderpass;
|
||||
lightingctx_t *lctx = ctx->lighting_context;
|
||||
|
||||
if (!lctx->scene) {
|
||||
return;
|
||||
}
|
||||
if (lctx->scene->lights) {
|
||||
update_lights (ctx);
|
||||
}
|
||||
|
||||
lightingframe_t *lframe = &lctx->frames.a[ctx->curFrame];
|
||||
VkCommandBuffer cmd = lframe->cmd;
|
||||
|
||||
DARRAY_APPEND (&rFrame->subpassCmdSets[QFV_passLighting], cmd);
|
||||
|
||||
dfunc->vkResetCommandBuffer (cmd, 0);
|
||||
VkCommandBufferInheritanceInfo inherit = {
|
||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 0,
|
||||
renderpass->renderpass, QFV_passLighting,
|
||||
rFrame->framebuffer,
|
||||
0, 0, 0,
|
||||
};
|
||||
VkCommandBufferBeginInfo beginInfo = {
|
||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 0,
|
||||
VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT
|
||||
| VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, &inherit,
|
||||
};
|
||||
dfunc->vkBeginCommandBuffer (cmd, &beginInfo);
|
||||
|
||||
QFV_duCmdBeginLabel (device, cmd, "lighting", { 0.6, 0.5, 0.6, 1});
|
||||
|
||||
dfunc->vkCmdBindPipeline (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
lctx->pipeline);
|
||||
|
||||
lframe->bufferInfo[0].buffer = lframe->light_buffer;
|
||||
lframe->attachInfo[0].imageView
|
||||
= renderpass->attachment_views->a[QFV_attachDepth];
|
||||
lframe->attachInfo[1].imageView
|
||||
= renderpass->attachment_views->a[QFV_attachColor];
|
||||
lframe->attachInfo[2].imageView
|
||||
= renderpass->attachment_views->a[QFV_attachEmission];
|
||||
lframe->attachInfo[3].imageView
|
||||
= renderpass->attachment_views->a[QFV_attachNormal];
|
||||
lframe->attachInfo[4].imageView
|
||||
= renderpass->attachment_views->a[QFV_attachPosition];
|
||||
dfunc->vkUpdateDescriptorSets (device->dev,
|
||||
LIGHTING_DESCRIPTORS,
|
||||
lframe->descriptors, 0, 0);
|
||||
|
||||
VkDescriptorSet sets[] = {
|
||||
lframe->attachWrite[0].dstSet,
|
||||
lframe->bufferWrite[0].dstSet,
|
||||
lframe->shadowWrite.dstSet,
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
lctx->layout, 0, 3, sets, 0, 0);
|
||||
|
||||
dfunc->vkCmdSetViewport (cmd, 0, 1, &rFrame->renderpass->viewport);
|
||||
dfunc->vkCmdSetScissor (cmd, 0, 1, &rFrame->renderpass->scissor);
|
||||
|
||||
dfunc->vkCmdDraw (cmd, 3, 1, 0, 0);
|
||||
|
||||
QFV_duCmdEndLabel (device, cmd);
|
||||
dfunc->vkEndCommandBuffer (cmd);
|
||||
}
|
||||
|
||||
static void
|
||||
lighting_draw_maps (qfv_orenderframe_t *rFrame)
|
||||
{
|
||||
|
@ -321,6 +249,42 @@ static VkWriteDescriptorSet base_image_write = {
|
|||
static void
|
||||
lights_draw (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
|
||||
{
|
||||
auto taskctx = (qfv_taskctx_t *) ectx;
|
||||
auto ctx = taskctx->ctx;
|
||||
auto device = ctx->device;
|
||||
auto dfunc = device->funcs;
|
||||
auto lctx = ctx->lighting_context;
|
||||
auto cmd = taskctx->cmd;
|
||||
|
||||
if (!lctx->scene) {
|
||||
return;
|
||||
}
|
||||
if (lctx->scene->lights) {
|
||||
update_lights (ctx);
|
||||
}
|
||||
|
||||
lightingframe_t *lframe = &lctx->frames.a[ctx->curFrame];
|
||||
|
||||
auto fb = &taskctx->renderpass->framebuffer;
|
||||
lframe->bufferInfo[0].buffer = lframe->light_buffer;
|
||||
lframe->attachInfo[0].imageView = fb->views[QFV_attachDepth];
|
||||
lframe->attachInfo[1].imageView = fb->views[QFV_attachColor];
|
||||
lframe->attachInfo[2].imageView = fb->views[QFV_attachEmission];
|
||||
lframe->attachInfo[3].imageView = fb->views[QFV_attachNormal];
|
||||
lframe->attachInfo[4].imageView = fb->views[QFV_attachPosition];
|
||||
dfunc->vkUpdateDescriptorSets (device->dev,
|
||||
LIGHTING_DESCRIPTORS,
|
||||
lframe->descriptors, 0, 0);
|
||||
|
||||
VkDescriptorSet sets[] = {
|
||||
lframe->attachWrite[0].dstSet,
|
||||
lframe->bufferWrite[0].dstSet,
|
||||
lframe->shadowWrite.dstSet,
|
||||
};
|
||||
dfunc->vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
lctx->layout, 0, 3, sets, 0, 0);
|
||||
|
||||
dfunc->vkCmdDraw (cmd, 3, 1, 0, 0);
|
||||
}
|
||||
|
||||
static exprfunc_t lights_draw_func[] = {
|
||||
|
|
|
@ -158,7 +158,6 @@ static void
|
|||
main_draw (qfv_orenderframe_t *rFrame)
|
||||
{
|
||||
Vulkan_RenderView (rFrame);
|
||||
Vulkan_Lighting_Draw (rFrame);
|
||||
Vulkan_Compose_Draw (rFrame);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue