Skip to content

Commit 7e71627

Browse files
cursoragenttimfox
andcommitted
Vulkan RTX: world BSP BLAS, frame UBO + depth, r_rtxWorldPrimCap
- Pack SF_FACE and SF_TRIANGLES geometry from world bmodel[0] into BLAS (vk_rtx_world). - Rebuild BLAS/TLAS when map name changes; cap triangles via latched r_rtxWorldPrimCap. - Descriptor set: TLAS, storage image, RtxFrame UBO, combined depth sampler; raygen uses invViewProj and depth. - vk_rtx_record_demo_pass: UBO fill, depth layout transitions on main pass, fix RT image barrier after first frame. - vk_render_pass: gate RT demo on r_rtxDemo; scratch buffer uses VK_BUFFER_USAGE_STORAGE_BUFFER_BIT for RT builds. - Docs: RENDERERS_FUTURE and TODO_TRIAGE reflect world BLAS path. Co-authored-by: Tim Fox <timfox@outlook.com>
1 parent 1a27bd3 commit 7e71627

12 files changed

Lines changed: 901 additions & 273 deletions

File tree

docs/RENDERERS_FUTURE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This document outlines the architecture and implementation plan for three render
88
|---------|--------|-------|
99
| **Vulkan** | ✅ Complete | Primary renderer, ~18k LOC |
1010
| **OpenGL** | ✅ Complete | Fallback renderer |
11-
| **Vulkan RTX** | 🔶 Demo path | With `USE_VULKAN_RTX=ON` and `r_rtx`>0 (latched): device enables KHR AS + ray-tracing pipeline + BDA. `r_rtxDemo` 1 (default): triangle BLAS/TLAS, minimal RTPSO, `vkCmdTraceRaysKHR` after main/post-bloom pass, blit into resolved color (layout barriers match FBO `SHADER_READ_ONLY` after `vkCmdEndRenderPass`). `r_rtxDemo` 0: extensions only. |
11+
| **Vulkan RTX** | 🔶 Demo path | With `USE_VULKAN_RTX=ON` and `r_rtx`>0 (latched): device enables KHR AS + ray-tracing pipeline + BDA. `r_rtxDemo` 1 (default): world BSP BLAS (SF_FACE + SF_TRIANGLES, capped by latched `r_rtxWorldPrimCap`) when a map is loaded, else a fallback triangle; raygen uses depth + `invViewProj` UBO; trace after main/post-bloom, blit into resolved color (depth briefly transitioned to read-only on main pass). `r_rtxDemo` 0: extensions only. |
1212
| **Metal** | ❌ Not started | Native Apple Silicon / macOS |
1313
| **DXR** | ❌ Not started | DirectX 12 + DirectX Raytracing (Windows) |
1414

