diff options
Diffstat (limited to 'src/gpu/demo_effects.cc')
| -rw-r--r-- | src/gpu/demo_effects.cc | 268 |
1 files changed, 194 insertions, 74 deletions
diff --git a/src/gpu/demo_effects.cc b/src/gpu/demo_effects.cc index 5d7419d..71f1284 100644 --- a/src/gpu/demo_effects.cc +++ b/src/gpu/demo_effects.cc @@ -243,14 +243,21 @@ struct Uniforms { time: f32, beat: f32, intensity: f32, aspect_ratio: f32, }; })"; // --- HeptagonEffect --- -HeptagonEffect::HeptagonEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : queue_(queue) { - uniforms_ = gpu_create_buffer(device, sizeof(float) * 4, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); +HeptagonEffect::HeptagonEffect(WGPUDevice device, WGPUQueue queue, + WGPUTextureFormat format) + : queue_(queue) { + uniforms_ = + gpu_create_buffer(device, sizeof(float) * 4, + WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); ResourceBinding bindings[] = {{uniforms_, WGPUBufferBindingType_Uniform}}; pass_ = gpu_create_render_pass(device, format, main_shader_wgsl, bindings, 1); pass_.vertex_count = 21; } -void HeptagonEffect::render(WGPURenderPassEncoder pass, float t, float b, float i, float a) { - struct { float p, a, t, d; } u = {i, a, t, 0.0f}; +void HeptagonEffect::render(WGPURenderPassEncoder pass, float t, float b, + float i, float a) { + struct { + float p, a, t, d; + } u = {i, a, t, 0.0f}; wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); wgpuRenderPassEncoderSetPipeline(pass, pass_.pipeline); wgpuRenderPassEncoderSetBindGroup(pass, 0, pass_.bind_group, 0, nullptr); @@ -258,54 +265,91 @@ void HeptagonEffect::render(WGPURenderPassEncoder pass, float t, float b, float } // --- ParticlesEffect --- -ParticlesEffect::ParticlesEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : queue_(queue) { - uniforms_ = gpu_create_buffer(device, sizeof(float) * 4, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); +ParticlesEffect::ParticlesEffect(WGPUDevice device, WGPUQueue queue, + WGPUTextureFormat format) + : queue_(queue) { + uniforms_ = + gpu_create_buffer(device, sizeof(float) * 4, + WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); std::vector<Particle> init_p(NUM_PARTICLES); - particles_buffer_ = gpu_create_buffer(device, sizeof(Particle) * NUM_PARTICLES, WGPUBufferUsage_Storage | WGPUBufferUsage_Vertex, init_p.data()); - ResourceBinding cb[] = {{particles_buffer_, WGPUBufferBindingType_Storage}, {uniforms_, WGPUBufferBindingType_Uniform}}; + particles_buffer_ = gpu_create_buffer( + device, sizeof(Particle) * NUM_PARTICLES, + WGPUBufferUsage_Storage | WGPUBufferUsage_Vertex, init_p.data()); + ResourceBinding cb[] = {{particles_buffer_, WGPUBufferBindingType_Storage}, + {uniforms_, WGPUBufferBindingType_Uniform}}; compute_pass_ = gpu_create_compute_pass(device, particle_compute_wgsl, cb, 2); compute_pass_.workgroup_size_x = (NUM_PARTICLES + 63) / 64; - ResourceBinding rb[] = {{particles_buffer_, WGPUBufferBindingType_ReadOnlyStorage}, {uniforms_, WGPUBufferBindingType_Uniform}}; - render_pass_ = gpu_create_render_pass(device, format, particle_render_wgsl, rb, 2); - render_pass_.vertex_count = 6; render_pass_.instance_count = NUM_PARTICLES; + ResourceBinding rb[] = { + {particles_buffer_, WGPUBufferBindingType_ReadOnlyStorage}, + {uniforms_, WGPUBufferBindingType_Uniform}}; + render_pass_ = + gpu_create_render_pass(device, format, particle_render_wgsl, rb, 2); + render_pass_.vertex_count = 6; + render_pass_.instance_count = NUM_PARTICLES; } -void ParticlesEffect::compute(WGPUCommandEncoder e, float t, float b, float i, float a) { - struct { float p, a, t, d; } u = {i, a, t, 0.0f}; +void ParticlesEffect::compute(WGPUCommandEncoder e, float t, float b, float i, + float a) { + struct { + float p, a, t, d; + } u = {i, a, t, 0.0f}; wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); WGPUComputePassEncoder pass = wgpuCommandEncoderBeginComputePass(e, nullptr); wgpuComputePassEncoderSetPipeline(pass, compute_pass_.pipeline); - wgpuComputePassEncoderSetBindGroup(pass, 0, compute_pass_.bind_group, 0, nullptr); - wgpuComputePassEncoderDispatchWorkgroups(pass, compute_pass_.workgroup_size_x, 1, 1); + wgpuComputePassEncoderSetBindGroup(pass, 0, compute_pass_.bind_group, 0, + nullptr); + wgpuComputePassEncoderDispatchWorkgroups(pass, compute_pass_.workgroup_size_x, + 1, 1); wgpuComputePassEncoderEnd(pass); } -void ParticlesEffect::render(WGPURenderPassEncoder pass, float t, float b, float i, float a) { +void ParticlesEffect::render(WGPURenderPassEncoder pass, float t, float b, + float i, float a) { wgpuRenderPassEncoderSetPipeline(pass, render_pass_.pipeline); - wgpuRenderPassEncoderSetBindGroup(pass, 0, render_pass_.bind_group, 0, nullptr); - wgpuRenderPassEncoderDraw(pass, render_pass_.vertex_count, render_pass_.instance_count, 0, 0); + wgpuRenderPassEncoderSetBindGroup(pass, 0, render_pass_.bind_group, 0, + nullptr); + wgpuRenderPassEncoderDraw(pass, render_pass_.vertex_count, + render_pass_.instance_count, 0, 0); } // --- PassthroughEffect --- -PassthroughEffect::PassthroughEffect(WGPUDevice device, WGPUTextureFormat format) : device_(device) { - pipeline_ = create_post_process_pipeline(device, format, passthrough_shader_wgsl); +PassthroughEffect::PassthroughEffect(WGPUDevice device, + WGPUTextureFormat format) + : device_(device) { + pipeline_ = + create_post_process_pipeline(device, format, passthrough_shader_wgsl); } void PassthroughEffect::update_bind_group(WGPUTextureView input_view) { - if (bind_group_) wgpuBindGroupRelease(bind_group_); + if (bind_group_) + wgpuBindGroupRelease(bind_group_); WGPUBindGroupLayout bgl = wgpuRenderPipelineGetBindGroupLayout(pipeline_, 0); - WGPUSamplerDescriptor sd = {}; WGPUSampler sampler = wgpuDeviceCreateSampler(device_, &sd); - WGPUBindGroupEntry bge[2] = {}; bge[0].binding = 0; bge[0].sampler = sampler; bge[1].binding = 1; bge[1].textureView = input_view; - WGPUBindGroupDescriptor bgd = {.layout = bgl, .entryCount = 2, .entries = bge}; + WGPUSamplerDescriptor sd = {}; + WGPUSampler sampler = wgpuDeviceCreateSampler(device_, &sd); + WGPUBindGroupEntry bge[2] = {}; + bge[0].binding = 0; + bge[0].sampler = sampler; + bge[1].binding = 1; + bge[1].textureView = input_view; + WGPUBindGroupDescriptor bgd = { + .layout = bgl, .entryCount = 2, .entries = bge}; bind_group_ = wgpuDeviceCreateBindGroup(device_, &bgd); } // --- MovingEllipseEffect --- -MovingEllipseEffect::MovingEllipseEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : queue_(queue) { - uniforms_ = gpu_create_buffer(device, sizeof(float) * 4, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); +MovingEllipseEffect::MovingEllipseEffect(WGPUDevice device, WGPUQueue queue, + WGPUTextureFormat format) + : queue_(queue) { + uniforms_ = + gpu_create_buffer(device, sizeof(float) * 4, + WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); ResourceBinding bindings[] = {{uniforms_, WGPUBufferBindingType_Uniform}}; - pass_ = gpu_create_render_pass(device, format, ellipse_shader_wgsl, bindings, 1); + pass_ = + gpu_create_render_pass(device, format, ellipse_shader_wgsl, bindings, 1); pass_.vertex_count = 3; } -void MovingEllipseEffect::render(WGPURenderPassEncoder pass, float t, float b, float i, float a) { - struct { float t, b, i, a; } u = {t, b, i, a}; +void MovingEllipseEffect::render(WGPURenderPassEncoder pass, float t, float b, + float i, float a) { + struct { + float t, b, i, a; + } u = {t, b, i, a}; wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); wgpuRenderPassEncoderSetPipeline(pass, pass_.pipeline); wgpuRenderPassEncoderSetBindGroup(pass, 0, pass_.bind_group, 0, nullptr); @@ -313,86 +357,162 @@ void MovingEllipseEffect::render(WGPURenderPassEncoder pass, float t, float b, f } // --- ParticleSprayEffect --- -ParticleSprayEffect::ParticleSprayEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : queue_(queue) { - uniforms_ = gpu_create_buffer(device, sizeof(float) * 4, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); - std::vector<Particle> init_p(NUM_PARTICLES); for (auto &p : init_p) p.pos[3] = 0.0f; - particles_buffer_ = gpu_create_buffer(device, sizeof(Particle) * NUM_PARTICLES, WGPUBufferUsage_Storage | WGPUBufferUsage_Vertex, init_p.data()); - ResourceBinding cb[] = {{particles_buffer_, WGPUBufferBindingType_Storage}, {uniforms_, WGPUBufferBindingType_Uniform}}; - compute_pass_ = gpu_create_compute_pass(device, particle_spray_compute_wgsl, cb, 2); +ParticleSprayEffect::ParticleSprayEffect(WGPUDevice device, WGPUQueue queue, + WGPUTextureFormat format) + : queue_(queue) { + uniforms_ = + gpu_create_buffer(device, sizeof(float) * 4, + WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); + std::vector<Particle> init_p(NUM_PARTICLES); + for (auto &p : init_p) + p.pos[3] = 0.0f; + particles_buffer_ = gpu_create_buffer( + device, sizeof(Particle) * NUM_PARTICLES, + WGPUBufferUsage_Storage | WGPUBufferUsage_Vertex, init_p.data()); + ResourceBinding cb[] = {{particles_buffer_, WGPUBufferBindingType_Storage}, + {uniforms_, WGPUBufferBindingType_Uniform}}; + compute_pass_ = + gpu_create_compute_pass(device, particle_spray_compute_wgsl, cb, 2); compute_pass_.workgroup_size_x = (NUM_PARTICLES + 63) / 64; - ResourceBinding rb[] = {{particles_buffer_, WGPUBufferBindingType_ReadOnlyStorage}, {uniforms_, WGPUBufferBindingType_Uniform}}; - render_pass_ = gpu_create_render_pass(device, format, particle_render_wgsl, rb, 2); - render_pass_.vertex_count = 6; render_pass_.instance_count = NUM_PARTICLES; + ResourceBinding rb[] = { + {particles_buffer_, WGPUBufferBindingType_ReadOnlyStorage}, + {uniforms_, WGPUBufferBindingType_Uniform}}; + render_pass_ = + gpu_create_render_pass(device, format, particle_render_wgsl, rb, 2); + render_pass_.vertex_count = 6; + render_pass_.instance_count = NUM_PARTICLES; } -void ParticleSprayEffect::compute(WGPUCommandEncoder e, float t, float b, float i, float a) { - struct { float i, a, t, b; } u = {i, a, t, b}; +void ParticleSprayEffect::compute(WGPUCommandEncoder e, float t, float b, + float i, float a) { + struct { + float i, a, t, b; + } u = {i, a, t, b}; wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); WGPUComputePassEncoder pass = wgpuCommandEncoderBeginComputePass(e, nullptr); wgpuComputePassEncoderSetPipeline(pass, compute_pass_.pipeline); - wgpuComputePassEncoderSetBindGroup(pass, 0, compute_pass_.bind_group, 0, nullptr); - wgpuComputePassEncoderDispatchWorkgroups(pass, compute_pass_.workgroup_size_x, 1, 1); + wgpuComputePassEncoderSetBindGroup(pass, 0, compute_pass_.bind_group, 0, + nullptr); + wgpuComputePassEncoderDispatchWorkgroups(pass, compute_pass_.workgroup_size_x, + 1, 1); wgpuComputePassEncoderEnd(pass); } -void ParticleSprayEffect::render(WGPURenderPassEncoder pass, float t, float b, float i, float a) { +void ParticleSprayEffect::render(WGPURenderPassEncoder pass, float t, float b, + float i, float a) { wgpuRenderPassEncoderSetPipeline(pass, render_pass_.pipeline); - wgpuRenderPassEncoderSetBindGroup(pass, 0, render_pass_.bind_group, 0, nullptr); + wgpuRenderPassEncoderSetBindGroup(pass, 0, render_pass_.bind_group, 0, + nullptr); wgpuRenderPassEncoderDraw(pass, 6, NUM_PARTICLES, 0, 0); } // --- PostProcess Implementation Helper --- -static void pp_update_bind_group(WGPUDevice device, WGPURenderPipeline pipeline, WGPUBindGroup *bind_group, WGPUTextureView input_view, GpuBuffer uniforms) { - if (*bind_group) wgpuBindGroupRelease(*bind_group); +static void pp_update_bind_group(WGPUDevice device, WGPURenderPipeline pipeline, + WGPUBindGroup *bind_group, + WGPUTextureView input_view, + GpuBuffer uniforms) { + if (*bind_group) + wgpuBindGroupRelease(*bind_group); WGPUBindGroupLayout bgl = wgpuRenderPipelineGetBindGroupLayout(pipeline, 0); - WGPUSamplerDescriptor sd = {}; sd.magFilter = WGPUFilterMode_Linear; sd.minFilter = WGPUFilterMode_Linear; + WGPUSamplerDescriptor sd = {}; + sd.magFilter = WGPUFilterMode_Linear; + sd.minFilter = WGPUFilterMode_Linear; WGPUSampler sampler = wgpuDeviceCreateSampler(device, &sd); WGPUBindGroupEntry bge[3] = {}; - bge[0].binding = 0; bge[0].sampler = sampler; - bge[1].binding = 1; bge[1].textureView = input_view; - bge[2].binding = 2; bge[2].buffer = uniforms.buffer; bge[2].size = uniforms.size; - WGPUBindGroupDescriptor bgd = {.layout = bgl, .entryCount = 3, .entries = bge}; + bge[0].binding = 0; + bge[0].sampler = sampler; + bge[1].binding = 1; + bge[1].textureView = input_view; + bge[2].binding = 2; + bge[2].buffer = uniforms.buffer; + bge[2].size = uniforms.size; + WGPUBindGroupDescriptor bgd = { + .layout = bgl, .entryCount = 3, .entries = bge}; *bind_group = wgpuDeviceCreateBindGroup(device, &bgd); } // --- GaussianBlurEffect --- -GaussianBlurEffect::GaussianBlurEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : device_(device), queue_(queue) { - uniforms_ = gpu_create_buffer(device, sizeof(float) * 4, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); - pipeline_ = create_post_process_pipeline(device, format, gaussian_blur_shader_wgsl); +GaussianBlurEffect::GaussianBlurEffect(WGPUDevice device, WGPUQueue queue, + WGPUTextureFormat format) + : device_(device), queue_(queue) { + uniforms_ = + gpu_create_buffer(device, sizeof(float) * 4, + WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); + pipeline_ = + create_post_process_pipeline(device, format, gaussian_blur_shader_wgsl); } -void GaussianBlurEffect::render(WGPURenderPassEncoder pass, float t, float b, float i, float a) { - struct { float t, b, i, a; } u = {t, b, i, a}; wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); +void GaussianBlurEffect::render(WGPURenderPassEncoder pass, float t, float b, + float i, float a) { + struct { + float t, b, i, a; + } u = {t, b, i, a}; + wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); PostProcessEffect::render(pass, t, b, i, a); } -void GaussianBlurEffect::update_bind_group(WGPUTextureView v) { pp_update_bind_group(device_, pipeline_, &bind_group_, v, uniforms_); } +void GaussianBlurEffect::update_bind_group(WGPUTextureView v) { + pp_update_bind_group(device_, pipeline_, &bind_group_, v, uniforms_); +} // --- SolarizeEffect --- -SolarizeEffect::SolarizeEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : device_(device), queue_(queue) { - uniforms_ = gpu_create_buffer(device, sizeof(float) * 4, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); - pipeline_ = create_post_process_pipeline(device, format, solarize_shader_wgsl); +SolarizeEffect::SolarizeEffect(WGPUDevice device, WGPUQueue queue, + WGPUTextureFormat format) + : device_(device), queue_(queue) { + uniforms_ = + gpu_create_buffer(device, sizeof(float) * 4, + WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); + pipeline_ = + create_post_process_pipeline(device, format, solarize_shader_wgsl); } -void SolarizeEffect::render(WGPURenderPassEncoder pass, float t, float b, float i, float a) { - struct { float t, b, i, a; } u = {t, b, i, a}; wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); +void SolarizeEffect::render(WGPURenderPassEncoder pass, float t, float b, + float i, float a) { + struct { + float t, b, i, a; + } u = {t, b, i, a}; + wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); PostProcessEffect::render(pass, t, b, i, a); } -void SolarizeEffect::update_bind_group(WGPUTextureView v) { pp_update_bind_group(device_, pipeline_, &bind_group_, v, uniforms_); } +void SolarizeEffect::update_bind_group(WGPUTextureView v) { + pp_update_bind_group(device_, pipeline_, &bind_group_, v, uniforms_); +} // --- DistortEffect --- -DistortEffect::DistortEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : device_(device), queue_(queue) { - uniforms_ = gpu_create_buffer(device, sizeof(float) * 4, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); +DistortEffect::DistortEffect(WGPUDevice device, WGPUQueue queue, + WGPUTextureFormat format) + : device_(device), queue_(queue) { + uniforms_ = + gpu_create_buffer(device, sizeof(float) * 4, + WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); pipeline_ = create_post_process_pipeline(device, format, distort_shader_wgsl); } -void DistortEffect::render(WGPURenderPassEncoder pass, float t, float b, float i, float a) { - struct { float t, b, i, a; } u = {t, b, i, a}; wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); +void DistortEffect::render(WGPURenderPassEncoder pass, float t, float b, + float i, float a) { + struct { + float t, b, i, a; + } u = {t, b, i, a}; + wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); PostProcessEffect::render(pass, t, b, i, a); } -void DistortEffect::update_bind_group(WGPUTextureView v) { pp_update_bind_group(device_, pipeline_, &bind_group_, v, uniforms_); } +void DistortEffect::update_bind_group(WGPUTextureView v) { + pp_update_bind_group(device_, pipeline_, &bind_group_, v, uniforms_); +} // --- ChromaAberrationEffect --- -ChromaAberrationEffect::ChromaAberrationEffect(WGPUDevice device, WGPUQueue queue, WGPUTextureFormat format) : device_(device), queue_(queue) { - uniforms_ = gpu_create_buffer(device, sizeof(float) * 4, WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); - pipeline_ = create_post_process_pipeline(device, format, chroma_aberration_shader_wgsl); +ChromaAberrationEffect::ChromaAberrationEffect(WGPUDevice device, + WGPUQueue queue, + WGPUTextureFormat format) + : device_(device), queue_(queue) { + uniforms_ = + gpu_create_buffer(device, sizeof(float) * 4, + WGPUBufferUsage_Uniform | WGPUBufferUsage_CopyDst); + pipeline_ = create_post_process_pipeline(device, format, + chroma_aberration_shader_wgsl); } -void ChromaAberrationEffect::render(WGPURenderPassEncoder pass, float t, float b, float i, float a) { - struct { float t, b, i, a; } u = {t, b, i, a}; wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); +void ChromaAberrationEffect::render(WGPURenderPassEncoder pass, float t, + float b, float i, float a) { + struct { + float t, b, i, a; + } u = {t, b, i, a}; + wgpuQueueWriteBuffer(queue_, uniforms_.buffer, 0, &u, sizeof(u)); PostProcessEffect::render(pass, t, b, i, a); } -void ChromaAberrationEffect::update_bind_group(WGPUTextureView v) { pp_update_bind_group(device_, pipeline_, &bind_group_, v, uniforms_); } +void ChromaAberrationEffect::update_bind_group(WGPUTextureView v) { + pp_update_bind_group(device_, pipeline_, &bind_group_, v, uniforms_); +} |
