summaryrefslogtreecommitdiff
path: root/src/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/demo_effects.h1
-rw-r--r--src/gpu/effects/cnn_v2_effect.cc170
-rw-r--r--src/gpu/effects/cnn_v2_effect.h41
3 files changed, 212 insertions, 0 deletions
diff --git a/src/gpu/demo_effects.h b/src/gpu/demo_effects.h
index 8cdf557..d0ae748 100644
--- a/src/gpu/demo_effects.h
+++ b/src/gpu/demo_effects.h
@@ -186,6 +186,7 @@ class DistortEffect : public PostProcessEffect {
// (included above)
#include "gpu/effects/cnn_effect.h"
+#include "gpu/effects/cnn_v2_effect.h"
// Auto-generated functions
void LoadTimeline(MainSequence& main_seq, const GpuContext& ctx);
diff --git a/src/gpu/effects/cnn_v2_effect.cc b/src/gpu/effects/cnn_v2_effect.cc
new file mode 100644
index 0000000..04fa74e
--- /dev/null
+++ b/src/gpu/effects/cnn_v2_effect.cc
@@ -0,0 +1,170 @@
+// CNN v2 Effect Implementation
+
+#include "gpu/effects/cnn_v2_effect.h"
+
+#if defined(USE_TEST_ASSETS)
+#include "test_assets.h"
+#else
+#include "generated/assets.h"
+#endif
+
+#include "util/asset_manager.h"
+#include "util/fatal_error.h"
+#include <cstring>
+
+CNNv2Effect::CNNv2Effect(const GpuContext& ctx)
+ : PostProcessEffect(ctx),
+ static_pipeline_(nullptr),
+ static_bind_group_(nullptr),
+ static_features_tex_(nullptr),
+ static_features_view_(nullptr),
+ input_mip_tex_(nullptr),
+ initialized_(false) {
+ std::memset(input_mip_view_, 0, sizeof(input_mip_view_));
+}
+
+CNNv2Effect::~CNNv2Effect() {
+ cleanup();
+}
+
+void CNNv2Effect::init(MainSequence* demo) {
+ (void)demo;
+ if (initialized_) return;
+
+ create_textures();
+ create_pipelines();
+
+ initialized_ = true;
+}
+
+void CNNv2Effect::resize(int width, int height) {
+ PostProcessEffect::resize(width, height);
+ cleanup();
+ create_textures();
+ create_pipelines();
+}
+
+void CNNv2Effect::create_textures() {
+ const WGPUExtent3D size = {
+ static_cast<uint32_t>(width_),
+ static_cast<uint32_t>(height_),
+ 1
+ };
+
+ // Static features texture (8×f16 packed as 4×u32)
+ WGPUTextureDescriptor static_desc = {};
+ static_desc.usage = WGPUTextureUsage_StorageBinding | WGPUTextureUsage_TextureBinding;
+ static_desc.dimension = WGPUTextureDimension_2D;
+ static_desc.size = size;
+ static_desc.format = WGPUTextureFormat_RGBA32Uint;
+ static_desc.mipLevelCount = 1;
+ static_desc.sampleCount = 1;
+ static_features_tex_ = wgpuDeviceCreateTexture(ctx_.device, &static_desc);
+
+ WGPUTextureViewDescriptor view_desc = {};
+ view_desc.format = WGPUTextureFormat_RGBA32Uint;
+ view_desc.dimension = WGPUTextureViewDimension_2D;
+ view_desc.baseMipLevel = 0;
+ view_desc.mipLevelCount = 1;
+ view_desc.baseArrayLayer = 0;
+ view_desc.arrayLayerCount = 1;
+ static_features_view_ = wgpuTextureCreateView(static_features_tex_, &view_desc);
+
+ // Input texture with mips (for multi-scale features)
+ WGPUTextureDescriptor input_mip_desc = {};
+ input_mip_desc.usage = WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst;
+ input_mip_desc.dimension = WGPUTextureDimension_2D;
+ input_mip_desc.size = size;
+ input_mip_desc.format = WGPUTextureFormat_RGBA8Unorm;
+ input_mip_desc.mipLevelCount = 3; // Levels 0, 1, 2
+ input_mip_desc.sampleCount = 1;
+ input_mip_tex_ = wgpuDeviceCreateTexture(ctx_.device, &input_mip_desc);
+
+ for (int i = 0; i < 3; ++i) {
+ WGPUTextureViewDescriptor mip_view_desc = {};
+ mip_view_desc.format = WGPUTextureFormat_RGBA8Unorm;
+ mip_view_desc.dimension = WGPUTextureViewDimension_2D;
+ mip_view_desc.baseMipLevel = i;
+ mip_view_desc.mipLevelCount = 1;
+ mip_view_desc.baseArrayLayer = 0;
+ mip_view_desc.arrayLayerCount = 1;
+ input_mip_view_[i] = wgpuTextureCreateView(input_mip_tex_, &mip_view_desc);
+ }
+
+ // Layer textures (placeholder - will be created based on config)
+ // TODO: Create layer textures based on layer_configs_
+}
+
+void CNNv2Effect::create_pipelines() {
+ // Static features compute pipeline
+ size_t shader_size = 0;
+ const char* static_code = (const char*)GetAsset(AssetId::ASSET_SHADER_CNN_V2_STATIC, &shader_size);
+
+ if (!static_code || shader_size == 0) {
+ // Shader not available (e.g., in test mode) - skip pipeline creation
+ return;
+ }
+
+ WGPUShaderSourceWGSL wgsl_src = {};
+ wgsl_src.chain.sType = WGPUSType_ShaderSourceWGSL;
+ wgsl_src.code = str_view(static_code);
+
+ WGPUShaderModuleDescriptor shader_desc = {};
+ shader_desc.nextInChain = &wgsl_src.chain;
+
+ WGPUShaderModule static_module = wgpuDeviceCreateShaderModule(ctx_.device, &shader_desc);
+ if (!static_module) {
+ return;
+ }
+
+ WGPUComputePipelineDescriptor pipeline_desc = {};
+ pipeline_desc.compute.module = static_module;
+ pipeline_desc.compute.entryPoint = str_view("main");
+
+ static_pipeline_ = wgpuDeviceCreateComputePipeline(ctx_.device, &pipeline_desc);
+ wgpuShaderModuleRelease(static_module);
+
+ // TODO: Create layer pipelines
+ // TODO: Create bind groups
+}
+
+void CNNv2Effect::update_bind_group(WGPUTextureView input_view) {
+ (void)input_view;
+ // TODO: Create bind groups for static features and layers
+}
+
+void CNNv2Effect::render(WGPURenderPassEncoder pass,
+ const CommonPostProcessUniforms& uniforms) {
+ (void)pass;
+ (void)uniforms;
+ if (!initialized_) return;
+
+ // TODO: Multi-pass execution
+ // 1. Compute static features
+ // 2. Execute CNN layers
+ // 3. Composite to output
+}
+
+void CNNv2Effect::cleanup() {
+ if (static_features_view_) wgpuTextureViewRelease(static_features_view_);
+ if (static_features_tex_) wgpuTextureRelease(static_features_tex_);
+ if (static_bind_group_) wgpuBindGroupRelease(static_bind_group_);
+ if (static_pipeline_) wgpuComputePipelineRelease(static_pipeline_);
+
+ for (int i = 0; i < 3; ++i) {
+ if (input_mip_view_[i]) wgpuTextureViewRelease(input_mip_view_[i]);
+ }
+ if (input_mip_tex_) wgpuTextureRelease(input_mip_tex_);
+
+ for (auto view : layer_views_) wgpuTextureViewRelease(view);
+ for (auto tex : layer_textures_) wgpuTextureRelease(tex);
+ for (auto bg : layer_bind_groups_) wgpuBindGroupRelease(bg);
+ for (auto pipeline : layer_pipelines_) wgpuComputePipelineRelease(pipeline);
+
+ layer_views_.clear();
+ layer_textures_.clear();
+ layer_bind_groups_.clear();
+ layer_pipelines_.clear();
+
+ initialized_ = false;
+}
diff --git a/src/gpu/effects/cnn_v2_effect.h b/src/gpu/effects/cnn_v2_effect.h
new file mode 100644
index 0000000..edf301e
--- /dev/null
+++ b/src/gpu/effects/cnn_v2_effect.h
@@ -0,0 +1,41 @@
+// CNN v2 Effect - Parametric Static Features
+// Multi-pass post-processing with 7D feature input
+
+#pragma once
+#include "gpu/effect.h"
+#include <vector>
+
+class CNNv2Effect : public PostProcessEffect {
+public:
+ explicit CNNv2Effect(const GpuContext& ctx);
+ ~CNNv2Effect();
+
+ void init(MainSequence* demo) override;
+ void resize(int width, int height) override;
+ void render(WGPURenderPassEncoder pass,
+ const CommonPostProcessUniforms& uniforms) override;
+ void update_bind_group(WGPUTextureView input_view) override;
+
+private:
+ void create_textures();
+ void create_pipelines();
+ void cleanup();
+
+ // Static features compute
+ WGPUComputePipeline static_pipeline_;
+ WGPUBindGroup static_bind_group_;
+ WGPUTexture static_features_tex_;
+ WGPUTextureView static_features_view_;
+
+ // CNN layers (opaque implementation)
+ std::vector<WGPUComputePipeline> layer_pipelines_;
+ std::vector<WGPUBindGroup> layer_bind_groups_;
+ std::vector<WGPUTexture> layer_textures_;
+ std::vector<WGPUTextureView> layer_views_;
+
+ // Input mips
+ WGPUTexture input_mip_tex_;
+ WGPUTextureView input_mip_view_[3];
+
+ bool initialized_;
+};