From e8b9d18d05242ee1f6f9de0db8830ff5202d0701 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Mon, 1 Jan 2024 16:01:13 +0300 Subject: [PATCH] WebGPU wrapper wip: add render pass encoder object --- .../psemek/wgpu/compute_pass_encoder.hpp | 2 +- .../include/psemek/wgpu/render_bundle.hpp | 24 +++++ .../psemek/wgpu/render_pass_encoder.hpp | 24 +++++ libs/wgpu/objects-todo | 2 +- libs/wgpu/source/compute_pass_encoder.cpp | 2 +- libs/wgpu/source/render_bundle.cpp | 17 ++++ libs/wgpu/source/render_pass_encoder.cpp | 97 +++++++++++++++++++ 7 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 libs/wgpu/include/psemek/wgpu/render_bundle.hpp create mode 100644 libs/wgpu/source/render_bundle.cpp diff --git a/libs/wgpu/include/psemek/wgpu/compute_pass_encoder.hpp b/libs/wgpu/include/psemek/wgpu/compute_pass_encoder.hpp index 6ed04b8d..52c80f50 100644 --- a/libs/wgpu/include/psemek/wgpu/compute_pass_encoder.hpp +++ b/libs/wgpu/include/psemek/wgpu/compute_pass_encoder.hpp @@ -33,7 +33,7 @@ namespace psemek::wgpu std::optional timestamp_writes = {}; }; - void set_bind_group(std::uint32_t group_index, bind_group group, std::vector dynamic_offsets); + void set_bind_group(std::uint32_t group_index, bind_group group, std::vector const & dynamic_offsets); void set_pipeline(compute_pipeline pipeline); void dispatch_workgroups(geom::vector const & workgroup_count); void dispatch_workgroups_indirect(buffer indirect_buffer, std::uint64_t offset); diff --git a/libs/wgpu/include/psemek/wgpu/render_bundle.hpp b/libs/wgpu/include/psemek/wgpu/render_bundle.hpp new file mode 100644 index 00000000..03daa7be --- /dev/null +++ b/libs/wgpu/include/psemek/wgpu/render_bundle.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include + +namespace psemek::wgpu +{ + + struct render_bundle + : detail::object + { + using detail::object::object; + + static void reference(void * ptr); + static void release(void * ptr); + + private: + explicit render_bundle(void * ptr) + : detail::object(ptr) + {} + + friend struct device; + }; + +} diff --git a/libs/wgpu/include/psemek/wgpu/render_pass_encoder.hpp b/libs/wgpu/include/psemek/wgpu/render_pass_encoder.hpp index 3e09272f..b5ff2e27 100644 --- a/libs/wgpu/include/psemek/wgpu/render_pass_encoder.hpp +++ b/libs/wgpu/include/psemek/wgpu/render_pass_encoder.hpp @@ -3,8 +3,13 @@ #include #include #include +#include +#include +#include +#include #include #include +#include #include #include @@ -72,7 +77,26 @@ namespace psemek::wgpu std::optional timestamp_writes = {}; }; + void set_pipeline(render_pipeline pipeline); + void set_bind_group(std::uint32_t group_index, bind_group group, std::vector const & dynamic_offsets); + void set_vertex_buffer(std::uint32_t slot, buffer buffer, std::uint64_t offset, std::uint64_t size); + void set_index_buffer(buffer buffer, index_format format, std::uint64_t offset, std::uint64_t size); + void set_viewport(geom::box const & viewport); + void set_scissor_rect(geom::box const & rect); + void set_blend_constant(geom::vector const & color); + void set_stencil_reference(std::uint32_t reference); + void draw(std::uint32_t vertex_count, std::uint32_t instance_count, std::uint32_t first_vertex, std::uint32_t first_instance); + void draw_indexed(std::uint32_t index_count, std::uint32_t instance_count, std::uint32_t first_index, std::uint32_t base_vertex, std::uint32_t first_instance); + void draw_indirect(buffer indirect_buffer, std::uint64_t offset); + void draw_indexed_indirect(buffer indirect_buffer, std::uint64_t offset); + void execute_bundles(std::vector const & bundles); + void begin_occlusion_query(std::uint32_t query_index); + void end_occlusion_query(); + void insert_debug_marker(std::string const & marker_label); + void push_debug_group(std::string const & group_label); + void pop_debug_group(); void end(); + void set_label(std::string const & label); static void reference(void * ptr); static void release(void * ptr); diff --git a/libs/wgpu/objects-todo b/libs/wgpu/objects-todo index dc3a08fe..f411c48d 100644 --- a/libs/wgpu/objects-todo +++ b/libs/wgpu/objects-todo @@ -13,7 +13,7 @@ + WGPUQueue WGPURenderBundle WGPURenderBundleEncoder -- WGPURenderPassEncoder ++ WGPURenderPassEncoder + WGPURenderPipeline + WGPUSampler + WGPUShaderModule diff --git a/libs/wgpu/source/compute_pass_encoder.cpp b/libs/wgpu/source/compute_pass_encoder.cpp index 3252a8c0..9f6aa3bf 100644 --- a/libs/wgpu/source/compute_pass_encoder.cpp +++ b/libs/wgpu/source/compute_pass_encoder.cpp @@ -4,7 +4,7 @@ namespace psemek::wgpu { - void compute_pass_encoder::set_bind_group(std::uint32_t group_index, bind_group group, std::vector dynamic_offsets) + void compute_pass_encoder::set_bind_group(std::uint32_t group_index, bind_group group, std::vector const & dynamic_offsets) { wgpuComputePassEncoderSetBindGroup((WGPUComputePassEncoder)get(), group_index, (WGPUBindGroup)group.get(), dynamic_offsets.size(), dynamic_offsets.data()); } diff --git a/libs/wgpu/source/render_bundle.cpp b/libs/wgpu/source/render_bundle.cpp new file mode 100644 index 00000000..5c8dbaf5 --- /dev/null +++ b/libs/wgpu/source/render_bundle.cpp @@ -0,0 +1,17 @@ +#include +#include + +namespace psemek::wgpu +{ + + void render_bundle::reference(void * ptr) + { + wgpuRenderBundleReference((WGPURenderBundle)ptr); + } + + void render_bundle::release(void * ptr) + { + wgpuRenderBundleRelease((WGPURenderBundle)ptr); + } + +} diff --git a/libs/wgpu/source/render_pass_encoder.cpp b/libs/wgpu/source/render_pass_encoder.cpp index f8e11ca2..869adfb1 100644 --- a/libs/wgpu/source/render_pass_encoder.cpp +++ b/libs/wgpu/source/render_pass_encoder.cpp @@ -4,11 +4,108 @@ namespace psemek::wgpu { + void render_pass_encoder::set_pipeline(render_pipeline pipeline) + { + wgpuRenderPassEncoderSetPipeline((WGPURenderPassEncoder)get(), (WGPURenderPipeline)pipeline.get()); + } + + void render_pass_encoder::set_bind_group(std::uint32_t group_index, bind_group group, std::vector const & dynamic_offsets) + { + wgpuRenderPassEncoderSetBindGroup((WGPURenderPassEncoder)get(), group_index, (WGPUBindGroup)group.get(), dynamic_offsets.size(), dynamic_offsets.data()); + } + + void render_pass_encoder::set_vertex_buffer(std::uint32_t slot, buffer buffer, std::uint64_t offset, std::uint64_t size) + { + wgpuRenderPassEncoderSetVertexBuffer((WGPURenderPassEncoder)get(), slot, (WGPUBuffer)buffer.get(), offset, size); + } + + void render_pass_encoder::set_index_buffer(buffer buffer, index_format format, std::uint64_t offset, std::uint64_t size) + { + wgpuRenderPassEncoderSetIndexBuffer((WGPURenderPassEncoder)get(), (WGPUBuffer)buffer.get(), (WGPUIndexFormat)format, offset, size); + } + + void render_pass_encoder::set_viewport(geom::box const & viewport) + { + wgpuRenderPassEncoderSetViewport((WGPURenderPassEncoder)get(), viewport[0].min, viewport[1].min, viewport[0].length(), viewport[1].length(), viewport[2].min, viewport[2].max); + } + + void render_pass_encoder::set_scissor_rect(geom::box const & rect) + { + wgpuRenderPassEncoderSetScissorRect((WGPURenderPassEncoder)get(), rect[0].min, rect[1].min, rect[0].length(), rect[1].length()); + } + + void render_pass_encoder::set_blend_constant(geom::vector const & color) + { + static_assert(sizeof(WGPUColor) == sizeof(color)); + wgpuRenderPassEncoderSetBlendConstant((WGPURenderPassEncoder)get(), (WGPUColor const *)(&color)); + } + + void render_pass_encoder::set_stencil_reference(std::uint32_t reference) + { + wgpuRenderPassEncoderSetStencilReference((WGPURenderPassEncoder)get(), reference); + } + + void render_pass_encoder::draw(std::uint32_t vertex_count, std::uint32_t instance_count, std::uint32_t first_vertex, std::uint32_t first_instance) + { + wgpuRenderPassEncoderDraw((WGPURenderPassEncoder)get(), vertex_count, instance_count, first_vertex, first_instance); + } + + void render_pass_encoder::draw_indexed(std::uint32_t index_count, std::uint32_t instance_count, std::uint32_t first_index, std::uint32_t base_vertex, std::uint32_t first_instance) + { + wgpuRenderPassEncoderDrawIndexed((WGPURenderPassEncoder)get(), index_count, instance_count, first_index, base_vertex, first_instance); + } + + void render_pass_encoder::draw_indirect(buffer indirect_buffer, std::uint64_t offset) + { + wgpuRenderPassEncoderDrawIndirect((WGPURenderPassEncoder)get(), (WGPUBuffer)indirect_buffer.get(), offset); + } + + void render_pass_encoder::draw_indexed_indirect(buffer indirect_buffer, std::uint64_t offset) + { + wgpuRenderPassEncoderDrawIndexedIndirect((WGPURenderPassEncoder)get(), (WGPUBuffer)indirect_buffer.get(), offset); + } + + void render_pass_encoder::execute_bundles(std::vector const & bundles) + { + static_assert(sizeof(WGPURenderBundle) == sizeof(render_bundle)); + wgpuRenderPassEncoderExecuteBundles((WGPURenderPassEncoder)get(), bundles.size(), (WGPURenderBundle const *)bundles.data()); + } + + void render_pass_encoder::begin_occlusion_query(std::uint32_t query_index) + { + wgpuRenderPassEncoderBeginOcclusionQuery((WGPURenderPassEncoder)get(), query_index); + } + + void render_pass_encoder::end_occlusion_query() + { + wgpuRenderPassEncoderEndOcclusionQuery((WGPURenderPassEncoder)get()); + } + + void render_pass_encoder::insert_debug_marker(std::string const & marker_label) + { + wgpuRenderPassEncoderInsertDebugMarker((WGPURenderPassEncoder)get(), marker_label.data()); + } + + void render_pass_encoder::push_debug_group(std::string const & group_label) + { + wgpuRenderPassEncoderPushDebugGroup((WGPURenderPassEncoder)get(), group_label.data()); + } + + void render_pass_encoder::pop_debug_group() + { + wgpuRenderPassEncoderPopDebugGroup((WGPURenderPassEncoder)get()); + } + void render_pass_encoder::end() { wgpuRenderPassEncoderEnd((WGPURenderPassEncoder)get()); } + void render_pass_encoder::set_label(std::string const & label) + { + wgpuRenderPassEncoderSetLabel((WGPURenderPassEncoder)get(), label.data()); + } + void render_pass_encoder::reference(void * ptr) { wgpuRenderPassEncoderReference((WGPURenderPassEncoder)ptr);