diff options
Diffstat (limited to 'src/gpu/effects/circle_mask_effect.cc')
| -rw-r--r-- | src/gpu/effects/circle_mask_effect.cc | 219 |
1 files changed, 0 insertions, 219 deletions
diff --git a/src/gpu/effects/circle_mask_effect.cc b/src/gpu/effects/circle_mask_effect.cc deleted file mode 100644 index dfe7d03..0000000 --- a/src/gpu/effects/circle_mask_effect.cc +++ /dev/null @@ -1,219 +0,0 @@ -// This file is part of the 64k demo project. -// It implements CircleMaskEffect for auxiliary texture masking demonstration. -// Generates circular mask and renders green background outside circle. - -#include "gpu/effects/circle_mask_effect.h" -#include "generated/assets.h" -#include "gpu/bind_group_builder.h" -#include "gpu/effects/shader_composer.h" - -CircleMaskEffect::CircleMaskEffect(const GpuContext& ctx, float radius) - : Effect(ctx), radius_(radius) { -} - -CircleMaskEffect::~CircleMaskEffect() { - if (mask_sampler_) - wgpuSamplerRelease(mask_sampler_); - if (render_bind_group_) - wgpuBindGroupRelease(render_bind_group_); - if (render_pipeline_) - wgpuRenderPipelineRelease(render_pipeline_); - if (compute_bind_group_) - wgpuBindGroupRelease(compute_bind_group_); - if (compute_pipeline_) - wgpuRenderPipelineRelease(compute_pipeline_); -} - -void CircleMaskEffect::init(MainSequence* demo) { - demo_ = demo; - - // Register auxiliary texture (width_/height_ set by resize() before init()) - demo_->register_auxiliary_texture("circle_mask", width_, height_); - - compute_params_.init(ctx_.device); - - // Initialize uniforms BEFORE bind group creation - uniforms_.update(ctx_.queue, get_common_uniforms()); - - WGPUSamplerDescriptor sampler_desc = {}; - sampler_desc.addressModeU = WGPUAddressMode_ClampToEdge; - sampler_desc.addressModeV = WGPUAddressMode_ClampToEdge; - sampler_desc.magFilter = WGPUFilterMode_Linear; - sampler_desc.minFilter = WGPUFilterMode_Linear; - sampler_desc.mipmapFilter = WGPUMipmapFilterMode_Linear; - sampler_desc.maxAnisotropy = 1; - mask_sampler_ = wgpuDeviceCreateSampler(ctx_.device, &sampler_desc); - - size_t compute_size, render_size; - const char* compute_shader = (const char*)GetAsset( - AssetId::ASSET_CIRCLE_MASK_COMPUTE_SHADER, &compute_size); - const char* render_shader = (const char*)GetAsset( - AssetId::ASSET_CIRCLE_MASK_RENDER_SHADER, &render_size); - - // Compose shaders to resolve #include directives - std::string composed_compute = ShaderComposer::Get().Compose({}, compute_shader); - - WGPUShaderSourceWGSL compute_wgsl = {}; - compute_wgsl.chain.sType = WGPUSType_ShaderSourceWGSL; - compute_wgsl.code = str_view(composed_compute.c_str()); - - WGPUShaderModuleDescriptor compute_desc = {}; - compute_desc.nextInChain = &compute_wgsl.chain; - WGPUShaderModule compute_module = - wgpuDeviceCreateShaderModule(ctx_.device, &compute_desc); - - const WGPUColorTargetState compute_target = { - .format = ctx_.format, // Match auxiliary texture format - .writeMask = WGPUColorWriteMask_All, - }; - WGPUFragmentState compute_frag = {}; - compute_frag.module = compute_module; - compute_frag.entryPoint = str_view("fs_main"); - compute_frag.targetCount = 1; - compute_frag.targets = &compute_target; - WGPURenderPipelineDescriptor compute_pipeline_desc = {}; - compute_pipeline_desc.label = label_view("CircleMaskEffect_compute"); - compute_pipeline_desc.vertex.module = compute_module; - compute_pipeline_desc.vertex.entryPoint = str_view("vs_main"); - compute_pipeline_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; - compute_pipeline_desc.primitive.cullMode = WGPUCullMode_None; - compute_pipeline_desc.multisample.count = 1; - compute_pipeline_desc.multisample.mask = 0xFFFFFFFF; - compute_pipeline_desc.fragment = &compute_frag; - compute_pipeline_ = - wgpuDeviceCreateRenderPipeline(ctx_.device, &compute_pipeline_desc); - wgpuShaderModuleRelease(compute_module); - - WGPUBindGroupLayout compute_layout = - wgpuRenderPipelineGetBindGroupLayout(compute_pipeline_, 0); - compute_bind_group_ = - BindGroupBuilder() - .buffer(0, uniforms_.get().buffer, sizeof(CommonPostProcessUniforms)) - .buffer(1, compute_params_.get().buffer, sizeof(CircleMaskParams)) - .build(ctx_.device, compute_layout); - wgpuBindGroupLayoutRelease(compute_layout); - - std::string composed_render = ShaderComposer::Get().Compose({}, render_shader); - - WGPUShaderSourceWGSL render_wgsl = {}; - render_wgsl.chain.sType = WGPUSType_ShaderSourceWGSL; - render_wgsl.code = str_view(composed_render.c_str()); - - WGPUShaderModuleDescriptor render_desc = {}; - render_desc.nextInChain = &render_wgsl.chain; - WGPUShaderModule render_module = - wgpuDeviceCreateShaderModule(ctx_.device, &render_desc); - - const WGPUColorTargetState render_target = { - .format = ctx_.format, - .writeMask = WGPUColorWriteMask_All, - }; - WGPUFragmentState render_frag = {}; - render_frag.module = render_module; - render_frag.entryPoint = str_view("fs_main"); - render_frag.targetCount = 1; - render_frag.targets = &render_target; - const WGPUDepthStencilState depth_stencil = { - .format = WGPUTextureFormat_Depth24Plus, - .depthWriteEnabled = WGPUOptionalBool_False, // Don't write depth - .depthCompare = WGPUCompareFunction_Always, // Always pass - }; - - WGPURenderPipelineDescriptor render_pipeline_desc = {}; - render_pipeline_desc.label = label_view("CircleMaskEffect_render"); - render_pipeline_desc.vertex.module = render_module; - render_pipeline_desc.vertex.entryPoint = str_view("vs_main"); - render_pipeline_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; - render_pipeline_desc.primitive.cullMode = WGPUCullMode_None; - render_pipeline_desc.depthStencil = &depth_stencil; - render_pipeline_desc.multisample.count = 1; - render_pipeline_desc.multisample.mask = 0xFFFFFFFF; - render_pipeline_desc.fragment = &render_frag; - render_pipeline_ = - wgpuDeviceCreateRenderPipeline(ctx_.device, &render_pipeline_desc); - wgpuShaderModuleRelease(render_module); - - WGPUTextureView mask_view = demo_->get_auxiliary_view("circle_mask"); - const WGPUBindGroupEntry render_entries[] = { - {.binding = 0, .textureView = mask_view}, - {.binding = 1, .sampler = mask_sampler_}, - {.binding = 2, - .buffer = uniforms_.get().buffer, - .size = sizeof(CommonPostProcessUniforms)}, - }; - const WGPUBindGroupDescriptor render_bg_desc = { - .layout = wgpuRenderPipelineGetBindGroupLayout(render_pipeline_, 0), - .entryCount = 3, - .entries = render_entries, - }; - render_bind_group_ = wgpuDeviceCreateBindGroup(ctx_.device, &render_bg_desc); -} - -void CircleMaskEffect::resize(int width, int height) { - if (width == width_ && height == height_) - return; - - Effect::resize(width, height); - - if (!demo_) - return; - - // Resize auxiliary texture - demo_->resize_auxiliary_texture("circle_mask", width, height); - - // Recreate render bind group with new texture view - if (render_bind_group_) - wgpuBindGroupRelease(render_bind_group_); - - WGPUTextureView mask_view = demo_->get_auxiliary_view("circle_mask"); - WGPUBindGroupLayout render_layout = - wgpuRenderPipelineGetBindGroupLayout(render_pipeline_, 0); - render_bind_group_ = - BindGroupBuilder() - .texture(0, mask_view) - .sampler(1, mask_sampler_) - .buffer(2, uniforms_.get().buffer, sizeof(CommonPostProcessUniforms)) - .build(ctx_.device, render_layout); - wgpuBindGroupLayoutRelease(render_layout); -} - -void CircleMaskEffect::compute(WGPUCommandEncoder encoder, - const CommonPostProcessUniforms& uniforms) { - uniforms_.update(ctx_.queue, uniforms); - - const CircleMaskParams params = { - .radius = radius_, - }; - compute_params_.update(ctx_.queue, params); - - WGPUTextureView mask_view = demo_->get_auxiliary_view("circle_mask"); - WGPURenderPassColorAttachment color_attachment = {}; - color_attachment.view = mask_view; - color_attachment.loadOp = WGPULoadOp_Clear; - color_attachment.storeOp = WGPUStoreOp_Store; - color_attachment.clearValue = {0.0, 0.0, 0.0, 1.0}; -#if !defined(DEMO_CROSS_COMPILE_WIN32) - color_attachment.depthSlice = WGPU_DEPTH_SLICE_UNDEFINED; -#endif - - WGPURenderPassDescriptor pass_desc = {}; - pass_desc.colorAttachmentCount = 1; - pass_desc.colorAttachments = &color_attachment; - - WGPURenderPassEncoder pass = - wgpuCommandEncoderBeginRenderPass(encoder, &pass_desc); - wgpuRenderPassEncoderSetPipeline(pass, compute_pipeline_); - wgpuRenderPassEncoderSetBindGroup(pass, 0, compute_bind_group_, 0, nullptr); - wgpuRenderPassEncoderDraw(pass, 3, 1, 0, 0); - wgpuRenderPassEncoderEnd(pass); - wgpuRenderPassEncoderRelease(pass); -} - -void CircleMaskEffect::render(WGPURenderPassEncoder pass, - const CommonPostProcessUniforms& uniforms) { - uniforms_.update(ctx_.queue, uniforms); - - wgpuRenderPassEncoderSetPipeline(pass, render_pipeline_); - wgpuRenderPassEncoderSetBindGroup(pass, 0, render_bind_group_, 0, nullptr); - wgpuRenderPassEncoderDraw(pass, 3, 1, 0, 0); -} |
