[vulkan] Run the shadow render passes

The shadow maps are rendered incorrectly because the matrices aren't set
correctly yet, but the dual-pass bsp rendering is working.
This commit is contained in:
Bill Currie 2023-07-29 01:17:53 +09:00
parent 3d4cca4393
commit 931175b21d
5 changed files with 153 additions and 16 deletions

View file

@ -61,6 +61,9 @@ typedef struct qfv_light_buffer_s {
#define LIGHTING_SHADOW_INFOS 32 #define LIGHTING_SHADOW_INFOS 32
#define LIGHTING_DESCRIPTORS (LIGHTING_BUFFER_INFOS + LIGHTING_ATTACH_INFOS + 1) #define LIGHTING_DESCRIPTORS (LIGHTING_BUFFER_INFOS + LIGHTING_ATTACH_INFOS + 1)
typedef struct qfv_framebufferset_s
DARRAY_TYPE (VkFramebuffer) qfv_framebufferset_t;
typedef struct lightingframe_s { typedef struct lightingframe_s {
VkBuffer data_buffer; VkBuffer data_buffer;
VkBuffer id_buffer; VkBuffer id_buffer;
@ -79,6 +82,9 @@ typedef struct lightingframe_s {
VkWriteDescriptorSet shadowWrite; VkWriteDescriptorSet shadowWrite;
}; };
}; };
qfv_imageviewset_t views;
qfv_framebufferset_t framebuffers;
} lightingframe_t; } lightingframe_t;
typedef struct lightingframeset_s typedef struct lightingframeset_s

View file

