diff options
Diffstat (limited to 'src/gpu/effects/cnn_v2_effect.cc')
| -rw-r--r-- | src/gpu/effects/cnn_v2_effect.cc | 260 |
1 files changed, 55 insertions, 205 deletions
diff --git a/src/gpu/effects/cnn_v2_effect.cc b/src/gpu/effects/cnn_v2_effect.cc index d412154..be856a4 100644 --- a/src/gpu/effects/cnn_v2_effect.cc +++ b/src/gpu/effects/cnn_v2_effect.cc @@ -8,6 +8,8 @@ #include "generated/assets.h" #endif +#include "gpu/bind_group_builder.h" +#include "gpu/gpu.h" #include "util/asset_manager.h" #include "util/fatal_error.h" #include <cstring> @@ -142,76 +144,30 @@ void CNNv2Effect::load_weights() { } 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); + TextureWithView static_tex = gpu_create_storage_texture_2d( + ctx_.device, width_, height_, WGPUTextureFormat_RGBA32Uint); + static_features_tex_ = static_tex.texture; + static_features_view_ = static_tex.view; // 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); + TextureWithView input_mip = gpu_create_texture_2d( + ctx_.device, width_, height_, WGPUTextureFormat_RGBA8Unorm, + WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst, 3); + input_mip_tex_ = input_mip.texture; 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); + input_mip_view_[i] = + gpu_create_mip_view(input_mip_tex_, WGPUTextureFormat_RGBA8Unorm, i); } // Create 2 layer textures (ping-pong buffers for intermediate results) // Each stores 8×f16 channels packed as 4×u32 for (int i = 0; i < 2; ++i) { - WGPUTextureDescriptor layer_desc = {}; - layer_desc.usage = WGPUTextureUsage_StorageBinding | WGPUTextureUsage_TextureBinding; - layer_desc.dimension = WGPUTextureDimension_2D; - layer_desc.size = size; - layer_desc.format = WGPUTextureFormat_RGBA32Uint; - layer_desc.mipLevelCount = 1; - layer_desc.sampleCount = 1; - - WGPUTexture tex = wgpuDeviceCreateTexture(ctx_.device, &layer_desc); - layer_textures_.push_back(tex); - - 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; - - WGPUTextureView view = wgpuTextureCreateView(tex, &view_desc); - layer_views_.push_back(view); + TextureWithView layer = gpu_create_storage_texture_2d( + ctx_.device, width_, height_, WGPUTextureFormat_RGBA32Uint); + layer_textures_.push_back(layer.texture); + layer_views_.push_back(layer.view); } // Create uniform buffer for static feature params @@ -255,55 +211,17 @@ void CNNv2Effect::create_pipelines() { // Create bind group layout for static features compute // Bindings: 0=input_tex, 1=input_mip1, 2=input_mip2, 3=depth_tex, 4=output, 5=params, 6=linear_sampler - WGPUBindGroupLayoutEntry bgl_entries[7] = {}; - - // Binding 0: Input texture (mip 0) - bgl_entries[0].binding = 0; - bgl_entries[0].visibility = WGPUShaderStage_Compute; - bgl_entries[0].texture.sampleType = WGPUTextureSampleType_Float; - bgl_entries[0].texture.viewDimension = WGPUTextureViewDimension_2D; - - // Binding 1: Input texture (mip 1) - bgl_entries[1].binding = 1; - bgl_entries[1].visibility = WGPUShaderStage_Compute; - bgl_entries[1].texture.sampleType = WGPUTextureSampleType_Float; - bgl_entries[1].texture.viewDimension = WGPUTextureViewDimension_2D; - - // Binding 2: Input texture (mip 2) - bgl_entries[2].binding = 2; - bgl_entries[2].visibility = WGPUShaderStage_Compute; - bgl_entries[2].texture.sampleType = WGPUTextureSampleType_Float; - bgl_entries[2].texture.viewDimension = WGPUTextureViewDimension_2D; - - // Binding 3: Depth texture - bgl_entries[3].binding = 3; - bgl_entries[3].visibility = WGPUShaderStage_Compute; - bgl_entries[3].texture.sampleType = WGPUTextureSampleType_Float; - bgl_entries[3].texture.viewDimension = WGPUTextureViewDimension_2D; - - // Binding 4: Output (static features) - bgl_entries[4].binding = 4; - bgl_entries[4].visibility = WGPUShaderStage_Compute; - bgl_entries[4].storageTexture.access = WGPUStorageTextureAccess_WriteOnly; - bgl_entries[4].storageTexture.format = WGPUTextureFormat_RGBA32Uint; - bgl_entries[4].storageTexture.viewDimension = WGPUTextureViewDimension_2D; - - // Binding 5: Params (mip_level) - bgl_entries[5].binding = 5; - bgl_entries[5].visibility = WGPUShaderStage_Compute; - bgl_entries[5].buffer.type = WGPUBufferBindingType_Uniform; - bgl_entries[5].buffer.minBindingSize = sizeof(StaticFeatureParams); - - // Binding 6: Linear sampler (for bilinear interpolation) - bgl_entries[6].binding = 6; - bgl_entries[6].visibility = WGPUShaderStage_Compute; - bgl_entries[6].sampler.type = WGPUSamplerBindingType_Filtering; - - WGPUBindGroupLayoutDescriptor bgl_desc = {}; - bgl_desc.entryCount = 7; - bgl_desc.entries = bgl_entries; - - WGPUBindGroupLayout static_bgl = wgpuDeviceCreateBindGroupLayout(ctx_.device, &bgl_desc); + WGPUBindGroupLayout static_bgl = + BindGroupLayoutBuilder() + .texture(0, WGPUShaderStage_Compute) + .texture(1, WGPUShaderStage_Compute) + .texture(2, WGPUShaderStage_Compute) + .texture(3, WGPUShaderStage_Compute) + .storage_texture(4, WGPUShaderStage_Compute, + WGPUTextureFormat_RGBA32Uint) + .uniform(5, WGPUShaderStage_Compute, sizeof(StaticFeatureParams)) + .sampler(6, WGPUShaderStage_Compute) + .build(ctx_.device); // Update pipeline layout WGPUPipelineLayoutDescriptor pl_desc = {}; @@ -344,49 +262,16 @@ void CNNv2Effect::create_pipelines() { // Create bind group layout for layer compute // 0=static_features, 1=layer_input, 2=output, 3=weights, 4=params, 5=original_input - WGPUBindGroupLayoutEntry layer_bgl_entries[6] = {}; - - // Binding 0: Static features (texture) - layer_bgl_entries[0].binding = 0; - layer_bgl_entries[0].visibility = WGPUShaderStage_Compute; - layer_bgl_entries[0].texture.sampleType = WGPUTextureSampleType_Uint; - layer_bgl_entries[0].texture.viewDimension = WGPUTextureViewDimension_2D; - - // Binding 1: Layer input (texture) - layer_bgl_entries[1].binding = 1; - layer_bgl_entries[1].visibility = WGPUShaderStage_Compute; - layer_bgl_entries[1].texture.sampleType = WGPUTextureSampleType_Uint; - layer_bgl_entries[1].texture.viewDimension = WGPUTextureViewDimension_2D; - - // Binding 2: Output (storage texture) - layer_bgl_entries[2].binding = 2; - layer_bgl_entries[2].visibility = WGPUShaderStage_Compute; - layer_bgl_entries[2].storageTexture.access = WGPUStorageTextureAccess_WriteOnly; - layer_bgl_entries[2].storageTexture.format = WGPUTextureFormat_RGBA32Uint; - layer_bgl_entries[2].storageTexture.viewDimension = WGPUTextureViewDimension_2D; - - // Binding 3: Weights (storage buffer) - layer_bgl_entries[3].binding = 3; - layer_bgl_entries[3].visibility = WGPUShaderStage_Compute; - layer_bgl_entries[3].buffer.type = WGPUBufferBindingType_ReadOnlyStorage; - - // Binding 4: Layer params (uniform buffer) - layer_bgl_entries[4].binding = 4; - layer_bgl_entries[4].visibility = WGPUShaderStage_Compute; - layer_bgl_entries[4].buffer.type = WGPUBufferBindingType_Uniform; - layer_bgl_entries[4].buffer.minBindingSize = sizeof(LayerParams); - - // Binding 5: Original input (for blending) - layer_bgl_entries[5].binding = 5; - layer_bgl_entries[5].visibility = WGPUShaderStage_Compute; - layer_bgl_entries[5].texture.sampleType = WGPUTextureSampleType_Float; - layer_bgl_entries[5].texture.viewDimension = WGPUTextureViewDimension_2D; - - WGPUBindGroupLayoutDescriptor layer_bgl_desc = {}; - layer_bgl_desc.entryCount = 6; - layer_bgl_desc.entries = layer_bgl_entries; - - WGPUBindGroupLayout layer_bgl = wgpuDeviceCreateBindGroupLayout(ctx_.device, &layer_bgl_desc); + WGPUBindGroupLayout layer_bgl = + BindGroupLayoutBuilder() + .uint_texture(0, WGPUShaderStage_Compute) + .uint_texture(1, WGPUShaderStage_Compute) + .storage_texture(2, WGPUShaderStage_Compute, + WGPUTextureFormat_RGBA32Uint) + .storage(3, WGPUShaderStage_Compute) + .uniform(4, WGPUShaderStage_Compute, sizeof(LayerParams)) + .texture(5, WGPUShaderStage_Compute) + .build(ctx_.device); WGPUPipelineLayoutDescriptor layer_pl_desc = {}; layer_pl_desc.bindGroupLayoutCount = 1; @@ -418,46 +303,33 @@ void CNNv2Effect::update_bind_group(WGPUTextureView input_view) { static_bind_group_ = nullptr; } - // Create bind group for static features compute + // Create bind group for static features compute (manual for storage texture binding) WGPUBindGroupEntry bg_entries[7] = {}; - - // Binding 0: Input (mip 0) bg_entries[0].binding = 0; bg_entries[0].textureView = input_view; - - // Binding 1: Input (mip 1) bg_entries[1].binding = 1; bg_entries[1].textureView = input_mip_view_[0]; - - // Binding 2: Input (mip 2) bg_entries[2].binding = 2; - bg_entries[2].textureView = (input_mip_view_[1]) ? input_mip_view_[1] : input_mip_view_[0]; - - // Binding 3: Depth (use input for now, no depth available) + bg_entries[2].textureView = + input_mip_view_[1] ? input_mip_view_[1] : input_mip_view_[0]; bg_entries[3].binding = 3; bg_entries[3].textureView = input_view; - - // Binding 4: Output (static features) bg_entries[4].binding = 4; bg_entries[4].textureView = static_features_view_; - - // Binding 5: Params bg_entries[5].binding = 5; bg_entries[5].buffer = static_params_buffer_; bg_entries[5].size = sizeof(StaticFeatureParams); - - // Binding 6: Linear sampler bg_entries[6].binding = 6; bg_entries[6].sampler = linear_sampler_; + WGPUBindGroupLayout layout = + wgpuComputePipelineGetBindGroupLayout(static_pipeline_, 0); WGPUBindGroupDescriptor bg_desc = {}; - bg_desc.layout = wgpuComputePipelineGetBindGroupLayout(static_pipeline_, 0); + bg_desc.layout = layout; bg_desc.entryCount = 7; bg_desc.entries = bg_entries; - static_bind_group_ = wgpuDeviceCreateBindGroup(ctx_.device, &bg_desc); - - wgpuBindGroupLayoutRelease(bg_desc.layout); + wgpuBindGroupLayoutRelease(layout); // Create layer bind groups if (!layer_pipeline_ || layer_info_.empty()) return; @@ -473,41 +345,19 @@ void CNNv2Effect::update_bind_group(WGPUTextureView input_view) { // Create bind group for each layer for (size_t i = 0; i < layer_info_.size(); ++i) { - WGPUBindGroupEntry layer_entries[6] = {}; - - // Binding 0: Static features (constant) - layer_entries[0].binding = 0; - layer_entries[0].textureView = static_features_view_; - - // Binding 1: Layer input (ping-pong: use previous layer's output) - // First layer uses static features as input, others use ping-pong buffers - layer_entries[1].binding = 1; - layer_entries[1].textureView = (i == 0) ? static_features_view_ : layer_views_[i % 2]; - - // Binding 2: Output texture (ping-pong) - layer_entries[2].binding = 2; - layer_entries[2].textureView = layer_views_[(i + 1) % 2]; - - // Binding 3: Weights buffer (constant) - layer_entries[3].binding = 3; - layer_entries[3].buffer = weights_buffer_; - layer_entries[3].size = wgpuBufferGetSize(weights_buffer_); - - // Binding 4: Layer params (use dedicated buffer for this layer) - layer_entries[4].binding = 4; - layer_entries[4].buffer = layer_params_buffers_[i]; - layer_entries[4].size = sizeof(LayerParams); - - // Binding 5: Original input (for blending) - layer_entries[5].binding = 5; - layer_entries[5].textureView = input_view; + WGPUTextureView layer_input = + (i == 0) ? static_features_view_ : layer_views_[i % 2]; - WGPUBindGroupDescriptor layer_bg_desc = {}; - layer_bg_desc.layout = layer_bgl; - layer_bg_desc.entryCount = 6; - layer_bg_desc.entries = layer_entries; + WGPUBindGroup layer_bg = + BindGroupBuilder() + .texture(0, static_features_view_) + .texture(1, layer_input) + .texture(2, layer_views_[(i + 1) % 2]) + .buffer(3, weights_buffer_, wgpuBufferGetSize(weights_buffer_)) + .buffer(4, layer_params_buffers_[i], sizeof(LayerParams)) + .texture(5, input_view) + .build(ctx_.device, layer_bgl); - WGPUBindGroup layer_bg = wgpuDeviceCreateBindGroup(ctx_.device, &layer_bg_desc); layer_bind_groups_.push_back(layer_bg); } |
