From beb05f28ff2b4f0e1cf2d5de989dec5c563c2a1b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 13 May 2022 22:00:03 +0900 Subject: [PATCH] [glsl,vulkan] More comments in the bsp code And maybe a nano-optimization. Switching from (~side + 1) to (-side) seems to give glsl a very tiny speed boost, but certainly doesn't hurt. Looking at some assembly output for the three cases, the two hacks seem to generate the same code as each other, but 3 instructions vs 6 for ?:. While ?: is more generically robust, the hacks are tuned for the knowledge side is either 0 or 1. The later xor might alter things, but at least I now know that the hack (either version) is worthwhile. --- libs/video/renderer/glsl/glsl_bsp.c | 9 +++++++-- libs/video/renderer/vulkan/vulkan_bsp.c | 12 +++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/libs/video/renderer/glsl/glsl_bsp.c b/libs/video/renderer/glsl/glsl_bsp.c index 6790cd68b..39ae051c7 100644 --- a/libs/video/renderer/glsl/glsl_bsp.c +++ b/libs/video/renderer/glsl/glsl_bsp.c @@ -731,6 +731,7 @@ visit_leaf (mleaf_t *leaf) R_StoreEfrags (leaf->efrags); } +// 1 = back side, 0 = front side static inline int get_side (mnode_t *node) { @@ -750,8 +751,10 @@ visit_node (glslbspctx_t *bctx, mnode_t *node, int side) msurface_t *surf; // sneaky hack for side = side ? SURF_PLANEBACK : 0; - side = (~side + 1) & SURF_PLANEBACK; - // draw stuff + // seems to be microscopically faster even on modern hardware + side = (-side) & SURF_PLANEBACK; + // chain any visible surfaces on the node that face the camera. + // not all nodes have any surfaces to draw (purely a split plane) if ((c = node->numsurfaces)) { surf = bctx->brush->surfaces + node->firstsurface; for (; c; c--, surf++) { @@ -759,6 +762,8 @@ visit_node (glslbspctx_t *bctx, mnode_t *node, int side) continue; // side is either 0 or SURF_PLANEBACK + // if side and the surface facing differ, then the camera is + // on backside of the surface if (side ^ (surf->flags & SURF_PLANEBACK)) continue; // wrong side diff --git a/libs/video/renderer/vulkan/vulkan_bsp.c b/libs/video/renderer/vulkan/vulkan_bsp.c index 17afc3f20..3663a5ede 100644 --- a/libs/video/renderer/vulkan/vulkan_bsp.c +++ b/libs/video/renderer/vulkan/vulkan_bsp.c @@ -638,11 +638,13 @@ R_DrawBrushModel (entity_t *e, vulkan_ctx_t *ctx) static inline void visit_leaf (mleaf_t *leaf) { - // deal with model fragments in this leaf + // since this leaf will be rendered, any entities in the leaf also need + // to be rendered (the bsp tree doubles as an entity cull structure) if (leaf->efrags) R_StoreEfrags (leaf->efrags); } +// 1 = back side, 0 = front side static inline int get_side (mnode_t *node) { @@ -662,8 +664,10 @@ visit_node (mod_brush_t *brush, mnode_t *node, int side, vulkan_ctx_t *ctx) msurface_t *surf; // sneaky hack for side = side ? SURF_PLANEBACK : 0; - side = (~side + 1) & SURF_PLANEBACK; - // draw stuff + // seems to be microscopically faster even on modern hardware + side = (-side) & SURF_PLANEBACK; + // chain any visible surfaces on the node that face the camera. + // not all nodes have any surfaces to draw (purely a split plane) if ((c = node->numsurfaces)) { surf = brush->surfaces + node->firstsurface; for (; c; c--, surf++) { @@ -671,6 +675,8 @@ visit_node (mod_brush_t *brush, mnode_t *node, int side, vulkan_ctx_t *ctx) continue; // side is either 0 or SURF_PLANEBACK + // if side and the surface facing differ, then the camera is + // on backside of the surface if (side ^ (surf->flags & SURF_PLANEBACK)) continue; // wrong side