[vulkan] Show surfaces for selected light leaf

This has resulted in some rather interesting information: it seems the
surfaces (and thus, presumably bounding boxes) for leafs have little to
do with the actual leaf node's volume.
This commit is contained in:
Bill Currie 2023-08-09 01:23:13 +09:00
parent 5bc1924a25
commit 481c12468e
4 changed files with 119 additions and 33 deletions

View file

@ -328,6 +328,7 @@ typedef enum {
typedef enum {
QFV_bspMain,
QFV_bspShadow,
QFV_bspDebug,
QFV_bspNumStages
} QFV_BspPass;
@ -372,6 +373,7 @@ typedef struct bspctx_s {
bsp_pass_t main_pass; ///< camera view depth, gbuffer, etc
bsp_pass_t shadow_pass;
bsp_pass_t debug_pass;
VkSampler sampler;
@ -395,7 +397,7 @@ void Vulkan_BuildDisplayLists (model_t **models, int num_models,
void Vulkan_Bsp_Init (struct vulkan_ctx_s *ctx);
void Vulkan_Bsp_Setup (struct vulkan_ctx_s *ctx);
void Vulkan_Bsp_Shutdown (struct vulkan_ctx_s *ctx);
bsp_pass_t *Vulkan_Bsp_GetAuxPass (struct vulkan_ctx_s *ctx);
bsp_pass_t *Vulkan_Bsp_GetPass (struct vulkan_ctx_s *ctx, QFV_BspPass pass_ind);
///@}
#endif//__QF_Vulkan_qf_bsp_h

View file

@ -1730,13 +1730,13 @@ renderpasses = {
color = $color.bsp;
tasks = (
{ func = bsp_draw_queue;
params = (main, solid, 0); },
params = (debug, solid, 0); },
{ func = bsp_draw_queue;
params = (main, sky, 0); },
params = (debug, sky, 0); },
{ func = bsp_draw_queue;
params = (main, translucent, 0); },
params = (debug, translucent, 0); },
{ func = bsp_draw_queue;
params = (main, turbulent, 0); },
params = (debug, turbulent, 0); },
);
stages = (
@ -2160,6 +2160,8 @@ steps = {
{ func = bsp_reset_queues; },
{ func = bsp_visit_world;
params = (main); },
{ func = bsp_visit_world;
params = (debug); },
{ func = scene_draw_viewmodel; },
{ func = lighting_update_lights; },
);

View file

@ -131,13 +131,21 @@ init_visstate (bspctx_t *bctx)
int count = brush->numnodes + brush->modleafs
+ brush->numsurfaces;
int size = count * sizeof (int);
int *node_frames = Hunk_AllocName (0, size, "visframes");
int *leaf_frames = node_frames + brush->numnodes;
int *face_frames = leaf_frames + brush->modleafs;
int *shadow_node_frames = Hunk_AllocName (0, size, "visframes");
int *shadow_leaf_frames = shadow_node_frames + brush->numnodes;
int *shadow_face_frames = shadow_leaf_frames + brush->modleafs;
int *debug_node_frames = Hunk_AllocName (0, size, "visframes");
int *debug_leaf_frames = debug_node_frames + brush->numnodes;
int *debug_face_frames = debug_leaf_frames + brush->modleafs;
bctx->shadow_pass.vis_frame = 0;
bctx->shadow_pass.face_frames = face_frames;
bctx->shadow_pass.leaf_frames = leaf_frames;
bctx->shadow_pass.node_frames = node_frames;
bctx->shadow_pass.face_frames = shadow_face_frames;
bctx->shadow_pass.leaf_frames = shadow_leaf_frames;
bctx->shadow_pass.node_frames = shadow_node_frames;
bctx->debug_pass.vis_frame = 0;
bctx->debug_pass.face_frames = debug_face_frames;
bctx->debug_pass.leaf_frames = debug_leaf_frames;
bctx->debug_pass.node_frames = debug_node_frames;
bctx->main_pass.face_frames = r_visstate.face_visframes;
bctx->main_pass.leaf_frames = r_visstate.leaf_visframes;
@ -209,6 +217,7 @@ clear_textures (vulkan_ctx_t *ctx)
clear_pass_face_queues (&bctx->main_pass, bctx);
clear_pass_face_queues (&bctx->shadow_pass, bctx);
clear_pass_face_queues (&bctx->debug_pass, bctx);
bctx->registered_textures.size = 0;
}
@ -315,6 +324,7 @@ Vulkan_RegisterTextures (model_t **models, int num_models, vulkan_ctx_t *ctx)
// create face queue arrays
setup_pass_face_queues (&bctx->main_pass, num_tex, bctx);
setup_pass_face_queues (&bctx->shadow_pass, num_tex, bctx);
setup_pass_face_queues (&bctx->debug_pass, num_tex, bctx);
}
typedef struct {
@ -432,6 +442,7 @@ Vulkan_BuildDisplayLists (model_t **models, int num_models, vulkan_ctx_t *ctx)
shutdown_pass_instances (&bctx->main_pass, bctx);
shutdown_pass_instances (&bctx->shadow_pass, bctx);
shutdown_pass_instances (&bctx->debug_pass, bctx);
bctx->num_models = 0;
// run through all surfaces, chaining them to their textures, thus
@ -473,6 +484,7 @@ Vulkan_BuildDisplayLists (model_t **models, int num_models, vulkan_ctx_t *ctx)
}
setup_pass_instances (&bctx->main_pass, bctx);
setup_pass_instances (&bctx->shadow_pass, bctx);
setup_pass_instances (&bctx->debug_pass, bctx);
// All vertices from all brush models go into one giant vbo.
uint32_t vertex_count = 0;
uint32_t index_count = 0;
@ -1195,9 +1207,13 @@ bsp_draw_queue (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
// params are in reverse order
auto pass_ind = *(QFV_BspPass *) params[2]->value;
auto queue = *(QFV_BspQueue *) params[1]->value;
auto stage = *(int *) params[0]->value;
auto textured = *(int *) params[0]->value;
auto pass = pass_ind ? &bctx->shadow_pass : &bctx->main_pass;
auto pass = (bsp_pass_t *[]) {
[QFV_bspMain] = &bctx->main_pass,
[QFV_bspShadow] = &bctx->shadow_pass,
[QFV_bspDebug] = &bctx->debug_pass,
}[pass_ind];
if (!pass->draw_queues[queue].size) {
return;
}
@ -1236,7 +1252,7 @@ bsp_draw_queue (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
bind_texture (&skybox, SKYBOX_SET, layout, dfunc, cmd);
}
pass->textures = stage ? &bctx->registered_textures : 0;
pass->textures = textured ? &bctx->registered_textures : 0;
draw_queue (pass, queue, layout, device, cmd);
}
@ -1248,14 +1264,18 @@ bsp_visit_world (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
auto bctx = ctx->bsp_context;
auto pass_ind = *(QFV_BspPass *) params[0]->value;
auto pass = pass_ind ? &bctx->shadow_pass : &bctx->main_pass;
auto pass = (bsp_pass_t *[]) {
[QFV_bspMain] = &bctx->main_pass,
[QFV_bspShadow] = &bctx->shadow_pass,
[QFV_bspDebug] = &bctx->debug_pass,
}[pass_ind];
if (!pass_ind) {
if (pass_ind == QFV_bspMain) {
pass->entqueue = r_ent_queue;
pass->brush = &r_refdef.worldmodel->brush;
pass->position = r_refdef.frame.position;
pass->vis_frame = r_visstate.visframecount;
}
pass->brush = &r_refdef.worldmodel->brush;
EntQueue_Clear (pass->entqueue);
@ -1281,8 +1301,11 @@ bsp_visit_world (const exprval_t **params, exprval_t *result, exprctx_t *ectx)
if (pass->instances) {
DARRAY_APPEND (&pass->instances[world_id].entities, world_id);
}
auto visit_node = pass_ind ? visit_node_no_bfcull : visit_node_bfcull;
R_VisitWorldNodes (pass, ctx, visit_node);
R_VisitWorldNodes (pass, ctx, (typeof(visit_node_bfcull)*[]) {
[QFV_bspMain] = visit_node_bfcull,
[QFV_bspShadow] = visit_node_no_bfcull,
[QFV_bspDebug] = visit_node_no_bfcull,
}[pass_ind]);
if (r_drawentities) {
auto queue = pass->entqueue;
@ -1312,10 +1335,12 @@ static exprtype_t bsp_pass_type = {
static int bsp_pass_values[] = {
QFV_bspMain,
QFV_bspShadow,
QFV_bspDebug,
};
static exprsym_t bsp_pass_symbols[] = {
{"main", &bsp_pass_type, bsp_pass_values + 0},
{"shadow", &bsp_pass_type, bsp_pass_values + 1},
{"debug", &bsp_pass_type, bsp_pass_values + 2},
{}
};
static exprtab_t bsp_pass_symtab = { .symbols = bsp_pass_symbols };
@ -1390,6 +1415,8 @@ Vulkan_Bsp_Init (vulkan_ctx_t *ctx)
bctx->main_pass.bsp_context = bctx;
bctx->shadow_pass.bsp_context = bctx;
bctx->shadow_pass.entqueue = EntQueue_New (mod_num_types);
bctx->debug_pass.bsp_context = bctx;
bctx->debug_pass.entqueue = EntQueue_New (mod_num_types);
}
void
@ -1417,6 +1444,7 @@ Vulkan_Bsp_Setup (vulkan_ctx_t *ctx)
setup_pass_draw_queues (&bctx->main_pass);
setup_pass_draw_queues (&bctx->shadow_pass);
setup_pass_draw_queues (&bctx->debug_pass);
auto rctx = ctx->render_context;
size_t frames = rctx->frames.size;
@ -1476,6 +1504,7 @@ Vulkan_Bsp_Shutdown (struct vulkan_ctx_s *ctx)
shutdown_pass_draw_queues (&bctx->main_pass);
shutdown_pass_draw_queues (&bctx->shadow_pass);
shutdown_pass_draw_queues (&bctx->debug_pass);
DARRAY_CLEAR (&bctx->registered_textures);
@ -1484,6 +1513,7 @@ Vulkan_Bsp_Shutdown (struct vulkan_ctx_s *ctx)
shutdown_pass_instances (&bctx->main_pass, bctx);
shutdown_pass_instances (&bctx->shadow_pass, bctx);
shutdown_pass_instances (&bctx->debug_pass, bctx);
DARRAY_CLEAR (&bctx->frames);
@ -1589,13 +1619,17 @@ Vulkan_LoadSkys (const char *sky, vulkan_ctx_t *ctx)
}
bsp_pass_t *
Vulkan_Bsp_GetAuxPass (struct vulkan_ctx_s *ctx)
Vulkan_Bsp_GetPass (struct vulkan_ctx_s *ctx, QFV_BspPass pass_ind)
{
auto bctx = ctx->bsp_context;
auto pass = &bctx->shadow_pass;
if (!r_refdef.worldmodel) {
return 0;
}
auto pass = (bsp_pass_t *[]) {
[QFV_bspMain] = &bctx->main_pass,
[QFV_bspShadow] = &bctx->shadow_pass,
[QFV_bspDebug] = &bctx->debug_pass,
}[pass_ind];
auto bframe = &bctx->frames.a[ctx->curFrame];
pass->entid_data = bframe->entid_data;
pass->entid_count = bframe->entid_count;

View file

@ -52,7 +52,8 @@
#include "QF/va.h"
#include "QF/scene/scene.h"
#include "QF/ui/view.h"
#include "QF/ui/imui.h"
#define IMUI_context imui_ctx
#include "QF/Vulkan/qf_bsp.h"
#include "QF/Vulkan/qf_draw.h"
@ -160,7 +161,7 @@ lighting_setup_shadow (const exprval_t **params, exprval_t *result,
if (!lctx->ldata) {
return;
}
auto pass = Vulkan_Bsp_GetAuxPass (ctx);
auto pass = Vulkan_Bsp_GetPass (ctx, QFV_bspShadow);
auto brush = pass->brush;
set_t leafs = SET_STATIC_INIT (brush->modleafs, alloca);
set_empty (&leafs);
@ -281,7 +282,6 @@ lighting_draw_shadow_maps (const exprval_t **params, exprval_t *result,
if (!lctx->num_maps) {
return;
}
//auto pass = Vulkan_Bsp_GetAuxPass (ctx);
clear_frame_buffers_views (ctx, lframe);
@ -884,15 +884,6 @@ Vulkan_Lighting_Setup (vulkan_ctx_t *ctx)
Vulkan_Script_SetOutput (ctx,
&(qfv_output_t) { .format = VK_FORMAT_X8_D24_UNORM_PACK32 });
#if 0
plitem_t *rp_def = lctx->qfv_renderpass->renderpassDef;
plitem_t *rp_cfg = PL_ObjectForKey (rp_def, "renderpass_6");
lctx->renderpass_6 = QFV_ParseRenderPass (ctx, rp_cfg, rp_def);
rp_cfg = PL_ObjectForKey (rp_def, "renderpass_4");
lctx->renderpass_4 = QFV_ParseRenderPass (ctx, rp_cfg, rp_def);
rp_cfg = PL_ObjectForKey (rp_def, "renderpass_1");
lctx->renderpass_1 = QFV_ParseRenderPass (ctx, rp_cfg, rp_def);
#endif
DARRAY_INIT (&lctx->light_mats, 16);
DARRAY_INIT (&lctx->light_control, 16);
@ -1764,6 +1755,60 @@ update_shadow_descriptors (lightingctx_t *lctx, vulkan_ctx_t *ctx)
dfunc->vkUpdateDescriptorSets (device->dev, 2, imageWrite, 0, 0);
}
static void
show_leaves (vulkan_ctx_t *ctx, uint32_t leafnum, efrag_t *efrags)
{
auto pass = Vulkan_Bsp_GetPass (ctx, QFV_bspDebug);
auto brush = pass->brush;
set_t pvs = SET_STATIC_INIT (brush->visleafs, alloca);
set_empty (&pvs);
if (leafnum) {
set_add (&pvs, leafnum - 1);
}
visstate_t visstate = {
.node_visframes = pass->node_frames,
.leaf_visframes = pass->leaf_frames,
.face_visframes = pass->face_frames,
.visframecount = pass->vis_frame,
.brush = pass->brush,
};
R_MarkLeavesPVS (&visstate, &pvs);
pass->vis_frame = visstate.visframecount;
}
static void
scene_efrags_ui (void *comp, imui_ctx_t *imui_ctx,
ecs_registry_t *reg, uint32_t ent, void *data)
{
auto efrags = *(efrag_t **) comp;
uint32_t len = 0;
bool valid = true;
for (auto e = efrags; e; e = e->entnext, len++) {
valid &= e->entity.id == ent;
}
UI_Horizontal {
UI_FlexibleSpace ();
UI_Labelf ("%4s %5u", valid ? "good" : "bad", len);
}
}
static void
scene_lightleaf_ui (void *comp, imui_ctx_t *imui_ctx,
ecs_registry_t *reg, uint32_t ent, void *data)
{
vulkan_ctx_t *ctx = data;
auto leaf = *(uint32_t *) comp;
UI_Horizontal {
if (UI_Button (va (ctx->va_ctx, "Show##lightleaf_ui.%08x", ent))) {
show_leaves (ctx, leaf, 0);
}
UI_FlexibleSpace ();
UI_Labelf ("%5u", leaf);
}
}
void
Vulkan_LoadLights (scene_t *scene, vulkan_ctx_t *ctx)
{
@ -1776,6 +1821,9 @@ Vulkan_LoadLights (scene_t *scene, vulkan_ctx_t *ctx)
lctx->ldata = 0;
if (lctx->scene) {
auto reg = lctx->scene->reg;
reg->components.a[scene_efrags].ui = scene_efrags_ui;
reg->components.a[scene_lightleaf].ui = scene_lightleaf_ui;
auto light_pool = &reg->comp_pools[scene_light];
if (light_pool->count) {
lctx->dynamic_base = light_pool->count;