docs/TODO_TRIAGE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ TODOs/FIXMEs in `src/external/` are from third-party code (duktape, zstd, cjson,
6262
| r_renderMode 1/2 | tr_init.c | Deferred / alternate-pipeline placeholders (`r_renderMode`); not wired to Vulkan **optional** Forward+ (`r_forwardPlus`). Real deferred still needs G-buffers, etc. Documented in cvar description. |
6363
| r_hdr 3 64-bit output | `vk_post_process_pipeline.c`, HDR format helpers | Infrastructure in place (vk_hdr64_active, _hdr64 modules, pipeline selection). glslangValidator rejects dvec4/f64vec4 fragment shader outputs. Falls back to RGBA32F. When glslang adds support, compile HDR64 variants and return RGBA64F from get_hdr_format. |
6464
| Vegetation wind draw | `vk_vegetation_wind.c` + draw path | Compute **dispatch** now runs **after** each `SURF_VEGETATION` tess batch (staging was previously uploaded *after* the misplaced `vk_begin_frame` dispatch, so GPU saw 0 verts). **Vertex shader still does not read** `vegwind_vertex_buffer` - deformed positions are not yet applied on draw. |
65-
| Vulkan RTX | CMake `USE_VULKAN_RTX`, `vk_rtx.c`, `r_rtx` / `r_rtxDemo` | Demo: triangle BLAS/TLAS + trace + blit when `r_rtxDemo` 1. World BSP / entity TLAS and real lighting still TODO. See `docs/RENDERERS_FUTURE.md`. |
65+
| Vulkan RTX | CMake `USE_VULKAN_RTX`, `vk_rtx.c` / `vk_rtx_world.c`, `r_rtx` / `r_rtxDemo` / `r_rtxWorldPrimCap` | Demo: world BSP BLAS (capped) + trace + blit when `r_rtxDemo` 1; entity TLAS and real lighting still TODO. See `docs/RENDERERS_FUTURE.md`. |
6666

6767
## Subsystem audit log (rolling)
6868

src/renderers/vulkan/shaders/glsl/rtx_demo.rchit

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ layout(location = 0) rayPayloadInEXT vec3 hitValue;
55

66
void main()
77
{
8-
hitValue = vec3( 0.15, 0.85, 0.25 );
8+
/* Simple diffuse-style albedo for BSP hits (no texture fetch yet). */
9+
hitValue = vec3( 0.72, 0.70, 0.66 );
910
}

src/renderers/vulkan/shaders/glsl/rtx_demo.rgen

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,37 @@ layout(location = 0) rayPayloadEXT vec3 hitValue;
66
layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;
77
layout(set = 0, binding = 1, rgba16f) uniform writeonly image2D outImage;
88

9+
layout(set = 0, binding = 2, std140) uniform RtxFrame {
10+
mat4 invViewProj;
11+
vec4 viewOrigin;
12+
vec4 zNearFar; /* x=zNear, y=zFar */
13+
vec4 outputSize; /* xy = width,height in pixels; zw unused */
14+
} rtx;
15+
16+
layout(set = 0, binding = 3) uniform sampler2D depthTex;
17+
918
void main()
1019
{
11-
const vec3 origin = vec3( 0.0, 0.0, -5.0 );
12-
const vec3 direction = vec3( 0.0, 0.0, 1.0 );
13-
traceRayEXT( topLevelAS, gl_RayFlagsOpaqueEXT, 0xFFu, 0u, 0u, 0u, origin, 0.001, direction, 100.0, 0 );
20+
vec2 pix = vec2( gl_LaunchIDEXT.xy ) + vec2( 0.5 );
21+
vec2 uv = pix / max( rtx.outputSize.xy, vec2( 1.0 ) );
22+
float d = textureLod( depthTex, uv, 0.0 ).r;
23+
24+
vec3 ro = rtx.viewOrigin.xyz;
25+
vec3 rd;
26+
27+
if ( d <= 0.0 || d >= 1.0 ) {
28+
/* Sky / void: shoot along forward from clip center ray */
29+
vec4 farClip = vec4( uv * 2.0 - 1.0, 0.0, 1.0 );
30+
vec4 farW = rtx.invViewProj * farClip;
31+
farW /= max( abs( farW.w ), 1e-6 );
32+
rd = normalize( farW.xyz - ro );
33+
} else {
34+
vec4 clip = vec4( uv * 2.0 - 1.0, d, 1.0 );
35+
vec4 worldPos = rtx.invViewProj * clip;
36+
worldPos /= max( abs( worldPos.w ), 1e-6 );
37+
rd = normalize( worldPos.xyz - ro );
38+
}
39+
40+
traceRayEXT( topLevelAS, gl_RayFlagsOpaqueEXT, 0xFFu, 0u, 0u, 0u, ro, 0.01, rd, 1.0e5, 0 );
1441
imageStore( outImage, ivec2( gl_LaunchIDEXT.xy ), vec4( hitValue, 1.0 ) );
1542
}

src/renderers/vulkan/shaders/glsl/rtx_demo.rmiss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ layout(location = 0) rayPayloadInEXT vec3 hitValue;
55

66
void main()
77
{
8-
hitValue = vec3( 0.95, 0.15, 0.15 );
8+
/* Sky tint */
9+
hitValue = vec3( 0.35, 0.52, 0.85 );
910
}

src/renderers/vulkan/tr_init.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ cvar_t *r_taa_feedbackMotion;
202202
cvar_t *r_taa_sharpen;
203203
cvar_t *r_rtx;
204204
cvar_t *r_rtxDemo;
205+
cvar_t *r_rtxWorldPrimCap;
205206
cvar_t *r_forwardPlus;
206207
cvar_t *r_forwardPlusMaxPerTile;
207208
cvar_t *r_forwardPlusDebug;
@@ -3471,7 +3472,10 @@ static void R_Register( void )
34713472
ri.Cvar_SetDescription( r_rtx, "Ray tracing (0=off, 1=shadows, 2=reflections, 3=full). When built with USE_VULKAN_RTX and set >0 before vid_restart, enables KHR ray tracing device extensions. See r_rtxDemo and docs/RENDERERS_FUTURE.md." );
34723473
r_rtxDemo = ri.Cvar_Get( "r_rtxDemo", "1", CVAR_ARCHIVE_ND | CVAR_LATCH );
34733474
ri.Cvar_CheckRange( r_rtxDemo, "0", "1", CV_INTEGER );
3474-
ri.Cvar_SetDescription( r_rtxDemo, "When USE_VULKAN_RTX and r_rtx>0: 1=build demo triangle TLAS and composite trace into scene color each frame; 0=extensions only (no demo GPU work)." );
3475+
ri.Cvar_SetDescription( r_rtxDemo, "When USE_VULKAN_RTX and r_rtx>0: 1=world BSP ray trace + composite each frame; 0=extensions only (no demo GPU work)." );
3476+
r_rtxWorldPrimCap = ri.Cvar_Get( "r_rtxWorldPrimCap", "262144", CVAR_ARCHIVE_ND | CVAR_LATCH );
3477+
ri.Cvar_CheckRange( r_rtxWorldPrimCap, "4096", "1048576", CV_INTEGER );
3478+
ri.Cvar_SetDescription( r_rtxWorldPrimCap, "Max triangles packed into the RTX world BLAS (latched). Lower on huge maps if BLAS build fails." );
34753479
r_forwardPlus = ri.Cvar_Get( "r_forwardPlus", "0", CVAR_ARCHIVE_ND | CVAR_LATCH );
34763480
ri.Cvar_CheckRange( r_forwardPlus, "0", "1", CV_INTEGER );
34773481
ri.Cvar_SetDescription( r_forwardPlus, "Forward+ scaffolding: GPU light SSBO + per-tile cull compute (16px tiles; max per tile from \\r_forwardPlusMaxPerTile, default 8). Packs at most MAX_DLIGHTS (32) so indices match tess.dlightBits. PBR: \\r_forwardPlusDebug (overlay), \\r_forwardPlusShade (experimental additive lights); see docs/RENDERER_2026_ARCHITECTURE_PASS.md." );

src/renderers/vulkan/tr_local.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,6 +1593,7 @@ extern cvar_t *r_taa_feedbackMotion;
15931593
extern cvar_t *r_taa_sharpen;
15941594
extern cvar_t *r_rtx;
15951595
extern cvar_t *r_rtxDemo;
1596+
extern cvar_t *r_rtxWorldPrimCap;
15961597
extern cvar_t *r_forwardPlus;
15971598
extern cvar_t *r_forwardPlusMaxPerTile;
15981599
extern cvar_t *r_forwardPlusDebug;

src/renderers/vulkan/vk_render_pass.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ void vk_end_render_pass_tracked( void )
128128

129129
#ifdef USE_VULKAN_RTX
130130
if ( vk.rtxAvailable && vk.fboActive && r_rtx && r_rtx->integer > 0 &&
131+
r_rtxDemo && r_rtxDemo->integer &&
131132
( vk.renderPassIndex == RENDER_PASS_MAIN || vk.renderPassIndex == RENDER_PASS_POST_BLOOM ) ) {
132133
vk_rtx_record_demo_pass( vk.cmd->command_buffer );
133134
}

0 commit comments

Comments
 (0)