@ -1920,6 +1920,7 @@ steps = {
dependencies = (wait_on_fence); dependencies = (wait_on_fence);
process = { process = {
tasks = ( tasks = (
{ func = bsp_reset_queues; },
{ func = bsp_visit_world; { func = bsp_visit_world;
params = (main); }, params = (main); },
{ func = scene_draw_viewmodel; }, { func = scene_draw_viewmodel; },

View file

@ -838,6 +838,7 @@ clear_queues (bspctx_t *bctx, bsp_pass_t *pass)
static void static void
queue_faces (bsp_pass_t *pass, const bspctx_t *bctx, bspframe_t *bframe) queue_faces (bsp_pass_t *pass, const bspctx_t *bctx, bspframe_t *bframe)
{ {
uint32_t base = bframe->index_count;
pass->indices = bframe->index_data + bframe->index_count; pass->indices = bframe->index_data + bframe->index_count;
for (size_t i = 0; i < bctx->registered_textures.size; i++) { for (size_t i = 0; i < bctx->registered_textures.size; i++) {
auto queue = &pass->face_queue[i]; auto queue = &pass->face_queue[i];
@ -882,7 +883,7 @@ queue_faces (bsp_pass_t *pass, const bspctx_t *bctx, bspframe_t *bframe)
.tex_id = i, .tex_id = i,
.inst_id = is.inst_id, .inst_id = is.inst_id,
.instance_count = instance->entities.size, .instance_count = instance->entities.size,
.first_index = pass->index_count, .first_index = pass->index_count + base,
.first_instance = instance->first_instance, .first_instance = instance->first_instance,
})); }));
dq_size = pass->draw_queues[dq].size; dq_size = pass->draw_queues[dq].size;
@ -1121,6 +1122,20 @@ create_notexture (vulkan_ctx_t *ctx)
bctx->notexture.tex = Vulkan_LoadTexArray (ctx, tex, 2, 1, "notexture"); bctx->notexture.tex = Vulkan_LoadTexArray (ctx, tex, 2, 1, "notexture");
} }
static void
bsp_reset_queues (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
{
auto taskctx = (qfv_taskctx_t *) ectx;
auto ctx = taskctx->ctx;
auto bctx = ctx->bsp_context;
auto bframe = &bctx->frames.a[ctx->curFrame];
bframe->index_count = 0;
bframe->entid_count = 0;
Vulkan_Scene_Flush (ctx);
}
static void static void
bsp_draw_queue (const exprval_t **params, exprval_t *result, exprctx_t *ectx) bsp_draw_queue (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
{ {
@ -1137,15 +1152,12 @@ bsp_draw_queue (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
} }
// params are in reverse order // params are in reverse order
auto pass = *(int *) params[2]->value; auto pass_ind = *(int *) params[2]->value;
auto queue = *(QFV_BspQueue *) params[1]->value; auto queue = *(QFV_BspQueue *) params[1]->value;
auto stage = *(int *) params[0]->value; auto stage = *(int *) params[0]->value;
if (pass) { auto pass = pass_ind ? &bctx->aux_pass : &bctx->main_pass;
Sys_Error ("bsp passes not implemented"); if (!pass->draw_queues[queue].size) {
}
auto mpass = &bctx->main_pass;
if (!mpass->draw_queues[queue].size) {
return; return;
} }
@ -1177,8 +1189,8 @@ bsp_draw_queue (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
bind_texture (&skybox, SKYBOX_SET, layout, dfunc, cmd); bind_texture (&skybox, SKYBOX_SET, layout, dfunc, cmd);
} }
mpass->textures = stage ? &bctx->registered_textures : 0; pass->textures = stage ? &bctx->registered_textures : 0;
draw_queue (mpass, queue, layout, device, cmd); draw_queue (pass, queue, layout, device, cmd);
} }
static void static void
@ -1188,6 +1200,7 @@ bsp_visit_world (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
auto ctx = taskctx->ctx; auto ctx = taskctx->ctx;
auto bctx = ctx->bsp_context; auto bctx = ctx->bsp_context;
auto pass_ind = *(int *) params[0]->value; auto pass_ind = *(int *) params[0]->value;
auto pass = pass_ind ? &bctx->aux_pass : &bctx->main_pass; auto pass = pass_ind ? &bctx->aux_pass : &bctx->main_pass;
if (!pass_ind) { if (!pass_ind) {
@ -1198,7 +1211,6 @@ bsp_visit_world (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
} }
EntQueue_Clear (pass->entqueue); EntQueue_Clear (pass->entqueue);
Vulkan_Scene_Flush (ctx);
clear_queues (bctx, pass); // do this first for water and skys clear_queues (bctx, pass); // do this first for water and skys
@ -1209,12 +1221,10 @@ bsp_visit_world (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
auto bframe = &bctx->frames.a[ctx->curFrame]; auto bframe = &bctx->frames.a[ctx->curFrame];
pass->entid_data = bframe->entid_data; pass->entid_data = bframe->entid_data;
pass->entid_count = 0; pass->entid_count = bframe->entid_count;
bctx->anim_index = r_data->realtime * 5; bctx->anim_index = r_data->realtime * 5;
bframe->index_count = 0;
entity_t worldent = nullentity; entity_t worldent = nullentity;
int world_id = Vulkan_Scene_AddEntity (ctx, worldent); int world_id = Vulkan_Scene_AddEntity (ctx, worldent);
@ -1236,9 +1246,10 @@ bsp_visit_world (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
} }
} }
} }
bframe->entid_count = bctx->main_pass.entid_count;
queue_faces (&bctx->main_pass, bctx, bframe); queue_faces (pass, bctx, bframe);
bframe->entid_count = pass->entid_count;
bsp_flush (ctx); bsp_flush (ctx);
} }
@ -1298,6 +1309,10 @@ static exprtype_t *bsp_draw_queue_params[] = {
&bsp_stage_type, &bsp_stage_type,
}; };
static exprfunc_t bsp_reset_queues_func[] = {
{ .func = bsp_reset_queues },
{}
};
static exprfunc_t bsp_visit_world_func[] = { static exprfunc_t bsp_visit_world_func[] = {
{ 0, 1, bsp_visit_world_params, bsp_visit_world }, { 0, 1, bsp_visit_world_params, bsp_visit_world },
{} {}
@ -1307,6 +1322,7 @@ static exprfunc_t bsp_draw_queue_func[] = {
{} {}
}; };
static exprsym_t bsp_task_syms[] = { static exprsym_t bsp_task_syms[] = {
{ "bsp_reset_queues", &cexpr_function, bsp_reset_queues_func },
{ "bsp_visit_world", &cexpr_function, bsp_visit_world_func }, { "bsp_visit_world", &cexpr_function, bsp_visit_world_func },
{ "bsp_draw_queue", &cexpr_function, bsp_draw_queue_func }, { "bsp_draw_queue", &cexpr_function, bsp_draw_queue_func },
{} {}

View file

@ -179,10 +179,106 @@ lighting_setup_aux (const exprval_t **params, exprval_t *result,
pass->vis_frame = visstate.visframecount; pass->vis_frame = visstate.visframecount;
} }
static VkImageView
create_view (vulkan_ctx_t *ctx, light_renderer_t *renderer)
{
auto device = ctx->device;
auto dfunc = device->funcs;
auto lctx = ctx->lighting_context;
VkImageViewCreateInfo cInfo = {
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.image = lctx->light_images.a[renderer->image_index],
.viewType = VK_IMAGE_VIEW_TYPE_2D_ARRAY,
.format = VK_FORMAT_X8_D24_UNORM_PACK32,
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT,
.levelCount = 1,
.baseArrayLayer = renderer->layer,
.layerCount = renderer->numLayers,
},
};
VkImageView view;
dfunc->vkCreateImageView (device->dev, &cInfo, 0, &view);
return view;
}
static VkFramebuffer
create_framebuffer (vulkan_ctx_t *ctx, light_renderer_t *renderer,
VkImageView view, VkRenderPass renderpass)
{
auto device = ctx->device;
auto dfunc = device->funcs;
VkFramebuffer framebuffer;
dfunc->vkCreateFramebuffer (device->dev,
&(VkFramebufferCreateInfo) {
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
.renderPass = renderpass,
.attachmentCount = 1,
.pAttachments = &view,
.width = renderer->size,
.height = renderer->size,
.layers = 1,
}, 0, &framebuffer);
return framebuffer;
}
static void
clear_frame_buffers_views (vulkan_ctx_t *ctx, lightingframe_t *lframe)
{
auto device = ctx->device;
auto dfunc = device->funcs;
for (size_t i = 0; i < lframe->framebuffers.size; i++) {
auto framebuffer = lframe->framebuffers.a[i];
dfunc->vkDestroyFramebuffer (device->dev, framebuffer, 0);
}
lframe->framebuffers.size = 0;
for (size_t i = 0; i < lframe->views.size; i++) {
auto view = lframe->views.a[i];
dfunc->vkDestroyImageView (device->dev, view, 0);
}
lframe->views.size = 0;
}
static void static void
lighting_draw_shadow_maps (const exprval_t **params, exprval_t *result, lighting_draw_shadow_maps (const exprval_t **params, exprval_t *result,
exprctx_t *ectx) exprctx_t *ectx)
{ {
auto taskctx = (qfv_taskctx_t *) ectx;
auto ctx = taskctx->ctx;
auto lctx = ctx->lighting_context;
auto shadow = QFV_GetStep (params[0], ctx->render_context->job);
auto render = shadow->render;
auto lframe = &lctx->frames.a[ctx->curFrame];
if (!lctx->ldata) {
return;
}
//auto pass = Vulkan_Bsp_GetAuxPass (ctx);
clear_frame_buffers_views (ctx, lframe);
auto queue = r_ent_queue; //FIXME fetch from scene
for (size_t i = 0; i < queue->ent_queues[mod_light].size; i++) {
entity_t ent = queue->ent_queues[mod_light].a[i];
auto ls = get_lightstyle (ent);
if (!d_lightstylevalue[ls]) {
continue;
}
uint32_t id = get_lightid (ent);
auto r = &lctx->light_renderers.a[id];
//auto l = get_light (ent);
auto renderpass = &render->renderpasses[r->renderpass_index];
auto view = create_view (ctx, r);
auto bi = &renderpass->beginInfo;
auto fbuffer = create_framebuffer (ctx, r, view, bi->renderPass);
bi->framebuffer = fbuffer;
QFV_RunRenderPass (ctx, renderpass, r->size, r->size);
DARRAY_APPEND (&lframe->views, view);
DARRAY_APPEND (&lframe->framebuffers, fbuffer);
bi->framebuffer = 0;
}
} }
static void static void
@ -692,6 +788,9 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
lframe->shadowWrite.dstBinding = 0; lframe->shadowWrite.dstBinding = 0;
lframe->shadowWrite.descriptorCount = LIGHTING_SHADOW_INFOS; lframe->shadowWrite.descriptorCount = LIGHTING_SHADOW_INFOS;
lframe->shadowWrite.pImageInfo = lframe->shadowInfo; lframe->shadowWrite.pImageInfo = lframe->shadowInfo;
lframe->views = (qfv_imageviewset_t) DARRAY_STATIC_INIT (16);
lframe->framebuffers = (qfv_framebufferset_t) DARRAY_STATIC_INIT (16);
} }
auto packet = QFV_PacketAcquire (ctx->staging); auto packet = QFV_PacketAcquire (ctx->staging);
@ -735,6 +834,13 @@ Vulkan_Lighting_Shutdown (vulkan_ctx_t *ctx)
QFV_DestroyResource (device, lctx->light_resources); QFV_DestroyResource (device, lctx->light_resources);
free (lctx->light_resources); free (lctx->light_resources);
for (size_t i = 0; i < lctx->frames.size; i++) {
auto lframe = &lctx->frames.a[i];
clear_frame_buffers_views (ctx, lframe);
DARRAY_CLEAR (&lframe->views);
DARRAY_CLEAR (&lframe->framebuffers);
}
DARRAY_CLEAR (&lctx->light_mats); DARRAY_CLEAR (&lctx->light_mats);
DARRAY_CLEAR (&lctx->light_images); DARRAY_CLEAR (&lctx->light_images);
DARRAY_CLEAR (&lctx->light_renderers); DARRAY_CLEAR (&lctx->light_renderers);
@ -956,7 +1062,7 @@ build_shadow_maps (lightingctx_t *lctx, vulkan_ctx_t *ctx)
for (int i = 0; i < numMaps; i++) { for (int i = 0; i < numMaps; i++) {
int cube = maps[i].layers < 6 ? 0 : maps[i].cube; int cube = maps[i].layers < 6 ? 0 : maps[i].cube;
shad->objects[i] = (qfv_resobj_t) { shad->objects[i] = (qfv_resobj_t) {
.name = "map", .name = va (ctx->va_ctx, "map:%d", maps[i].size),
.type = qfv_res_image, .type = qfv_res_image,
.image = { .image = {
.flags = cube ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0, .flags = cube ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0,

View file

@ -84,6 +84,14 @@ Vulkan_Scene_AddEntity (vulkan_ctx_t *ctx, entity_t entity)
render_id = sframe->entity_pool.size++; render_id = sframe->entity_pool.size++;
entdata = sframe->entity_pool.a + render_id; entdata = sframe->entity_pool.a + render_id;
} }
} else {
if (!Entity_Valid (entity)) {
return 0; //FIXME see below
} else {
renderer_t *renderer = Ent_GetComponent (entity.id, scene_renderer,
entity.reg);
return renderer->render_id;
}
} }
if (Entity_Valid (entity)) { if (Entity_Valid (entity)) {
renderer_t *renderer = Ent_GetComponent (entity.id, scene_renderer, renderer_t *renderer = Ent_GetComponent (entity.id, scene_renderer,