diff options
| author | skal <pascal.massimino@gmail.com> | 2026-05-21 08:10:47 +0200 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-05-21 08:10:47 +0200 |
| commit | d806027dcaeadcdd8d2febd88bc46b2fd2c465de (patch) | |
| tree | 30bc1ef9f40ccab7c00e31ee20e62bb86755fa26 /src | |
| parent | 680042a18c11ad5e58757e45b260745c2f52417f (diff) | |
Diffstat (limited to 'src')
49 files changed, 493 insertions, 369 deletions
diff --git a/src/3d/object.h b/src/3d/object.h index e2cd15a..eb1125c 100644 --- a/src/3d/object.h +++ b/src/3d/object.h @@ -9,7 +9,7 @@ #include <memory> // For std::shared_ptr enum class ObjectType { - CUBE, // Legacy alias for BOX (value 0, kept for binary scene compat) + CUBE, // Legacy alias for BOX (value 0, kept for binary scene compat) SPHERE, PLANE, TORUS, diff --git a/src/3d/physics.cc b/src/3d/physics.cc index 788246f..592428b 100644 --- a/src/3d/physics.cc +++ b/src/3d/physics.cc @@ -16,7 +16,8 @@ float PhysicsSystem::sample_sdf(const Object3D& obj, vec3 world_p) { float d = 1000.0f; if (obj.type == ObjectType::SPHERE) { d = q.len() - 1.0f; - } else if (obj.type == ObjectType::BOX || obj.type == ObjectType::CUBE) { // CUBE is legacy alias + } else if (obj.type == ObjectType::BOX || + obj.type == ObjectType::CUBE) { // CUBE is legacy alias d = sdf::sdBox(q, vec3(1.0f, 1.0f, 1.0f)); } else if (obj.type == ObjectType::TORUS) { d = sdf::sdTorus(q, vec2(1.0f, 0.4f)); diff --git a/src/3d/renderer.h b/src/3d/renderer.h index 21192f3..5a9a065 100644 --- a/src/3d/renderer.h +++ b/src/3d/renderer.h @@ -80,7 +80,9 @@ class Renderer3D { // Call before init(). When true, renders directly to surface (no post-process // Y-flip): uses standard perspective (Y not negated) and CCW winding. - void set_direct_render(bool v) { direct_render_ = v; } + void set_direct_render(bool v) { + direct_render_ = v; + } struct MeshGpuData { WGPUBuffer vertex_buffer; @@ -124,7 +126,8 @@ class Renderer3D { BVH cpu_bvh_; // Keep a CPU-side copy for building/uploading bool bvh_enabled_ = true; - bool direct_render_ = false; // true = render to surface (no post-process flip) + bool direct_render_ = + false; // true = render to surface (no post-process flip) bool bind_group_dirty_ = true; // Recreate bind group when textures change std::map<AssetId, MeshGpuData> mesh_cache_; diff --git a/src/3d/renderer_draw.cc b/src/3d/renderer_draw.cc index 929f261..bd7e994 100644 --- a/src/3d/renderer_draw.cc +++ b/src/3d/renderer_draw.cc @@ -10,11 +10,11 @@ void Renderer3D::update_uniforms(const Scene& scene, const Camera& camera, float time) { mat4 proj = camera.get_projection_matrix(); - if (direct_render_) proj.m[5] = -proj.m[5]; // undo Y-negate for direct surface + if (direct_render_) + proj.m[5] = -proj.m[5]; // undo Y-negate for direct surface const mat4 vp = proj * camera.get_view_matrix(); const GlobalUniforms globals = GlobalUniforms::make( - vp, - vec4(camera.position.x, camera.position.y, camera.position.z, time), + vp, vec4(camera.position.x, camera.position.y, camera.position.z, time), vec4((float)std::min((size_t)kMaxObjects, scene.objects.size()), 0.0f, 0.0f, 0.0f), vec2((float)width_, (float)height_)); @@ -26,13 +26,25 @@ void Renderer3D::update_uniforms(const Scene& scene, const Camera& camera, for (const auto& obj : scene.objects) { float type_id = 0.0f; switch (obj.type) { - case ObjectType::SPHERE: type_id = 1.0f; break; - case ObjectType::CUBE: // fallthrough (legacy alias for BOX) - case ObjectType::BOX: type_id = 2.0f; break; - case ObjectType::TORUS: type_id = 3.0f; break; - case ObjectType::PLANE: type_id = 4.0f; break; - case ObjectType::MESH: type_id = 5.0f; break; - default: type_id = 0.0f; break; + case ObjectType::SPHERE: + type_id = 1.0f; + break; + case ObjectType::CUBE: // fallthrough (legacy alias for BOX) + case ObjectType::BOX: + type_id = 2.0f; + break; + case ObjectType::TORUS: + type_id = 3.0f; + break; + case ObjectType::PLANE: + type_id = 4.0f; + break; + case ObjectType::MESH: + type_id = 5.0f; + break; + default: + type_id = 0.0f; + break; } float plane_distance = 0.0f; @@ -69,68 +81,69 @@ void Renderer3D::draw(WGPURenderPassEncoder pass, const Scene& scene, } else { bind_group_dirty_ = false; - if (bind_group_) - wgpuBindGroupRelease(bind_group_); + if (bind_group_) + wgpuBindGroupRelease(bind_group_); - std::vector<WGPUBindGroupEntry> bg_entries; + std::vector<WGPUBindGroupEntry> bg_entries; - { - WGPUBindGroupEntry e = {}; - e.binding = 0; - e.buffer = global_uniform_buffer_; - e.size = sizeof(GlobalUniforms); - bg_entries.push_back(e); - } + { + WGPUBindGroupEntry e = {}; + e.binding = 0; + e.buffer = global_uniform_buffer_; + e.size = sizeof(GlobalUniforms); + bg_entries.push_back(e); + } - { - WGPUBindGroupEntry e = {}; - e.binding = 1; - e.buffer = object_storage_buffer_; - e.size = sizeof(ObjectData) * kMaxObjects; - bg_entries.push_back(e); - } + { + WGPUBindGroupEntry e = {}; + e.binding = 1; + e.buffer = object_storage_buffer_; + e.size = sizeof(ObjectData) * kMaxObjects; + bg_entries.push_back(e); + } - if (bvh_enabled_) { - WGPUBindGroupEntry e = {}; - e.binding = 2; - e.buffer = bvh_storage_buffer_; - e.size = sizeof(BVHNode) * kMaxObjects * 2; - bg_entries.push_back(e); - } + if (bvh_enabled_) { + WGPUBindGroupEntry e = {}; + e.binding = 2; + e.buffer = bvh_storage_buffer_; + e.size = sizeof(BVHNode) * kMaxObjects * 2; + bg_entries.push_back(e); + } - { - WGPUBindGroupEntry e = {}; - e.binding = 3; - e.textureView = noise_texture_view_; - bg_entries.push_back(e); - } + { + WGPUBindGroupEntry e = {}; + e.binding = 3; + e.textureView = noise_texture_view_; + bg_entries.push_back(e); + } - { - WGPUBindGroupEntry e = {}; - e.binding = 4; - e.sampler = default_sampler_; - bg_entries.push_back(e); - } + { + WGPUBindGroupEntry e = {}; + e.binding = 4; + e.sampler = default_sampler_; + bg_entries.push_back(e); + } - { - WGPUBindGroupEntry e = {}; - e.binding = 5; - e.textureView = sky_texture_view_ ? sky_texture_view_ : noise_texture_view_; - bg_entries.push_back(e); - } + { + WGPUBindGroupEntry e = {}; + e.binding = 5; + e.textureView = + sky_texture_view_ ? sky_texture_view_ : noise_texture_view_; + bg_entries.push_back(e); + } - WGPURenderPipeline cp = bvh_enabled_ ? pipeline_ : pipeline_no_bvh_; - WGPUBindGroupLayout current_layout = - wgpuRenderPipelineGetBindGroupLayout(cp, 0); + WGPURenderPipeline cp = bvh_enabled_ ? pipeline_ : pipeline_no_bvh_; + WGPUBindGroupLayout current_layout = + wgpuRenderPipelineGetBindGroupLayout(cp, 0); - WGPUBindGroupDescriptor bg_desc = {}; - bg_desc.layout = current_layout; - bg_desc.entryCount = (uint32_t)bg_entries.size(); - bg_desc.entries = bg_entries.data(); + WGPUBindGroupDescriptor bg_desc = {}; + bg_desc.layout = current_layout; + bg_desc.entryCount = (uint32_t)bg_entries.size(); + bg_desc.entries = bg_entries.data(); - bind_group_ = wgpuDeviceCreateBindGroup(device_, &bg_desc); + bind_group_ = wgpuDeviceCreateBindGroup(device_, &bg_desc); - wgpuBindGroupLayoutRelease(current_layout); + wgpuBindGroupLayoutRelease(current_layout); } // end dirty block WGPURenderPipeline current_pipeline = @@ -208,7 +221,8 @@ void Renderer3D::draw(WGPURenderPassEncoder pass, const Scene& scene, } mat4 dbg_proj = camera.get_projection_matrix(); - if (direct_render_) dbg_proj.m[5] = -dbg_proj.m[5]; + if (direct_render_) + dbg_proj.m[5] = -dbg_proj.m[5]; mat4 view_proj = dbg_proj * camera.get_view_matrix(); visual_debug_.render(pass, view_proj); } diff --git a/src/3d/renderer_pipelines.cc b/src/3d/renderer_pipelines.cc index 195baad..9e1e2fb 100644 --- a/src/3d/renderer_pipelines.cc +++ b/src/3d/renderer_pipelines.cc @@ -253,8 +253,8 @@ void Renderer3D::create_mesh_pipeline() { pipeline_desc.vertex.buffers = &vert_buffer_layout; pipeline_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; pipeline_desc.primitive.cullMode = WGPUCullMode_Back; - // CW winding compensates for Y-negation in perspective() (post-process chain). - // Direct-to-surface rendering uses standard CCW winding. + // CW winding compensates for Y-negation in perspective() (post-process + // chain). Direct-to-surface rendering uses standard CCW winding. pipeline_desc.primitive.frontFace = direct_render_ ? WGPUFrontFace_CCW : WGPUFrontFace_CW; pipeline_desc.multisample.count = 1; diff --git a/src/3d/scene_loader.cc b/src/3d/scene_loader.cc index d5c1879..d27cc16 100644 --- a/src/3d/scene_loader.cc +++ b/src/3d/scene_loader.cc @@ -64,26 +64,40 @@ bool LoadScene(Scene& scene, const uint8_t* data, size_t size) { if (offset + 12 + 16 + 12 + 16 > size) return false; // Transforms + Color - float px = read_f32(data + offset); offset += 4; - float py = read_f32(data + offset); offset += 4; - float pz = read_f32(data + offset); offset += 4; + float px = read_f32(data + offset); + offset += 4; + float py = read_f32(data + offset); + offset += 4; + float pz = read_f32(data + offset); + offset += 4; vec3 pos(px, py, pz); - float rx = read_f32(data + offset); offset += 4; - float ry = read_f32(data + offset); offset += 4; - float rz = read_f32(data + offset); offset += 4; - float rw = read_f32(data + offset); offset += 4; + float rx = read_f32(data + offset); + offset += 4; + float ry = read_f32(data + offset); + offset += 4; + float rz = read_f32(data + offset); + offset += 4; + float rw = read_f32(data + offset); + offset += 4; quat rot(rx, ry, rz, rw); - float sx = read_f32(data + offset); offset += 4; - float sy = read_f32(data + offset); offset += 4; - float sz = read_f32(data + offset); offset += 4; + float sx = read_f32(data + offset); + offset += 4; + float sy = read_f32(data + offset); + offset += 4; + float sz = read_f32(data + offset); + offset += 4; vec3 scale(sx, sy, sz); - float cr = read_f32(data + offset); offset += 4; - float cg = read_f32(data + offset); offset += 4; - float cb = read_f32(data + offset); offset += 4; - float ca = read_f32(data + offset); offset += 4; + float cr = read_f32(data + offset); + offset += 4; + float cg = read_f32(data + offset); + offset += 4; + float cb = read_f32(data + offset); + offset += 4; + float ca = read_f32(data + offset); + offset += 4; vec4 color(cr, cg, cb, ca); // Plane Distance (if type == PLANE) @@ -127,9 +141,12 @@ bool LoadScene(Scene& scene, const uint8_t* data, size_t size) { // Physics properties if (offset + 4 + 4 + 4 > size) return false; - float mass = read_f32(data + offset); offset += 4; - float restitution = read_f32(data + offset); offset += 4; - uint32_t is_static_u32 = read_u32(data + offset); offset += 4; + float mass = read_f32(data + offset); + offset += 4; + float restitution = read_f32(data + offset); + offset += 4; + uint32_t is_static_u32 = read_u32(data + offset); + offset += 4; bool is_static = (is_static_u32 != 0); // Create Object3D diff --git a/src/audio/audio_engine.cc b/src/audio/audio_engine.cc index 1d6659d..3033882 100644 --- a/src/audio/audio_engine.cc +++ b/src/audio/audio_engine.cc @@ -170,7 +170,8 @@ void AudioEngine::seek(float target_time) { // 1. Reset synth state (clear all active voices) synth_init(); - // 2. Re-init tracker: re-registers all spectrograms with now-clean synth slots + // 2. Re-init tracker: re-registers all spectrograms with now-clean synth + // slots resource_mgr_.reset(); ::tracker_init(&resource_mgr_); diff --git a/src/audio/backend/miniaudio_backend.cc b/src/audio/backend/miniaudio_backend.cc index 8871d10..e591c72 100644 --- a/src/audio/backend/miniaudio_backend.cc +++ b/src/audio/backend/miniaudio_backend.cc @@ -286,7 +286,7 @@ float MiniaudioBackend::get_realtime_peak() { } void MiniaudioBackend::get_callback_state(double* out_time, - int64_t* out_samples) { + int64_t* out_samples) { *out_time = last_callback_time_.load(std::memory_order_acquire); *out_samples = last_callback_samples_.load(std::memory_order_acquire); } diff --git a/src/audio/backend/miniaudio_backend.h b/src/audio/backend/miniaudio_backend.h index 01fa790..c959f2b 100644 --- a/src/audio/backend/miniaudio_backend.h +++ b/src/audio/backend/miniaudio_backend.h @@ -36,7 +36,8 @@ class MiniaudioBackend : public AudioBackend { static std::atomic<float> realtime_peak_; // Smooth playback time interpolation (updated in callback) - static std::atomic<double> last_callback_time_; // Absolute CLOCK_MONOTONIC time + static std::atomic<double> + last_callback_time_; // Absolute CLOCK_MONOTONIC time static std::atomic<int64_t> last_callback_samples_; // Static callback required by miniaudio C API diff --git a/src/audio/gen.cc b/src/audio/gen.cc index 9d18517..723a9cb 100644 --- a/src/audio/gen.cc +++ b/src/audio/gen.cc @@ -12,7 +12,8 @@ std::vector<float> generate_note_spectrogram(const NoteParams& params, int* out_num_frames) { - int num_frames = (int)(params.duration_sec * RING_BUFFER_SAMPLE_RATE / DCT_SIZE); + int num_frames = + (int)(params.duration_sec * RING_BUFFER_SAMPLE_RATE / DCT_SIZE); if (num_frames < 1) num_frames = 1; *out_num_frames = num_frames; diff --git a/src/audio/ola.h b/src/audio/ola.h index 1fb2a4a..33ec674 100644 --- a/src/audio/ola.h +++ b/src/audio/ola.h @@ -21,6 +21,6 @@ void ola_decode(const float* spec, int num_frames, float* pcm); // Single-frame OLA-IDCT decoder. // spec_frame: single DCT_SIZE spectral frame. -// overlap: OLA_OVERLAP buffer (read/write). Must be zero-initialized for first frame. -// out_hop: OLA_HOP_SIZE buffer for the resulting time-domain samples. +// overlap: OLA_OVERLAP buffer (read/write). Must be zero-initialized for first +// frame. out_hop: OLA_HOP_SIZE buffer for the resulting time-domain samples. void ola_decode_frame(const float* spec_frame, float* overlap, float* out_hop); diff --git a/src/audio/synth.cc b/src/audio/synth.cc index d584c62..57972cc 100644 --- a/src/audio/synth.cc +++ b/src/audio/synth.cc @@ -110,8 +110,8 @@ int synth_register_spectrogram(const Spectrogram* spec) { for (int i = 0; i < MAX_SPECTROGRAMS; ++i) { if (!g_synth_data.spectrogram_registered[i]) { g_synth_data.spectrograms[i] = *spec; - g_synth_data.active_spectrogram_data[i].store( - spec->spectral_data_a, std::memory_order_release); + g_synth_data.active_spectrogram_data[i].store(spec->spectral_data_a, + std::memory_order_release); g_synth_data.spectrogram_registered[i] = true; return i; } @@ -184,9 +184,8 @@ void synth_trigger_voice(int spectrogram_id, float volume, float pan, volume, spectrogram_id); } if (pan < -1.0f || pan > 1.0f) { - DEBUG_SYNTH( - "[SYNTH WARNING] Invalid pan=%.2f for spectrogram_id=%d\n", - pan, spectrogram_id); + DEBUG_SYNTH("[SYNTH WARNING] Invalid pan=%.2f for spectrogram_id=%d\n", pan, + spectrogram_id); } if (start_offset_samples < 0) { DEBUG_SYNTH("[SYNTH WARNING] Negative start_offset=%d, clamping to 0\n", diff --git a/src/audio/tracker.cc b/src/audio/tracker.cc index e634333..f9657e9 100644 --- a/src/audio/tracker.cc +++ b/src/audio/tracker.cc @@ -176,7 +176,8 @@ void tracker_update(double music_time_sec, double dt_music_sec) { const TrackerPatternTrigger& trigger = g_tracker_score.triggers[g_last_trigger_idx]; - const double trigger_time_sec = (double)trigger.unit_time * unit_duration_sec; + const double trigger_time_sec = + (double)trigger.unit_time * unit_duration_sec; if (trigger_time_sec > end_music_time) break; @@ -214,8 +215,8 @@ void tracker_update(double music_time_sec, double dt_music_sec) { // Offset = (music_time_delta / tempo_scale) * sample_rate int sample_offset = 0; if (event_music_time > music_time_sec) { - sample_offset = (int)((event_music_time - music_time_sec) / tempo_scale * - (double)RING_BUFFER_SAMPLE_RATE); + sample_offset = (int)((event_music_time - music_time_sec) / + tempo_scale * (double)RING_BUFFER_SAMPLE_RATE); } // Apply humanization if enabled @@ -230,9 +231,10 @@ void tracker_update(double music_time_sec, double dt_music_sec) { // Timing variation: jitter by % of beat duration if (g_tracker_score.timing_variation_pct > 0.0f) { double beat_sec = 60.0 / (double)g_tracker_score.bpm; - double jitter = dist(rng) * - (double)(g_tracker_score.timing_variation_pct / 100.0f) * - beat_sec; + double jitter = + dist(rng) * + (double)(g_tracker_score.timing_variation_pct / 100.0f) * + beat_sec; sample_offset += (int)(jitter / tempo_scale * (double)RING_BUFFER_SAMPLE_RATE); } @@ -240,7 +242,8 @@ void tracker_update(double music_time_sec, double dt_music_sec) { // Volume variation: vary by % if (g_tracker_score.volume_variation_pct > 0.0f) { volume_mult += - (float)(dist(rng) * (double)(g_tracker_score.volume_variation_pct / 100.0f)); + (float)(dist(rng) * + (double)(g_tracker_score.volume_variation_pct / 100.0f)); } } @@ -250,7 +253,8 @@ void tracker_update(double music_time_sec, double dt_music_sec) { // Pattern remains active until full duration elapses const double pattern_end_time = - active.start_music_time + (double)pattern.unit_length * unit_duration_sec; + active.start_music_time + + (double)pattern.unit_length * unit_duration_sec; if (pattern_end_time <= end_music_time) { active.active = false; } diff --git a/src/effects/flash_effect.h b/src/effects/flash_effect.h index 1cfe1ee..1871186 100644 --- a/src/effects/flash_effect.h +++ b/src/effects/flash_effect.h @@ -9,5 +9,6 @@ struct Flash : public WgslEffect { const std::vector<std::string>& outputs, float start_time, float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, - flash_shader_wgsl) {} + flash_shader_wgsl) { + } }; diff --git a/src/effects/gaussian_blur_effect.h b/src/effects/gaussian_blur_effect.h index 0c528c5..43d0120 100644 --- a/src/effects/gaussian_blur_effect.h +++ b/src/effects/gaussian_blur_effect.h @@ -11,5 +11,6 @@ struct GaussianBlur : public WgslEffect { float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, gaussian_blur_shader_wgsl, WGPULoadOp_Clear, - WgslEffectParams{{8.0f, 0.5f, 1.0f, 0.0f}, {}}) {} + WgslEffectParams{{8.0f, 0.5f, 1.0f, 0.0f}, {}}) { + } }; diff --git a/src/effects/heptagon_effect.h b/src/effects/heptagon_effect.h index 3762202..ff1be46 100644 --- a/src/effects/heptagon_effect.h +++ b/src/effects/heptagon_effect.h @@ -9,5 +9,6 @@ struct Heptagon : public WgslEffect { const std::vector<std::string>& outputs, float start_time, float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, - heptagon_shader_wgsl) {} + heptagon_shader_wgsl) { + } }; diff --git a/src/effects/ntsc_effect.h b/src/effects/ntsc_effect.h index 4737291..b975c4d 100644 --- a/src/effects/ntsc_effect.h +++ b/src/effects/ntsc_effect.h @@ -9,14 +9,17 @@ struct Ntsc : public WgslEffect { const std::vector<std::string>& outputs, float start_time, float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, - ntsc_rgb_shader_wgsl) {} + ntsc_rgb_shader_wgsl) { + } }; -// YIQ input: input texture already stores luma/chroma/phase (e.g. RotatingCube output). +// YIQ input: input texture already stores luma/chroma/phase (e.g. RotatingCube +// output). struct NtscYiq : public WgslEffect { NtscYiq(const GpuContext& ctx, const std::vector<std::string>& inputs, const std::vector<std::string>& outputs, float start_time, float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, - ntsc_yiq_shader_wgsl) {} + ntsc_yiq_shader_wgsl) { + } }; diff --git a/src/effects/passthrough_effect.h b/src/effects/passthrough_effect.h index 285663f..9137b48 100644 --- a/src/effects/passthrough_effect.h +++ b/src/effects/passthrough_effect.h @@ -9,5 +9,6 @@ struct Passthrough : public WgslEffect { const std::vector<std::string>& outputs, float start_time, float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, - passthrough_shader_wgsl) {} + passthrough_shader_wgsl) { + } }; diff --git a/src/effects/peak_meter_effect.cc b/src/effects/peak_meter_effect.cc index 8956e32..6c6e8fd 100644 --- a/src/effects/peak_meter_effect.cc +++ b/src/effects/peak_meter_effect.cc @@ -67,9 +67,8 @@ void PeakMeter::render(WGPUCommandEncoder encoder, WGPUTextureView input_view = nodes.get_view(input_nodes_[0]); WGPUTextureView output_view = nodes.get_view(output_nodes_[0]); - pp_update_bind_group(ctx_.device, pipeline_.get(), - bind_group_.get_address(), input_view, - uniforms_buffer_.get(), {nullptr, 0}); + pp_update_bind_group(ctx_.device, pipeline_.get(), bind_group_.get_address(), + input_view, uniforms_buffer_.get(), {nullptr, 0}); run_fullscreen_pass(encoder, pipeline_.get(), bind_group_.get(), output_view, WGPULoadOp_Load); diff --git a/src/effects/rotating_cube_effect.cc b/src/effects/rotating_cube_effect.cc index 000d177..ec587b5 100644 --- a/src/effects/rotating_cube_effect.cc +++ b/src/effects/rotating_cube_effect.cc @@ -44,7 +44,8 @@ RotatingCube::RotatingCube(const GpuContext& ctx, wgpuDeviceCreatePipelineLayout(ctx_.device, &pl_desc); // Load shader - const std::string composed = ShaderComposer::Get().Compose({}, rotating_cube_wgsl); + const std::string composed = + ShaderComposer::Get().Compose({}, rotating_cube_wgsl); WGPUShaderSourceWGSL wgsl_src = {}; wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL; wgsl_src.code = str_view(composed.c_str()); @@ -78,7 +79,7 @@ RotatingCube::RotatingCube(const GpuContext& ctx, pipeline_desc.vertex.entryPoint = str_view("vs_main"); pipeline_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; pipeline_desc.primitive.cullMode = WGPUCullMode_Back; - pipeline_desc.primitive.frontFace = WGPUFrontFace_CW; // Y-flipped perspective + pipeline_desc.primitive.frontFace = WGPUFrontFace_CW; // Y-flipped perspective pipeline_desc.depthStencil = &depth_stencil; pipeline_desc.multisample.count = 1; pipeline_desc.multisample.mask = 0xFFFFFFFF; @@ -136,8 +137,7 @@ void RotatingCube::render(WGPUCommandEncoder encoder, // Update uniforms const Uniforms uniforms = Uniforms::make( - view_proj, - vec4(camera_pos.x, camera_pos.y, camera_pos.z, params.time), + view_proj, vec4(camera_pos.x, camera_pos.y, camera_pos.z, params.time), vec4(1.0f, 0.0f, 0.0f, 0.0f), params.resolution, params.aspect_ratio); const ObjectData obj_data = { diff --git a/src/effects/scene2_effect.h b/src/effects/scene2_effect.h index 0e26fc3..1ede2e7 100644 --- a/src/effects/scene2_effect.h +++ b/src/effects/scene2_effect.h @@ -13,5 +13,6 @@ struct Scene2Effect : public WgslEffect { float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, scene2_shader_wgsl, WGPULoadOp_Clear, {}, - WgslSamplerType::Nearest) {} + WgslSamplerType::Nearest) { + } }; diff --git a/src/effects/scratch_effect.h b/src/effects/scratch_effect.h index 6c0e0cb..dc67118 100644 --- a/src/effects/scratch_effect.h +++ b/src/effects/scratch_effect.h @@ -9,5 +9,6 @@ struct Scratch : public WgslEffect { const std::vector<std::string>& outputs, float start_time, float end_time) : WgslEffect(ctx, inputs, outputs, start_time, end_time, - scratch_shader_wgsl) {} + scratch_shader_wgsl) { + } }; diff --git a/src/effects/shaders.cc b/src/effects/shaders.cc index 7ca66fa..a099bf4 100644 --- a/src/effects/shaders.cc +++ b/src/effects/shaders.cc @@ -51,7 +51,7 @@ void InitShaderComposer() { register_if_exists("ray_box", AssetId::ASSET_SHADER_RAY_BOX); register_if_exists("ray_triangle", AssetId::ASSET_SHADER_RAY_TRIANGLE); - register_if_exists("ray_sphere", AssetId::ASSET_SHADER_RAY_SPHERE); + register_if_exists("ray_sphere", AssetId::ASSET_SHADER_RAY_SPHERE); register_if_exists("debug/debug_print", AssetId::ASSET_SHADER_DEBUG_DEBUG_PRINT); @@ -73,12 +73,13 @@ void InitShaderComposer() { register_if_exists("render/raymarching_id", AssetId::ASSET_SHADER_RENDER_RAYMARCHING_ID); // CNN v3 inference snippets - register_if_exists("cnn_v3/common", AssetId::ASSET_SHADER_CNN_V3_COMMON); - register_if_exists("cnn_v3/enc0", AssetId::ASSET_SHADER_CNN_V3_ENC0); - register_if_exists("cnn_v3/enc1", AssetId::ASSET_SHADER_CNN_V3_ENC1); - register_if_exists("cnn_v3/bottleneck", AssetId::ASSET_SHADER_CNN_V3_BOTTLENECK); - register_if_exists("cnn_v3/dec1", AssetId::ASSET_SHADER_CNN_V3_DEC1); - register_if_exists("cnn_v3/dec0", AssetId::ASSET_SHADER_CNN_V3_DEC0); + register_if_exists("cnn_v3/common", AssetId::ASSET_SHADER_CNN_V3_COMMON); + register_if_exists("cnn_v3/enc0", AssetId::ASSET_SHADER_CNN_V3_ENC0); + register_if_exists("cnn_v3/enc1", AssetId::ASSET_SHADER_CNN_V3_ENC1); + register_if_exists("cnn_v3/bottleneck", + AssetId::ASSET_SHADER_CNN_V3_BOTTLENECK); + register_if_exists("cnn_v3/dec1", AssetId::ASSET_SHADER_CNN_V3_DEC1); + register_if_exists("cnn_v3/dec0", AssetId::ASSET_SHADER_CNN_V3_DEC0); // CNN shaders (workspace-specific) // register_if_exists("cnn_activation", AssetId::ASSET_SHADER_CNN_ACTIVATION); @@ -119,16 +120,18 @@ const char* scene2_shader_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_SCENE2); const char* scratch_shader_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_SCRATCH); const char* ntsc_rgb_shader_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_NTSC_RGB); const char* ntsc_yiq_shader_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_NTSC_YIQ); -const char* gbuf_raster_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_RASTER); -const char* gbuf_pack_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_PACK); -const char* gbuf_shadow_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_SHADOW); -const char* gbuf_view_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_VIEW); -const char* gbuf_deferred_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_DEFERRED); -const char* cnn_v3_enc0_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_ENC0); -const char* cnn_v3_enc1_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_ENC1); -const char* cnn_v3_bottleneck_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_BOTTLENECK); -const char* cnn_v3_dec1_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_DEC1); -const char* cnn_v3_dec0_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_DEC0); +const char* gbuf_raster_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_RASTER); +const char* gbuf_pack_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_PACK); +const char* gbuf_shadow_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_SHADOW); +const char* gbuf_view_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_GBUF_VIEW); +const char* gbuf_deferred_wgsl = + SafeGetAsset(AssetId::ASSET_SHADER_GBUF_DEFERRED); +const char* cnn_v3_enc0_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_ENC0); +const char* cnn_v3_enc1_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_ENC1); +const char* cnn_v3_bottleneck_wgsl = + SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_BOTTLENECK); +const char* cnn_v3_dec1_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_DEC1); +const char* cnn_v3_dec0_wgsl = SafeGetAsset(AssetId::ASSET_SHADER_CNN_V3_DEC0); // Compute shaders const char* gen_noise_compute_wgsl = diff --git a/src/gpu/demo_effects.h b/src/gpu/demo_effects.h index 1f859bc..d67478e 100644 --- a/src/gpu/demo_effects.h +++ b/src/gpu/demo_effects.h @@ -22,6 +22,7 @@ #include "effects/gaussian_blur_effect.h" #include "effects/heptagon_effect.h" #include "effects/hybrid3_d_effect.h" +#include "effects/ntsc_effect.h" #include "effects/particles_effect.h" #include "effects/passthrough_effect.h" #include "effects/peak_meter_effect.h" @@ -30,12 +31,11 @@ #include "effects/scene1_effect.h" #include "effects/scene2_effect.h" #include "effects/scratch_effect.h" -#include "effects/ntsc_effect.h" // CNN v3 G-buffer + inference + debug view -#include "../../cnn_v3/src/gbuffer_effect.h" #include "../../cnn_v3/src/cnn_v3_effect.h" -#include "../../cnn_v3/src/gbuf_view_effect.h" #include "../../cnn_v3/src/gbuf_deferred_effect.h" +#include "../../cnn_v3/src/gbuf_view_effect.h" +#include "../../cnn_v3/src/gbuffer_effect.h" #include <memory> diff --git a/src/gpu/effect.cc b/src/gpu/effect.cc index 2e93a11..d761b2d 100644 --- a/src/gpu/effect.cc +++ b/src/gpu/effect.cc @@ -59,8 +59,8 @@ void Effect::blit_input_to_output(WGPUCommandEncoder encoder, &extent); } -std::string Effect::find_downstream_output( - const std::vector<EffectDAGNode>& dag) const { +std::string +Effect::find_downstream_output(const std::vector<EffectDAGNode>& dag) const { for (const auto& node : dag) { for (const auto& in : node.input_nodes) { for (const auto& out : output_nodes_) { diff --git a/src/gpu/effect.h b/src/gpu/effect.h index 47dd3c2..4c9b157 100644 --- a/src/gpu/effect.h +++ b/src/gpu/effect.h @@ -77,7 +77,8 @@ class Effect { // Returns output_nodes[0] of the first effect in |dag| whose input_nodes // intersect this effect's output_nodes_ (i.e. the first direct downstream // consumer). Returns "" if no such effect exists or it has no outputs. - std::string find_downstream_output(const std::vector<EffectDAGNode>& dag) const; + std::string + find_downstream_output(const std::vector<EffectDAGNode>& dag) const; // Helper: Run a fullscreen triangle pass (pipeline + bind_group → output) static void run_fullscreen_pass(WGPUCommandEncoder encoder, diff --git a/src/gpu/gpu.cc b/src/gpu/gpu.cc index f5f1515..3200655 100644 --- a/src/gpu/gpu.cc +++ b/src/gpu/gpu.cc @@ -138,14 +138,18 @@ WGPUShaderModule gpu_create_shader_module(WGPUDevice device, } WGPUSampler gpu_create_linear_sampler(WGPUDevice device) { - WGPUSampler s = SamplerCache::Get().get_or_create(device, SamplerCache::clamp()); - if (s) wgpuSamplerAddRef(s); // Caller owns a reference (for RAII wrappers) + WGPUSampler s = + SamplerCache::Get().get_or_create(device, SamplerCache::clamp()); + if (s) + wgpuSamplerAddRef(s); // Caller owns a reference (for RAII wrappers) return s; } WGPUSampler gpu_create_nearest_sampler(WGPUDevice device) { - WGPUSampler s = SamplerCache::Get().get_or_create(device, SamplerCache::nearest()); - if (s) wgpuSamplerAddRef(s); // Caller owns a reference (for RAII wrappers) + WGPUSampler s = + SamplerCache::Get().get_or_create(device, SamplerCache::nearest()); + if (s) + wgpuSamplerAddRef(s); // Caller owns a reference (for RAII wrappers) return s; } @@ -170,8 +174,8 @@ RenderPass gpu_create_render_pass(WGPUDevice device, WGPUTextureFormat format, // Compose shader to resolve #include directives std::string composed_shader = ShaderComposer::Get().Compose({}, shader_code); - WGPUShaderModule shader_module = - gpu_create_shader_module(device, composed_shader.c_str(), "render_shader"); + WGPUShaderModule shader_module = gpu_create_shader_module( + device, composed_shader.c_str(), "render_shader"); // Create Bind Group Layout & Bind Group std::vector<WGPUBindGroupLayoutEntry> bgl_entries; @@ -268,8 +272,8 @@ ComputePass gpu_create_compute_pass(WGPUDevice device, const char* shader_code, // Compose shader to resolve #include directives std::string composed_shader = ShaderComposer::Get().Compose({}, shader_code); - WGPUShaderModule shader_module = - gpu_create_shader_module(device, composed_shader.c_str(), "compute_shader"); + WGPUShaderModule shader_module = gpu_create_shader_module( + device, composed_shader.c_str(), "compute_shader"); std::vector<WGPUBindGroupLayoutEntry> bgl_entries; std::vector<WGPUBindGroupEntry> bg_entries; @@ -379,7 +383,7 @@ void gpu_init(PlatformState* platform_state) { // Exclude GL backend: wgpu's WGL pixel-format selection panics under Wine. WGPUInstanceExtras win_extras = {}; win_extras.chain.sType = (WGPUSType)WGPUSType_InstanceExtras; - win_extras.backends = WGPUInstanceBackend_Primary; // Vulkan + DX12, no GL + win_extras.backends = WGPUInstanceBackend_Primary; // Vulkan + DX12, no GL WGPUInstanceDescriptor win_desc = {}; win_desc.nextInChain = (WGPUChainedStruct*)&win_extras; g_instance = wgpuCreateInstance(&win_desc); @@ -435,7 +439,6 @@ void gpu_init(PlatformState* platform_state) { wgpuSurfaceConfigure(g_surface, &g_config); InitShaderComposer(); - } void gpu_resize(int width, int height) { diff --git a/src/gpu/pipeline_builder.cc b/src/gpu/pipeline_builder.cc index acd2ae9..03eb9dd 100644 --- a/src/gpu/pipeline_builder.cc +++ b/src/gpu/pipeline_builder.cc @@ -16,8 +16,8 @@ RenderPipelineBuilder& RenderPipelineBuilder::shader(const char* wgsl, shader_text_ = compose ? ShaderComposer::Get().Compose({}, wgsl) : wgsl; if (device_ == nullptr) return *this; - shader_module_ = - gpu_create_shader_module(device_, shader_text_.c_str(), "pipeline_shader"); + shader_module_ = gpu_create_shader_module(device_, shader_text_.c_str(), + "pipeline_shader"); desc_.vertex.module = shader_module_; desc_.vertex.entryPoint = str_view("vs_main"); return *this; diff --git a/src/gpu/post_process_helper.cc b/src/gpu/post_process_helper.cc index 871a238..8e5bae2 100644 --- a/src/gpu/post_process_helper.cc +++ b/src/gpu/post_process_helper.cc @@ -40,8 +40,8 @@ WGPURenderPipeline create_post_process_pipeline(WGPUDevice device, } // NOTE: create_post_process_pipeline_simple() was removed (zero callers). -// If a 3-binding pipeline is needed in the future, add a `bool use_effect_params` -// parameter to create_post_process_pipeline() instead. +// If a 3-binding pipeline is needed in the future, add a `bool +// use_effect_params` parameter to create_post_process_pipeline() instead. // Example: // WGPURenderPipeline p = create_post_process_pipeline(device, format, code); // // Then pass {nullptr, 0} as effect_params to pp_update_bind_group — diff --git a/src/gpu/post_process_helper.h b/src/gpu/post_process_helper.h index 8f2bd21..645ac4f 100644 --- a/src/gpu/post_process_helper.h +++ b/src/gpu/post_process_helper.h @@ -21,6 +21,7 @@ void pp_update_bind_group(WGPUDevice device, WGPURenderPipeline pipeline, WGPUBindGroup* bind_group, WGPUTextureView input_view, GpuBuffer uniforms, GpuBuffer effect_params); -// Upload a mat4 to a GPU buffer, transposing from C++ row-major to WGSL column-major. +// Upload a mat4 to a GPU buffer, transposing from C++ row-major to WGSL +// column-major. void gpu_upload_mat4(WGPUQueue queue, WGPUBuffer buffer, size_t offset, const mat4& m); diff --git a/src/gpu/sequence.cc b/src/gpu/sequence.cc index c81a912..f0e0356 100644 --- a/src/gpu/sequence.cc +++ b/src/gpu/sequence.cc @@ -226,10 +226,10 @@ void NodeRegistry::create_texture(Node& node) { view_desc.mipLevelCount = 1; view_desc.baseArrayLayer = 0; view_desc.arrayLayerCount = 1; - view_desc.aspect = (node.type == NodeType::DEPTH24 || - node.type == NodeType::GBUF_DEPTH32) - ? WGPUTextureAspect_DepthOnly - : WGPUTextureAspect_All; + view_desc.aspect = + (node.type == NodeType::DEPTH24 || node.type == NodeType::GBUF_DEPTH32) + ? WGPUTextureAspect_DepthOnly + : WGPUTextureAspect_All; node.view = wgpuTextureCreateView(node.texture, &view_desc); FATAL_CHECK(node.view != nullptr, "Failed to create texture view\n"); diff --git a/src/gpu/sequence.h b/src/gpu/sequence.h index 51c8af1..ee0260d 100644 --- a/src/gpu/sequence.h +++ b/src/gpu/sequence.h @@ -19,9 +19,11 @@ enum class NodeType { DEPTH24, COMPUTE_F32, // G-buffer types for CNN v3 - GBUF_ALBEDO, // rgba16float: RENDER_ATTACHMENT | TEXTURE_BINDING | STORAGE_BINDING | COPY_SRC - GBUF_DEPTH32, // depth32float: RENDER_ATTACHMENT | TEXTURE_BINDING | COPY_SRC - GBUF_R8, // rgba8unorm (4ch for compat): STORAGE_BINDING | TEXTURE_BINDING | RENDER_ATTACHMENT + GBUF_ALBEDO, // rgba16float: RENDER_ATTACHMENT | TEXTURE_BINDING | + // STORAGE_BINDING | COPY_SRC + GBUF_DEPTH32, // depth32float: RENDER_ATTACHMENT | TEXTURE_BINDING | COPY_SRC + GBUF_R8, // rgba8unorm (4ch for compat): STORAGE_BINDING | TEXTURE_BINDING | + // RENDER_ATTACHMENT GBUF_RGBA32UINT, // rgba32uint: STORAGE_BINDING | TEXTURE_BINDING }; @@ -69,8 +71,12 @@ class NodeRegistry { void set_external_view(const std::string& name, WGPUTextureView view); - int default_width() const { return default_width_; } - int default_height() const { return default_height_; } + int default_width() const { + return default_width_; + } + int default_height() const { + return default_height_; + } private: WGPUDevice device_; diff --git a/src/gpu/texture_manager.cc b/src/gpu/texture_manager.cc index 20e215d..9e42841 100644 --- a/src/gpu/texture_manager.cc +++ b/src/gpu/texture_manager.cc @@ -285,10 +285,12 @@ void TextureManager::dispatch_compute(const std::string& func_name, wgpuTextureViewRelease(target_view); } -void TextureManager::create_gpu_procedural( - const std::string& name, const std::string& func_name, - const char* shader_code, const GpuProceduralParams& params, - const void* uniform_data, size_t uniform_size) { +void TextureManager::create_gpu_procedural(const std::string& name, + const std::string& func_name, + const char* shader_code, + const GpuProceduralParams& params, + const void* uniform_data, + size_t uniform_size) { get_or_create_compute_pipeline(func_name, shader_code, uniform_size); TextureWithView tv = gpu_create_storage_texture_2d( diff --git a/src/gpu/wgsl_effect.cc b/src/gpu/wgsl_effect.cc index 4f658a5..4c5f7e2 100644 --- a/src/gpu/wgsl_effect.cc +++ b/src/gpu/wgsl_effect.cc @@ -13,8 +13,7 @@ WgslEffect::WgslEffect(const GpuContext& ctx, WgslEffectParams initial_params, WgslSamplerType sampler_type) : Effect(ctx, inputs, outputs, start_time, end_time), - effect_params(initial_params), - load_op_(load_op) { + effect_params(initial_params), load_op_(load_op) { HEADLESS_RETURN_IF_NULL(ctx_.device); if (sampler_type == WgslSamplerType::Nearest) @@ -23,9 +22,8 @@ WgslEffect::WgslEffect(const GpuContext& ctx, create_linear_sampler(); params_buffer_.init(ctx_.device); - pipeline_.set(create_post_process_pipeline(ctx_.device, - WGPUTextureFormat_RGBA8Unorm, - shader_code)); + pipeline_.set(create_post_process_pipeline( + ctx_.device, WGPUTextureFormat_RGBA8Unorm, shader_code)); } void WgslEffect::render(WGPUCommandEncoder encoder, diff --git a/src/gpu/wgsl_effect.h b/src/gpu/wgsl_effect.h index f487ef7..49e97c5 100644 --- a/src/gpu/wgsl_effect.h +++ b/src/gpu/wgsl_effect.h @@ -11,12 +11,16 @@ // effect_params.p — 4 generic floats (strength, scale, etc.) // effect_params.c — color or secondary vec4 struct WgslEffectParams { - float p[4]; // vec4: generic float params - float c[4]; // vec4: color / secondary params + float p[4]; // vec4: generic float params + float c[4]; // vec4: color / secondary params }; -static_assert(sizeof(WgslEffectParams) == 32, "WgslEffectParams must be 32 bytes"); +static_assert(sizeof(WgslEffectParams) == 32, + "WgslEffectParams must be 32 bytes"); -enum class WgslSamplerType { Linear, Nearest }; +enum class WgslSamplerType { + Linear, + Nearest +}; class WgslEffect : public Effect { public: diff --git a/src/platform/stub_types.h b/src/platform/stub_types.h index 6cef8c7..850f5b8 100644 --- a/src/platform/stub_types.h +++ b/src/platform/stub_types.h @@ -163,5 +163,4 @@ static inline void platform_wgpu_wait_any(WGPUInstance) { #define WGPUOptionalBool_True true #define WGPUOptionalBool_False false - #endif // STRIP_EXTERNAL_LIBS diff --git a/src/procedural/generator.cc b/src/procedural/generator.cc index a2a383b..ee2dcc0 100644 --- a/src/procedural/generator.cc +++ b/src/procedural/generator.cc @@ -211,9 +211,18 @@ bool gen_plasma(uint8_t* buffer, int w, int h, const float* params, const float kTau = 6.2832f; const float kPhase = 2.0944f; // 2*pi/3 const int idx = (y * w + x) * 4; - buffer[idx + 0] = (uint8_t)(fminf(fmaxf(sinf(v * kTau) * 0.5f + 0.5f, 0.0f), 1.0f) * 255.0f); - buffer[idx + 1] = (uint8_t)(fminf(fmaxf(sinf(v * kTau + kPhase) * 0.5f + 0.5f, 0.0f), 1.0f) * 255.0f); - buffer[idx + 2] = (uint8_t)(fminf(fmaxf(sinf(v * kTau + 2.0f * kPhase) * 0.5f + 0.5f, 0.0f), 1.0f) * 255.0f); + buffer[idx + 0] = + (uint8_t)(fminf(fmaxf(sinf(v * kTau) * 0.5f + 0.5f, 0.0f), 1.0f) * + 255.0f); + buffer[idx + 1] = + (uint8_t)(fminf(fmaxf(sinf(v * kTau + kPhase) * 0.5f + 0.5f, 0.0f), + 1.0f) * + 255.0f); + buffer[idx + 2] = + (uint8_t)(fminf(fmaxf(sinf(v * kTau + 2.0f * kPhase) * 0.5f + 0.5f, + 0.0f), + 1.0f) * + 255.0f); buffer[idx + 3] = 255; } } @@ -247,15 +256,22 @@ bool gen_voronoi(uint8_t* buffer, int w, int h, const float* params, const float ddy = py - fy; const float dist2 = ddx * ddx + ddy * ddy; - if (dist2 < f1) { f2 = f1; f1 = dist2; } - else if (dist2 < f2) { f2 = dist2; } + if (dist2 < f1) { + f2 = f1; + f1 = dist2; + } else if (dist2 < f2) { + f2 = dist2; + } } } float value; - if (mode == 0) value = sqrtf(f1) * 1.5f; - else if (mode == 1) value = sqrtf(f2) * 1.2f; - else value = (sqrtf(f2) - sqrtf(f1)) * 3.0f; + if (mode == 0) + value = sqrtf(f1) * 1.5f; + else if (mode == 1) + value = sqrtf(f2) * 1.2f; + else + value = (sqrtf(f2) - sqrtf(f1)) * 3.0f; value = fminf(fmaxf(value, 0.0f), 1.0f); const uint8_t uval = (uint8_t)(value * 255.0f); @@ -305,7 +321,11 @@ bool gen_normalmap(uint8_t* buffer, int w, int h, const float* params, // Test-only: Failing generator bool gen_fail(uint8_t* buffer, int w, int h, const float* params, int num_params) { - (void)buffer; (void)w; (void)h; (void)params; (void)num_params; + (void)buffer; + (void)w; + (void)h; + (void)params; + (void)num_params; return false; } #endif diff --git a/src/tests/3d/test_3d_render.cc b/src/tests/3d/test_3d_render.cc index ef799ec..3a440be 100644 --- a/src/tests/3d/test_3d_render.cc +++ b/src/tests/3d/test_3d_render.cc @@ -105,7 +105,8 @@ bool gen_periodic_noise(uint8_t* buffer, int w, int h, const float* params, // Wrapper: fBm noise → normal map bool gen_fbm_normalmap(uint8_t* buffer, int w, int h, const float* params, int num_params) { - (void)params; (void)num_params; + (void)params; + (void)num_params; float fbm_params[] = {0.0f, 4.0f, 1.0f, 0.5f, 5.0f}; if (!procedural::gen_perlin(buffer, w, h, fbm_params, 5)) return false; @@ -140,7 +141,8 @@ int main(int argc, char** argv) { InitShaderComposer(); - g_renderer.set_direct_render(true); // Renders to surface, no post-process flip + g_renderer.set_direct_render( + true); // Renders to surface, no post-process flip g_renderer.init(g_device, g_queue, g_format); g_renderer.resize(platform_state.width, platform_state.height); diff --git a/src/tests/audio/test_fft.cc b/src/tests/audio/test_fft.cc index 2d47aa0..a34d203 100644 --- a/src/tests/audio/test_fft.cc +++ b/src/tests/audio/test_fft.cc @@ -39,7 +39,7 @@ static void idct_reference(const float* input, float* output, size_t N) { // Reference direct DFT matching fft_forward convention (e^{+j} sign). // fft_radix2 with direction=+1 computes X[k] = sum x[n] * e^{+j*2*pi*k*n/N}. static void dft_reference(const float* real_in, const float* imag_in, - float* real_out, float* imag_out, size_t N) { + float* real_out, float* imag_out, size_t N) { const float PI = 3.14159265358979323846f; for (size_t k = 0; k < N; k++) { real_out[k] = 0.0f; @@ -68,7 +68,8 @@ static bool arrays_match(const float* a, const float* b, size_t N, // Test B: fft_forward small N=4 — all 4 unit impulses vs direct DFT static void test_b_fft_radix2_small_n() { - printf("Test B: fft_forward N=4 (unit impulses vs direct DFT, tol=1e-5)...\n"); + printf( + "Test B: fft_forward N=4 (unit impulses vs direct DFT, tol=1e-5)...\n"); const size_t N = 4; const float tolerance = 1e-5f; @@ -117,8 +118,7 @@ static void test_c_twiddle_accumulation() { if (k >= 128 && k < 256) { const float wr_direct = cosf(angle * (float)k); const float wi_direct = sinf(angle * (float)k); - const float err = - fabsf(wr_iter - wr_direct) + fabsf(wi_iter - wi_direct); + const float err = fabsf(wr_iter - wr_direct) + fabsf(wi_iter - wi_direct); if (err > max_err) { max_err = err; max_err_k = k; @@ -129,9 +129,8 @@ static void test_c_twiddle_accumulation() { wi_iter = wr_old * wi_delta + wi_iter * wr_delta; } - printf( - " ✓ iterative twiddle drift at k=128..255: max_err=%.2e at k=%zu\n", - (double)max_err, max_err_k); + printf(" ✓ iterative twiddle drift at k=128..255: max_err=%.2e at k=%zu\n", + (double)max_err, max_err_k); printf(" ✓ fixed code uses cosf/sinf directly — no accumulation\n"); printf("Test C: PASSED ✓\n\n"); } @@ -279,7 +278,8 @@ static void test_idct_correctness() { assert(arrays_match(output_ref, output_fft, N)); printf(" ✓ Single bin test passed\n"); - // Mixed spectrum: IDCT→DCT round-trip (dct_fft and idct_fft are mutual inverses) + // Mixed spectrum: IDCT→DCT round-trip (dct_fft and idct_fft are mutual + // inverses) for (size_t i = 0; i < N; i++) { input[i] = sinf(i * 0.1f) * cosf(i * 0.05f) + cosf(i * 0.03f); } diff --git a/src/tests/gpu/test_cnn_v3_parity.cc b/src/tests/gpu/test_cnn_v3_parity.cc index 4fada5d..9663b09 100644 --- a/src/tests/gpu/test_cnn_v3_parity.cc +++ b/src/tests/gpu/test_cnn_v3_parity.cc @@ -4,10 +4,10 @@ // 2. Random-weight test: output must match Python-generated test vectors // (within 1/255 per pixel) +#include "../../cnn_v3/test_vectors.h" #include "../common/webgpu_test_fixture.h" #include "cnn_v3/src/cnn_v3_effect.h" #include "gpu/sequence.h" -#include "../../cnn_v3/test_vectors.h" #include <cassert> #include <cmath> @@ -20,37 +20,46 @@ static float fp16_bits_to_f32(uint16_t h) { uint32_t sign = (h & 0x8000u) << 16; - uint32_t exp = (h & 0x7C00u) >> 10; + uint32_t exp = (h & 0x7C00u) >> 10; uint32_t mant = (h & 0x03FFu); if (exp == 0 && mant == 0) { - float r; uint32_t b = sign; __builtin_memcpy(&r, &b, 4); return r; + float r; + uint32_t b = sign; + __builtin_memcpy(&r, &b, 4); + return r; } if (exp == 31) { uint32_t b = sign | 0x7F800000u | (mant << 13); - float r; __builtin_memcpy(&r, &b, 4); return r; + float r; + __builtin_memcpy(&r, &b, 4); + return r; } uint32_t b = sign | ((exp + 112) << 23) | (mant << 13); - float r; __builtin_memcpy(&r, &b, 4); return r; + float r; + __builtin_memcpy(&r, &b, 4); + return r; } // --------------------------------------------------------------------------- // Raw RGBA16Float readback → flat array of f32 (one per channel per pixel) // --------------------------------------------------------------------------- -struct MapState { bool done = false; WGPUMapAsyncStatus status; }; +struct MapState { + bool done = false; + WGPUMapAsyncStatus status; +}; static std::vector<float> readback_rgba16float(WGPUDevice device, - WGPUQueue queue, - WGPUTexture tex, - int W, int H) { - const uint32_t bytes_per_px = 8; // 4 × f16 - const uint32_t unaligned_bpr = (uint32_t)(W * bytes_per_px); - const uint32_t aligned_bpr = ((unaligned_bpr + 255u) / 256u) * 256u; - const size_t buf_size = aligned_bpr * (size_t)H; + WGPUQueue queue, WGPUTexture tex, + int W, int H) { + const uint32_t bytes_per_px = 8; // 4 × f16 + const uint32_t unaligned_bpr = (uint32_t)(W * bytes_per_px); + const uint32_t aligned_bpr = ((unaligned_bpr + 255u) / 256u) * 256u; + const size_t buf_size = aligned_bpr * (size_t)H; WGPUBufferDescriptor bd = {}; bd.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_MapRead; - bd.size = buf_size; + bd.size = buf_size; WGPUBuffer staging = wgpuDeviceCreateBuffer(device, &bd); WGPUCommandEncoder enc = wgpuDeviceCreateCommandEncoder(device, nullptr); @@ -58,9 +67,9 @@ static std::vector<float> readback_rgba16float(WGPUDevice device, src.texture = tex; WGPUTexelCopyBufferInfo dst = {}; dst.buffer = staging; - dst.layout.bytesPerRow = aligned_bpr; + dst.layout.bytesPerRow = aligned_bpr; dst.layout.rowsPerImage = (uint32_t)H; - WGPUExtent3D extent = { (uint32_t)W, (uint32_t)H, 1 }; + WGPUExtent3D extent = {(uint32_t)W, (uint32_t)H, 1}; wgpuCommandEncoderCopyTextureToBuffer(enc, &src, &dst, &extent); WGPUCommandBuffer cmds = wgpuCommandEncoderFinish(enc, nullptr); wgpuQueueSubmit(queue, 1, &cmds); @@ -73,7 +82,8 @@ static std::vector<float> readback_rgba16float(WGPUDevice device, mi.mode = WGPUCallbackMode_AllowProcessEvents; mi.callback = [](WGPUMapAsyncStatus s, WGPUStringView, void* u, void*) { auto* st = (MapState*)u; - st->status = s; st->done = true; + st->status = s; + st->done = true; }; mi.userdata1 = &ms; wgpuBufferMapAsync(staging, WGPUMapMode_Read, 0, buf_size, mi); @@ -82,16 +92,15 @@ static std::vector<float> readback_rgba16float(WGPUDevice device, std::vector<float> result(W * H * 4, 0.0f); if (ms.done && ms.status == WGPUMapAsyncStatus_Success) { - const uint8_t* mapped = (const uint8_t*)wgpuBufferGetConstMappedRange( - staging, 0, buf_size); + const uint8_t* mapped = + (const uint8_t*)wgpuBufferGetConstMappedRange(staging, 0, buf_size); if (mapped) { for (int y = 0; y < H; ++y) { const uint16_t* row = (const uint16_t*)(mapped + (size_t)y * aligned_bpr); for (int x = 0; x < W; ++x) { for (int c = 0; c < 4; ++c) { - result[(y * W + x) * 4 + c] = - fp16_bits_to_f32(row[x * 4 + c]); + result[(y * W + x) * 4 + c] = fp16_bits_to_f32(row[x * 4 + c]); } } } @@ -107,17 +116,17 @@ static std::vector<float> readback_rgba16float(WGPUDevice device, // --------------------------------------------------------------------------- static std::vector<float> readback_rgba32uint_8ch(WGPUDevice device, - WGPUQueue queue, - WGPUTexture tex, - int W, int H) { - const uint32_t bytes_per_px = 16; // 4 × u32 - const uint32_t unaligned_bpr = (uint32_t)(W * bytes_per_px); - const uint32_t aligned_bpr = ((unaligned_bpr + 255u) / 256u) * 256u; - const size_t buf_size = aligned_bpr * (size_t)H; + WGPUQueue queue, + WGPUTexture tex, int W, + int H) { + const uint32_t bytes_per_px = 16; // 4 × u32 + const uint32_t unaligned_bpr = (uint32_t)(W * bytes_per_px); + const uint32_t aligned_bpr = ((unaligned_bpr + 255u) / 256u) * 256u; + const size_t buf_size = aligned_bpr * (size_t)H; WGPUBufferDescriptor bd = {}; bd.usage = WGPUBufferUsage_CopyDst | WGPUBufferUsage_MapRead; - bd.size = buf_size; + bd.size = buf_size; WGPUBuffer staging = wgpuDeviceCreateBuffer(device, &bd); WGPUCommandEncoder enc = wgpuDeviceCreateCommandEncoder(device, nullptr); @@ -125,9 +134,9 @@ static std::vector<float> readback_rgba32uint_8ch(WGPUDevice device, src.texture = tex; WGPUTexelCopyBufferInfo dst = {}; dst.buffer = staging; - dst.layout.bytesPerRow = aligned_bpr; + dst.layout.bytesPerRow = aligned_bpr; dst.layout.rowsPerImage = (uint32_t)H; - WGPUExtent3D extent = { (uint32_t)W, (uint32_t)H, 1 }; + WGPUExtent3D extent = {(uint32_t)W, (uint32_t)H, 1}; wgpuCommandEncoderCopyTextureToBuffer(enc, &src, &dst, &extent); WGPUCommandBuffer cmds = wgpuCommandEncoderFinish(enc, nullptr); wgpuQueueSubmit(queue, 1, &cmds); @@ -140,7 +149,8 @@ static std::vector<float> readback_rgba32uint_8ch(WGPUDevice device, mi.mode = WGPUCallbackMode_AllowProcessEvents; mi.callback = [](WGPUMapAsyncStatus s, WGPUStringView, void* u, void*) { auto* st = (MapState*)u; - st->status = s; st->done = true; + st->status = s; + st->done = true; }; mi.userdata1 = &ms; wgpuBufferMapAsync(staging, WGPUMapMode_Read, 0, buf_size, mi); @@ -149,8 +159,8 @@ static std::vector<float> readback_rgba32uint_8ch(WGPUDevice device, std::vector<float> result(W * H * 8, 0.0f); if (ms.done && ms.status == WGPUMapAsyncStatus_Success) { - const uint8_t* mapped = (const uint8_t*)wgpuBufferGetConstMappedRange( - staging, 0, buf_size); + const uint8_t* mapped = + (const uint8_t*)wgpuBufferGetConstMappedRange(staging, 0, buf_size); if (mapped) { for (int y = 0; y < H; ++y) { const uint32_t* row = @@ -178,31 +188,31 @@ static std::vector<float> readback_rgba32uint_8ch(WGPUDevice device, static WGPUTexture make_feat_tex(WGPUDevice dev, int W, int H) { WGPUTextureDescriptor d = {}; - d.format = WGPUTextureFormat_RGBA32Uint; - d.usage = WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst; - d.dimension = WGPUTextureDimension_2D; - d.size = { (uint32_t)W, (uint32_t)H, 1 }; + d.format = WGPUTextureFormat_RGBA32Uint; + d.usage = WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst; + d.dimension = WGPUTextureDimension_2D; + d.size = {(uint32_t)W, (uint32_t)H, 1}; d.mipLevelCount = 1; - d.sampleCount = 1; + d.sampleCount = 1; return wgpuDeviceCreateTexture(dev, &d); } static WGPUTexture make_output_tex(WGPUDevice dev, int W, int H) { WGPUTextureDescriptor d = {}; - d.format = WGPUTextureFormat_RGBA16Float; - d.usage = WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopySrc; - d.dimension = WGPUTextureDimension_2D; - d.size = { (uint32_t)W, (uint32_t)H, 1 }; + d.format = WGPUTextureFormat_RGBA16Float; + d.usage = WGPUTextureUsage_StorageBinding | WGPUTextureUsage_CopySrc; + d.dimension = WGPUTextureDimension_2D; + d.size = {(uint32_t)W, (uint32_t)H, 1}; d.mipLevelCount = 1; - d.sampleCount = 1; + d.sampleCount = 1; return wgpuDeviceCreateTexture(dev, &d); } static WGPUTextureView make_view(WGPUTexture tex, WGPUTextureFormat fmt) { WGPUTextureViewDescriptor d = {}; - d.format = fmt; - d.dimension = WGPUTextureViewDimension_2D; - d.mipLevelCount = 1; + d.format = fmt; + d.dimension = WGPUTextureViewDimension_2D; + d.mipLevelCount = 1; d.arrayLayerCount = 1; return wgpuTextureCreateView(tex, &d); } @@ -211,38 +221,36 @@ static WGPUTextureView make_view(WGPUTexture tex, WGPUTextureFormat fmt) { // Run one CNN v3 forward pass and return output pixels // --------------------------------------------------------------------------- -static std::vector<float> run_cnn_v3(WebGPUTestFixture& fixture, - int W, int H, - const uint32_t* feat0_u32, // W*H*4 - const uint32_t* feat1_u32, // W*H*4 - const uint32_t* weights_u32, // (TOTAL_F16+1)/2 - uint32_t weights_bytes, - std::vector<float>* enc0_out = nullptr, - std::vector<float>* dec1_out = nullptr) { +static std::vector<float> +run_cnn_v3(WebGPUTestFixture& fixture, int W, int H, + const uint32_t* feat0_u32, // W*H*4 + const uint32_t* feat1_u32, // W*H*4 + const uint32_t* weights_u32, // (TOTAL_F16+1)/2 + uint32_t weights_bytes, std::vector<float>* enc0_out = nullptr, + std::vector<float>* dec1_out = nullptr) { GpuContext ctx = fixture.ctx(); // Create input textures manually (with CopyDst for upload) WGPUTexture feat0_tex = make_feat_tex(ctx.device, W, H); WGPUTexture feat1_tex = make_feat_tex(ctx.device, W, H); - WGPUTexture out_tex = make_output_tex(ctx.device, W, H); + WGPUTexture out_tex = make_output_tex(ctx.device, W, H); WGPUTextureView feat0_view = make_view(feat0_tex, WGPUTextureFormat_RGBA32Uint); WGPUTextureView feat1_view = make_view(feat1_tex, WGPUTextureFormat_RGBA32Uint); - WGPUTextureView out_view = - make_view(out_tex, WGPUTextureFormat_RGBA16Float); + WGPUTextureView out_view = make_view(out_tex, WGPUTextureFormat_RGBA16Float); // Upload feat texture data auto upload_tex = [&](WGPUTexture tex, const uint32_t* data) { WGPUTexelCopyTextureInfo dst_tex = {}; dst_tex.texture = tex; WGPUTexelCopyBufferLayout layout = {}; - layout.bytesPerRow = (uint32_t)(W * 16); // 4 u32 per pixel + layout.bytesPerRow = (uint32_t)(W * 16); // 4 u32 per pixel layout.rowsPerImage = (uint32_t)H; - WGPUExtent3D ext = { (uint32_t)W, (uint32_t)H, 1 }; - wgpuQueueWriteTexture(ctx.queue, &dst_tex, data, - (size_t)(W * H * 16), &layout, &ext); + WGPUExtent3D ext = {(uint32_t)W, (uint32_t)H, 1}; + wgpuQueueWriteTexture(ctx.queue, &dst_tex, data, (size_t)(W * H * 16), + &layout, &ext); }; upload_tex(feat0_tex, feat0_u32); upload_tex(feat1_tex, feat1_u32); @@ -267,10 +275,9 @@ static std::vector<float> run_cnn_v3(WebGPUTestFixture& fixture, } // Run 5 compute passes - WGPUCommandEncoder enc = - wgpuDeviceCreateCommandEncoder(ctx.device, nullptr); + WGPUCommandEncoder enc = wgpuDeviceCreateCommandEncoder(ctx.device, nullptr); UniformsSequenceParams params = {}; - params.resolution = { (float)W, (float)H }; + params.resolution = {(float)W, (float)H}; params.aspect_ratio = 1.0f; effect.render(enc, params, registry); @@ -292,7 +299,8 @@ static std::vector<float> run_cnn_v3(WebGPUTestFixture& fixture, if (dec1_out) { // dec1 is rgba32uint, 8ch (pack2x16float), half-res WGPUTexture dec1_tex = registry.get_texture("cnn3_out_dec1"); - *dec1_out = readback_rgba32uint_8ch(ctx.device, ctx.queue, dec1_tex, W / 2, H / 2); + *dec1_out = + readback_rgba32uint_8ch(ctx.device, ctx.queue, dec1_tex, W / 2, H / 2); } // Cleanup @@ -326,9 +334,8 @@ static int test_zero_weights() { std::vector<uint32_t> feat0(W * H * 4, 0u); std::vector<uint32_t> feat1(W * H * 4, 0u); - auto pixels = run_cnn_v3(fixture, W, H, - feat0.data(), feat1.data(), - nullptr, 0); // null = zero weights (default) + auto pixels = run_cnn_v3(fixture, W, H, feat0.data(), feat1.data(), nullptr, + 0); // null = zero weights (default) // Expected: sigmoid(0) = 0.5 exactly const float expected = 0.5f; @@ -360,14 +367,12 @@ static int test_random_weights() { InitShaderComposer(); const int W = kCnnV3TestW, H = kCnnV3TestH; - const uint32_t weights_bytes = - (uint32_t)sizeof(kCnnV3TestWeightsU32); + const uint32_t weights_bytes = (uint32_t)sizeof(kCnnV3TestWeightsU32); std::vector<float> enc0_pixels, dec1_pixels; - auto pixels = run_cnn_v3(fixture, W, H, - kCnnV3TestFeat0U32, kCnnV3TestFeat1U32, - kCnnV3TestWeightsU32, weights_bytes, - &enc0_pixels, &dec1_pixels); + auto pixels = run_cnn_v3(fixture, W, H, kCnnV3TestFeat0U32, + kCnnV3TestFeat1U32, kCnnV3TestWeightsU32, + weights_bytes, &enc0_pixels, &dec1_pixels); // Check enc0 layer first (8ch, rgba32uint) const float tol = 1.0f / 255.0f; @@ -376,15 +381,18 @@ static int test_random_weights() { for (int i = 0; i < W * H * 8; ++i) { float ref = fp16_bits_to_f32(kCnnV3ExpectedEnc0U16[i]); float err = fabsf(enc0_pixels[i] - ref); - if (err > enc0_max_err) { enc0_max_err = err; enc0_worst = i; } + if (err > enc0_max_err) { + enc0_max_err = err; + enc0_worst = i; + } } bool enc0_ok = (enc0_max_err <= tol); if (!enc0_ok) { int px = enc0_worst / 8, ch = enc0_worst % 8; - fprintf(stderr, " ✗ enc0 mismatch: max_err=%.5f > %.5f at px=%d ch=%d" + fprintf(stderr, + " ✗ enc0 mismatch: max_err=%.5f > %.5f at px=%d ch=%d" " gpu=%.5f ref=%.5f\n", - enc0_max_err, tol, px, ch, - enc0_pixels[enc0_worst], + enc0_max_err, tol, px, ch, enc0_pixels[enc0_worst], fp16_bits_to_f32(kCnnV3ExpectedEnc0U16[enc0_worst])); } else { fprintf(stdout, " ✓ enc0: max_err=%.2e OK\n", enc0_max_err); @@ -397,15 +405,18 @@ static int test_random_weights() { for (int i = 0; i < dec1_n; ++i) { float ref = fp16_bits_to_f32(kCnnV3ExpectedDec1U16[i]); float err = fabsf(dec1_pixels[i] - ref); - if (err > dec1_max_err) { dec1_max_err = err; dec1_worst = i; } + if (err > dec1_max_err) { + dec1_max_err = err; + dec1_worst = i; + } } bool dec1_ok = (dec1_max_err <= tol); if (!dec1_ok) { int px = dec1_worst / 8, ch = dec1_worst % 8; - fprintf(stderr, " ✗ dec1 mismatch: max_err=%.5f > %.5f at px=%d ch=%d" + fprintf(stderr, + " ✗ dec1 mismatch: max_err=%.5f > %.5f at px=%d ch=%d" " gpu=%.5f ref=%.5f\n", - dec1_max_err, tol, px, ch, - dec1_pixels[dec1_worst], + dec1_max_err, tol, px, ch, dec1_pixels[dec1_worst], fp16_bits_to_f32(kCnnV3ExpectedDec1U16[dec1_worst])); } else { fprintf(stdout, " ✓ dec1: max_err=%.2e OK\n", dec1_max_err); @@ -418,16 +429,19 @@ static int test_random_weights() { for (int i = 0; i < n; ++i) { float ref = fp16_bits_to_f32(kCnnV3ExpectedOutputU16[i]); float err = fabsf(pixels[i] - ref); - if (err > max_err) { max_err = err; worst = i; } + if (err > max_err) { + max_err = err; + worst = i; + } } bool out_ok = (max_err <= tol); if (!out_ok) { int px = worst / 4, ch = worst % 4; - fprintf(stderr, " ✗ random_weights: max_err=%.5f > %.5f at px=%d ch=%d" + fprintf(stderr, + " ✗ random_weights: max_err=%.5f > %.5f at px=%d ch=%d" " gpu=%.5f ref=%.5f\n", - max_err, tol, px, ch, - pixels[worst], + max_err, tol, px, ch, pixels[worst], fp16_bits_to_f32(kCnnV3ExpectedOutputU16[worst])); } else { fprintf(stdout, " ✓ random_weights: max_err=%.2e OK\n", max_err); @@ -442,8 +456,10 @@ static int test_random_weights() { int main() { int pass = 0, total = 0; - ++total; pass += test_zero_weights(); - ++total; pass += test_random_weights(); + ++total; + pass += test_zero_weights(); + ++total; + pass += test_random_weights(); fprintf(stdout, "\nCNN v3 parity: %d/%d passed\n", pass, total); return (pass == total) ? 0 : 1; diff --git a/src/tests/gpu/test_demo_effects.cc b/src/tests/gpu/test_demo_effects.cc index 1bb89f9..fa1ac87 100644 --- a/src/tests/gpu/test_demo_effects.cc +++ b/src/tests/gpu/test_demo_effects.cc @@ -73,9 +73,9 @@ static void test_effects() { {"Scratch", std::make_shared<Scratch>( fixture.ctx(), std::vector<std::string>{"source"}, std::vector<std::string>{"sink"}, 0.0f, 1000.0f)}, - {"Ntsc", std::make_shared<Ntsc>( - fixture.ctx(), std::vector<std::string>{"source"}, - std::vector<std::string>{"sink"}, 0.0f, 1000.0f)}, + {"Ntsc", + std::make_shared<Ntsc>(fixture.ctx(), std::vector<std::string>{"source"}, + std::vector<std::string>{"sink"}, 0.0f, 1000.0f)}, {"NtscYiq", std::make_shared<NtscYiq>( fixture.ctx(), std::vector<std::string>{"source"}, std::vector<std::string>{"sink"}, 0.0f, 1000.0f)}, @@ -86,18 +86,15 @@ static void test_effects() { 1000.0f)}, {"CNNv3Effect", std::make_shared<CNNv3Effect>( - fixture.ctx(), - std::vector<std::string>{"gbuf_feat0", "gbuf_feat1"}, + fixture.ctx(), std::vector<std::string>{"gbuf_feat0", "gbuf_feat1"}, std::vector<std::string>{"cnn_v3_output"}, 0.0f, 1000.0f)}, {"GBufViewEffect", std::make_shared<GBufViewEffect>( - fixture.ctx(), - std::vector<std::string>{"gbuf_feat0", "gbuf_feat1"}, + fixture.ctx(), std::vector<std::string>{"gbuf_feat0", "gbuf_feat1"}, std::vector<std::string>{"gbuf_view_out"}, 0.0f, 1000.0f)}, {"GBufDeferredEffect", std::make_shared<GBufDeferredEffect>( - fixture.ctx(), - std::vector<std::string>{"gbuf_feat0", "gbuf_feat1"}, + fixture.ctx(), std::vector<std::string>{"gbuf_feat0", "gbuf_feat1"}, std::vector<std::string>{"gbuf_deferred_out"}, 0.0f, 1000.0f)}, }; diff --git a/src/tests/gpu/test_effect_base.cc b/src/tests/gpu/test_effect_base.cc index ad7bca3..57d0504 100644 --- a/src/tests/gpu/test_effect_base.cc +++ b/src/tests/gpu/test_effect_base.cc @@ -214,12 +214,15 @@ class WireDagTestEffect : public Effect { public: WireDagTestEffect(const GpuContext& ctx, std::vector<std::string> ins, std::vector<std::string> outs) - : Effect(ctx, std::move(ins), std::move(outs), 0.0f, 1000.0f) {} + : Effect(ctx, std::move(ins), std::move(outs), 0.0f, 1000.0f) { + } void render(WGPUCommandEncoder, const UniformsSequenceParams&, - NodeRegistry&) override {} + NodeRegistry&) override { + } - std::string call_find_downstream(const std::vector<EffectDAGNode>& dag) const { + std::string + call_find_downstream(const std::vector<EffectDAGNode>& dag) const { return find_downstream_output(dag); } @@ -239,12 +242,12 @@ static void test_find_downstream_output() { return; } - auto a = std::make_shared<WireDagTestEffect>( - fixture.ctx(), std::vector<std::string>{"src"}, - std::vector<std::string>{"mid"}); - auto b = std::make_shared<WireDagTestEffect>( - fixture.ctx(), std::vector<std::string>{"mid"}, - std::vector<std::string>{"out"}); + auto a = std::make_shared<WireDagTestEffect>(fixture.ctx(), + std::vector<std::string>{"src"}, + std::vector<std::string>{"mid"}); + auto b = std::make_shared<WireDagTestEffect>(fixture.ctx(), + std::vector<std::string>{"mid"}, + std::vector<std::string>{"out"}); auto c = std::make_shared<WireDagTestEffect>( fixture.ctx(), std::vector<std::string>{"out"}, std::vector<std::string>{"final"}); @@ -304,7 +307,8 @@ static void test_find_downstream_output() { a->wire_dag(dag_to_sink); assert(a->wired_to == "sink" && "base helper returns sink — caller must guard"); - fprintf(stdout, " ✓ sink downstream: find returns 'sink', caller must guard\n"); + fprintf(stdout, + " ✓ sink downstream: find returns 'sink', caller must guard\n"); } // Test 8: wire_dag called automatically by init_effect_nodes @@ -326,13 +330,12 @@ static void test_wire_dag_called_by_sequence() { class TestSequence : public Sequence { public: - TestSequence(const GpuContext& ctx, - std::shared_ptr<Effect> up, + TestSequence(const GpuContext& ctx, std::shared_ptr<Effect> up, std::shared_ptr<Effect> down) : Sequence(ctx, 256, 256) { - effect_dag_.push_back({up, {"source"}, {"mid"}, 0}); - effect_dag_.push_back({down, {"mid"}, {"sink"}, 1}); - init_effect_nodes(); // triggers wire_dag on both effects + effect_dag_.push_back({up, {"source"}, {"mid"}, 0}); + effect_dag_.push_back({down, {"mid"}, {"sink"}, 1}); + init_effect_nodes(); // triggers wire_dag on both effects } }; diff --git a/src/tests/gpu/test_shader_composer.cc b/src/tests/gpu/test_shader_composer.cc index 2f87e57..8d1f7c7 100644 --- a/src/tests/gpu/test_shader_composer.cc +++ b/src/tests/gpu/test_shader_composer.cc @@ -52,8 +52,7 @@ void test_asset_composition() { assert(snippet_a_code != nullptr); sc.RegisterSnippet("TEST_WGSL", std::string(snippet_a_code, snippet_a_size)); - std::string main_code = - "fn main() -> f32 { return test_wgsl(); }"; + std::string main_code = "fn main() -> f32 { return test_wgsl(); }"; std::string result = sc.Compose({"TEST_WGSL"}, main_code); assert(result.find("fn snippet_a()") != std::string::npos); diff --git a/src/tests/util/test_ans.cc b/src/tests/util/test_ans.cc index 108c46d..d8cc85c 100644 --- a/src/tests/util/test_ans.cc +++ b/src/tests/util/test_ans.cc @@ -15,8 +15,7 @@ namespace { bool RoundtripCheck(const std::vector<uint8_t>& input, - const uint32_t* initial_counts, - const char* label) { + const uint32_t* initial_counts, const char* label) { std::vector<uint8_t> compressed; if (!ans::Encode(input.data(), input.size(), &compressed, initial_counts)) { fprintf(stderr, "[%s] Encode failed\n", label); @@ -47,7 +46,8 @@ bool RoundtripCheck(const std::vector<uint8_t>& input, void TestRoundtripVariants() { std::mt19937 rng_uniform(12345); std::vector<uint8_t> random_uniform(64 * 1024); - for (auto& b : random_uniform) b = (uint8_t)(rng_uniform() & 0xff); + for (auto& b : random_uniform) + b = (uint8_t)(rng_uniform() & 0xff); std::mt19937 rng_skewed(67890); std::vector<uint8_t> random_skewed(32 * 1024); @@ -66,7 +66,7 @@ void TestRoundtripVariants() { " return textureSample(tex, smplr, uv);\n" "}\n"; std::vector<uint8_t> ascii_block; - for (int i = 0; i < 50; ++i) { // cross chunk boundary + for (int i = 0; i < 50; ++i) { // cross chunk boundary ascii_block.insert(ascii_block.end(), ascii, ascii + std::strlen(ascii)); } @@ -124,7 +124,8 @@ void TestRejection() { // 1) Mismatched models. { std::vector<uint8_t> v(4096); - for (auto& b : v) b = (uint8_t)('a' + (rng() % 26)); + for (auto& b : v) + b = (uint8_t)('a' + (rng() % 26)); uint32_t hist[256] = {}; ans::Histogram(v.data(), v.size(), hist); @@ -141,10 +142,11 @@ void TestRejection() { // 2) Corruption. { std::vector<uint8_t> v(2048); - for (auto& b : v) b = (uint8_t)(rng() & 0xff); + for (auto& b : v) + b = (uint8_t)(rng() & 0xff); std::vector<uint8_t> encoded; assert(ans::Encode(v.data(), v.size(), &encoded, nullptr)); - encoded[encoded.size() / 2] ^= 0x55; // flip a payload byte + encoded[encoded.size() / 2] ^= 0x55; // flip a payload byte std::vector<uint8_t> decoded(v.size()); size_t decoded_size = 0; @@ -156,7 +158,8 @@ void TestRejection() { // 3) Truncation. { std::vector<uint8_t> v(4096); - for (size_t i = 0; i < v.size(); ++i) v[i] = (uint8_t)i; + for (size_t i = 0; i < v.size(); ++i) + v[i] = (uint8_t)i; std::vector<uint8_t> encoded; assert(ans::Encode(v.data(), v.size(), &encoded, nullptr)); encoded.resize(encoded.size() - 8); @@ -173,11 +176,10 @@ void TestPeekSize() { std::vector<uint8_t> v(1234, 'Q'); std::vector<uint8_t> encoded; assert(ans::Encode(v.data(), v.size(), &encoded, nullptr)); - assert(ans::PeekUncompressedSize(encoded.data(), encoded.size()) == - v.size()); + assert(ans::PeekUncompressedSize(encoded.data(), encoded.size()) == v.size()); } -} // namespace +} // namespace int main() { TestRoundtripVariants(); diff --git a/src/tests/util/test_procedural.cc b/src/tests/util/test_procedural.cc index c6616ad..355f70c 100644 --- a/src/tests/util/test_procedural.cc +++ b/src/tests/util/test_procedural.cc @@ -165,7 +165,10 @@ void test_voronoi() { bool nonzero = false; for (size_t i = 0; i < buffer.size(); i += 4) { - if (buffer[i] > 0) { nonzero = true; break; } + if (buffer[i] > 0) { + nonzero = true; + break; + } } assert(nonzero); @@ -204,7 +207,10 @@ void test_normalmap() { // (non-flat normals expected) bool has_normal_variation = false; for (size_t i = 0; i < buffer.size(); i += 4) { - if (buffer[i] != 128) { has_normal_variation = true; break; } + if (buffer[i] != 128) { + has_normal_variation = true; + break; + } } assert(has_normal_variation); diff --git a/src/util/ans.cc b/src/util/ans.cc index aa79e4b..779ef81 100644 --- a/src/util/ans.cc +++ b/src/util/ans.cc @@ -58,8 +58,7 @@ struct Stats { // the slot. Increments the symbol's count on the fly. void decode_lookup(uint32_t s, uint8_t* sym, uint32_t* p, uint32_t* r) { // upper_bound(s) - 1; cumul is strictly non-decreasing. - const uint32_t* it = - std::upper_bound(cumul, cumul + kNumSymbols + 1, s); + const uint32_t* it = std::upper_bound(cumul, cumul + kNumSymbols + 1, s); const int c = (int)(it - cumul) - 1; stats[c] += 1; *sym = (uint8_t)c; @@ -97,27 +96,31 @@ inline void AppendU32BE(std::vector<uint8_t>* dst, uint32_t v) { } #endif -} // namespace +} // namespace uint32_t PeekUncompressedSize(const uint8_t* src, size_t src_size) { - if (!src || src_size < 4) return 0; + if (!src || src_size < 4) + return 0; return ReadU32BE(src); } -bool Decode(const uint8_t* src, size_t src_size, - uint8_t* dst, size_t dst_capacity, - size_t* out_size, +bool Decode(const uint8_t* src, size_t src_size, uint8_t* dst, + size_t dst_capacity, size_t* out_size, const uint32_t* initial_counts) { - if (out_size) *out_size = 0; - if (!src || src_size < 4) return false; + if (out_size) + *out_size = 0; + if (!src || src_size < 4) + return false; const uint8_t* p = src; const uint8_t* end = src + src_size; const uint32_t output_size = ReadU32BE(p); p += 4; - if (output_size > dst_capacity) return false; - if (output_size > 0 && !dst) return false; + if (output_size > dst_capacity) + return false; + if (output_size > 0 && !dst) + return false; Stats stats; stats.init(initial_counts); @@ -126,14 +129,16 @@ bool Decode(const uint8_t* src, size_t src_size, while (t < output_size) { const uint32_t chunk = std::min<uint32_t>(kChunkSize, output_size - t); - if (end - p < 4) return false; + if (end - p < 4) + return false; uint32_t s = ReadU32BE(p); p += 4; for (uint32_t i = 0; i < chunk; ++i) { if (s <= kMask) { // Pull in one renorm word. - if (end - p < 2) return false; + if (end - p < 2) + return false; s = (s << kBits) | (uint32_t)ReadU16BE(p); p += 2; } @@ -144,31 +149,37 @@ bool Decode(const uint8_t* src, size_t src_size, s = proba * (s >> kBits) + residual; } // Final-state sanity check: catches stream corruption and model mismatch. - if (s != kInitState) return false; + if (s != kInitState) + return false; stats.normalize(); t += chunk; } - if (out_size) *out_size = output_size; + if (out_size) + *out_size = output_size; return true; } #if defined(ANS_ENABLE_ENCODER) void Histogram(const uint8_t* src, size_t size, uint32_t* out_counts) { - if (!src || !out_counts) return; - for (size_t i = 0; i < size; ++i) out_counts[src[i]] += 1; + if (!src || !out_counts) + return; + for (size_t i = 0; i < size; ++i) + out_counts[src[i]] += 1; } -bool Encode(const uint8_t* src, size_t size, - std::vector<uint8_t>* dst, +bool Encode(const uint8_t* src, size_t size, std::vector<uint8_t>* dst, const uint32_t* initial_counts) { - if (!dst) return false; + if (!dst) + return false; dst->clear(); - if (size > 0xffffffffu) return false; // header is u32 + if (size > 0xffffffffu) + return false; // header is u32 AppendU32BE(dst, (uint32_t)size); - if (size == 0) return true; + if (size == 0) + return true; Stats stats; stats.init(initial_counts); @@ -200,9 +211,11 @@ bool Encode(const uint8_t* src, size_t size, } // Invariant: final state must be > kMask so the decoder's first read is // a valid renormalized state. - if (s <= kMask) return false; + if (s <= kMask) + return false; AppendU32BE(dst, s); - for (size_t k = pos; k < chunk; ++k) AppendU16BE(dst, tmp[k]); + for (size_t k = pos; k < chunk; ++k) + AppendU16BE(dst, tmp[k]); stats.normalize(); t += chunk; @@ -210,6 +223,6 @@ bool Encode(const uint8_t* src, size_t size, return true; } -#endif // ANS_ENABLE_ENCODER +#endif // ANS_ENABLE_ENCODER -} // namespace ans +} // namespace ans diff --git a/src/util/ans.h b/src/util/ans.h index 53c34b1..cf3d83a 100644 --- a/src/util/ans.h +++ b/src/util/ans.h @@ -34,25 +34,23 @@ uint32_t PeekUncompressedSize(const uint8_t* src, size_t src_size); // 'initial_counts' (256 entries) seeds the per-chunk adaptive model; pass // nullptr for the uniform default (all-ones). // Returns true on success and writes the decoded size to '*out_size'. -bool Decode(const uint8_t* src, size_t src_size, - uint8_t* dst, size_t dst_capacity, - size_t* out_size, +bool Decode(const uint8_t* src, size_t src_size, uint8_t* dst, + size_t dst_capacity, size_t* out_size, const uint32_t* initial_counts = nullptr); #if defined(ANS_ENABLE_ENCODER) // Encodes 'src[0..size]' into '*dst' (cleared and re-filled). // 'initial_counts' has the same semantics as in Decode(). // Returns true on success. -bool Encode(const uint8_t* src, size_t size, - std::vector<uint8_t>* dst, +bool Encode(const uint8_t* src, size_t size, std::vector<uint8_t>* dst, const uint32_t* initial_counts = nullptr); // Computes a byte histogram over 'src[0..size]', accumulating into // 'out_counts[256]' (caller must zero-initialize before the first call). // Useful for deriving a corpus-wide initial distribution from many files. void Histogram(const uint8_t* src, size_t size, uint32_t* out_counts); -#endif // ANS_ENABLE_ENCODER +#endif // ANS_ENABLE_ENCODER -} // namespace ans +} // namespace ans -#endif // ANS_H_ +#endif // ANS_H_ diff --git a/src/util/asset_manager.cc b/src/util/asset_manager.cc index 82c07be..aef67f3 100644 --- a/src/util/asset_manager.cc +++ b/src/util/asset_manager.cc @@ -120,7 +120,8 @@ const uint8_t* GetAsset(AssetId asset_id, size_t* out_size) { const size_t uncomp = source_record.uncompressed_size; uint8_t* buffer = new (std::nothrow) uint8_t[uncomp + 1]; CHECK_RETURN_BEGIN(!buffer, nullptr) - if (out_size) *out_size = 0; + if (out_size) + *out_size = 0; ERROR_MSG("Failed to allocate buffer for ANS-compressed asset id=%u", index); return nullptr; @@ -130,7 +131,8 @@ const uint8_t* GetAsset(AssetId asset_id, size_t* out_size) { &got, GetAnsAsciiHistogram()) || got != uncomp) { delete[] buffer; - if (out_size) *out_size = 0; + if (out_size) + *out_size = 0; ERROR_MSG("ANS decode failed for asset id=%u", index); return nullptr; } @@ -139,7 +141,8 @@ const uint8_t* GetAsset(AssetId asset_id, size_t* out_size) { cached_record.size = uncomp; cached_record.uncompressed_size = uncomp; g_asset_cache[index] = cached_record; - if (out_size) *out_size = uncomp; + if (out_size) + *out_size = uncomp; return buffer; } @@ -279,9 +282,8 @@ bool ReloadAssetsFromFile(const char* config_path) { const AssetRecord& e = g_asset_cache[i]; if (e.data && (e.type == AssetType::PROC || e.type == AssetType::PROC_GPU || - e.compression != AssetCompression::NONE || - e.type == AssetType::SPEC || e.type == AssetType::MP3 || - e.type == AssetType::WGSL)) { + e.compression != AssetCompression::NONE || e.type == AssetType::SPEC || + e.type == AssetType::MP3 || e.type == AssetType::WGSL)) { delete[] e.data; } g_asset_cache[i] = {}; diff --git a/src/util/mini_math.h b/src/util/mini_math.h index 0aa66a3..c386134 100644 --- a/src/util/mini_math.h +++ b/src/util/mini_math.h @@ -229,7 +229,7 @@ struct mat4 { mat4 r = {}; float t = 1.0f / std::tan(fov * 0.5f); r.m[0] = t / asp; - r.m[5] = -t; // Negate Y: post-process chain samples textures Y-flipped + r.m[5] = -t; // Negate Y: post-process chain samples textures Y-flipped r.m[10] = f / (n - f); r.m[11] = -1; r.m[14] = (n * f) / (n - f); |
