From 3b1d28500629b8488863aeaba3203ad5c3118d5f Mon Sep 17 00:00:00 2001 From: skal Date: Sat, 7 Feb 2026 18:50:40 +0100 Subject: feat(gpu): Systematize post-process bindings and enable vertex shader uniforms - Add PP_BINDING_* macros for standard post-process bind group layout - PP_BINDING_SAMPLER (0): Input texture sampler - PP_BINDING_TEXTURE (1): Input texture from previous pass - PP_BINDING_UNIFORMS (2): Custom uniforms buffer - Change uniforms visibility from Fragment-only to Vertex|Fragment - Enables dynamic geometry in vertex shaders (e.g., peak meter bar) - Replace all hardcoded binding numbers with macros in post_process_helper.cc - Update test_demo.cc to use systematic bindings - Benefits: All post-process effects can now access uniforms in vertex shaders Result: More flexible post-process effects, better code maintainability --- src/test_demo.cc | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) (limited to 'src/test_demo.cc') diff --git a/src/test_demo.cc b/src/test_demo.cc index 9635f88..491968c 100644 --- a/src/test_demo.cc +++ b/src/test_demo.cc @@ -23,6 +23,7 @@ class PeakMeterEffect : public PostProcessEffect { public: PeakMeterEffect(const GpuContext& ctx) : PostProcessEffect(ctx) { + // Use standard post-process binding macros const char* shader_code = R"( struct VertexOutput { @builtin(position) position: vec4, @@ -43,6 +44,7 @@ class PeakMeterEffect : public PostProcessEffect { @vertex fn vs_main(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput { var output: VertexOutput; + // Full-screen triangle (required for post-process pass-through) var pos = array, 3>( vec2(-1.0, -1.0), vec2(3.0, -1.0), @@ -55,30 +57,23 @@ class PeakMeterEffect : public PostProcessEffect { @fragment fn fs_main(input: VertexOutput) -> @location(0) vec4 { - let color = textureSample(inputTexture, inputSampler, input.uv); - - // Draw red horizontal bar in middle of screen - // Bar height: 5% of screen height - // Bar width: proportional to peak_value (0.0 to 1.0) - let bar_height = 0.05; - let bar_center_y = 0.5; - let bar_y_min = bar_center_y - bar_height * 0.5; - let bar_y_max = bar_center_y + bar_height * 0.5; - - // Bar extends from left (0.0) to peak_value position - let bar_x_max = uniforms.peak_value; - - // Check if current pixel is inside the bar + // Bar dimensions + let bar_y_min = 0.005; + let bar_y_max = 0.015; + let bar_x_min = 0.015; + let bar_x_max = 0.250; let in_bar_y = input.uv.y >= bar_y_min && input.uv.y <= bar_y_max; - let in_bar_x = input.uv.x <= bar_x_max; + let in_bar_x = input.uv.x >= bar_x_min && input.uv.x <= bar_x_max; + // Optimization: Return bar color early (avoids texture sampling for ~5% of pixels) if (in_bar_y && in_bar_x) { - // Red bar - return vec4(1.0, 0.0, 0.0, 1.0); - } else { - // Original color - return color; + let uv_x = (input.uv.x - bar_x_min) / (bar_x_max - bar_x_min); + let factor = step(uv_x, uniforms.peak_value); + return mix(vec4(0.0, 0.0, 0.0, 1.0), vec4(1.0, 0.0, 0.0,1.0), factor); } + + // Pass through input texture for rest of screen + return textureSample(inputTexture, inputSampler, input.uv); } )"; @@ -102,7 +97,7 @@ class PeakMeterEffect : public PostProcessEffect { wgpuRenderPassEncoderSetPipeline(pass, pipeline_); wgpuRenderPassEncoderSetBindGroup(pass, 0, bind_group_, 0, nullptr); - wgpuRenderPassEncoderDraw(pass, 3, 1, 0, 0); + wgpuRenderPassEncoderDraw(pass, 3, 1, 0, 0); // Full-screen triangle } }; @@ -316,7 +311,9 @@ int main(int argc, char** argv) { if (peak_log) { if (log_peaks_fine) { // Log every frame for fine-grained analysis - fprintf(peak_log, "%d %.6f %.6f %d\n", frame_number, audio_time, raw_peak, beat_number); + // Use platform_get_time() for high-resolution timestamps (not audio_time which advances in chunks) + const double frame_time = platform_get_time(); + fprintf(peak_log, "%d %.6f %.6f %d\n", frame_number, frame_time, raw_peak, beat_number); } else if (beat_number != last_beat_logged) { // Log only at beat boundaries fprintf(peak_log, "%d %.6f %.6f\n", beat_number, audio_time, raw_peak); @@ -350,7 +347,6 @@ int main(int argc, char** argv) { printf("Peak log written to '%s'\n", log_peaks_file); } #endif - audio_shutdown(); gpu_shutdown(); platform_shutdown(&platform_state); -- cgit v1.2.3