From 082b8e049336996a4ee98b983b4155fa81d3884f Mon Sep 17 00:00:00 2001 From: lisyarus Date: Mon, 1 Jan 2024 17:29:30 +0300 Subject: [PATCH] WebGPU wrapper wip: add push constants support --- .../include/psemek/wgpu/chained_struct.hpp | 32 ++++++++++++++----- .../include/psemek/wgpu/pipeline_layout.hpp | 14 ++++++++ .../psemek/wgpu/render_pass_encoder.hpp | 1 + .../include/psemek/wgpu/shader_module.hpp | 2 +- libs/wgpu/source/pipeline_layout.cpp | 11 +++++++ libs/wgpu/source/render_pass_encoder.cpp | 6 ++++ libs/wgpu/source/shader_module.cpp | 4 +-- 7 files changed, 59 insertions(+), 11 deletions(-) diff --git a/libs/wgpu/include/psemek/wgpu/chained_struct.hpp b/libs/wgpu/include/psemek/wgpu/chained_struct.hpp index 48fcd35e..173f5069 100644 --- a/libs/wgpu/include/psemek/wgpu/chained_struct.hpp +++ b/libs/wgpu/include/psemek/wgpu/chained_struct.hpp @@ -17,31 +17,47 @@ namespace psemek::wgpu virtual void * ptr() = 0; }; - template + struct empty_storage + {}; + + template struct chained_struct_impl : chained_struct_base { - chained_struct_impl(T const & value) - : value_(value) + chained_struct_impl(ChainedType const & chained, StorageType const & storage) + : chained_(chained) + , storage_(std::move(storage)) + {} + + chained_struct_impl(ChainedType const & chained, StorageType && storage) + : chained_(chained) + , storage_(std::move(storage)) {} void * ptr() override { - return &value_; + return &chained_; } private: - T value_; + ChainedType chained_; + StorageType storage_; }; void * fill_chain(std::vector const & chain); using chained_struct_ptr = std::shared_ptr; - template - chained_struct_ptr make_chained_struct(T const & value) + template + chained_struct_ptr make_chained_struct(ChainedType const & chained) { - return std::make_shared>(value); + return std::make_shared>(chained, empty_storage{}); + } + + template + chained_struct_ptr make_chained_struct(ChainedType const & chained, StorageType && storage) + { + return std::make_shared>>(chained, std::forward(storage)); } } diff --git a/libs/wgpu/include/psemek/wgpu/pipeline_layout.hpp b/libs/wgpu/include/psemek/wgpu/pipeline_layout.hpp index 3ccafb9e..fc5c6445 100644 --- a/libs/wgpu/include/psemek/wgpu/pipeline_layout.hpp +++ b/libs/wgpu/include/psemek/wgpu/pipeline_layout.hpp @@ -10,6 +10,13 @@ namespace psemek::wgpu { + struct push_constant_range + { + shader_stage stages; + std::uint32_t start; + std::uint32_t end; + }; + struct pipeline_layout : detail::object { @@ -22,6 +29,11 @@ namespace psemek::wgpu std::vector layouts; }; + struct extras + { + std::vector ranges; + }; + void set_label(std::string const & label); static void reference(void * ptr); @@ -35,4 +47,6 @@ namespace psemek::wgpu friend struct device; }; + detail::chained_struct_ptr to_chained_struct(pipeline_layout::extras && value); + } diff --git a/libs/wgpu/include/psemek/wgpu/render_pass_encoder.hpp b/libs/wgpu/include/psemek/wgpu/render_pass_encoder.hpp index ca5fa3c9..cf34c57a 100644 --- a/libs/wgpu/include/psemek/wgpu/render_pass_encoder.hpp +++ b/libs/wgpu/include/psemek/wgpu/render_pass_encoder.hpp @@ -85,6 +85,7 @@ namespace psemek::wgpu 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 set_push_constants(shader_stage stages, std::uint32_t offset, util::span data); 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 const & indirect_buffer, std::uint64_t offset); diff --git a/libs/wgpu/include/psemek/wgpu/shader_module.hpp b/libs/wgpu/include/psemek/wgpu/shader_module.hpp index c943286b..72c4b7ff 100644 --- a/libs/wgpu/include/psemek/wgpu/shader_module.hpp +++ b/libs/wgpu/include/psemek/wgpu/shader_module.hpp @@ -109,6 +109,6 @@ namespace psemek::wgpu detail::chained_struct_ptr to_chained_struct(shader_module::spirv_descriptor const & value); detail::chained_struct_ptr to_chained_struct(shader_module::wgsl_descriptor const & value); - detail::chained_struct_ptr to_chained_struct(shader_module::glsl_descriptor const & value); + detail::chained_struct_ptr to_chained_struct(shader_module::glsl_descriptor && value); } diff --git a/libs/wgpu/source/pipeline_layout.cpp b/libs/wgpu/source/pipeline_layout.cpp index 67b6d153..03b20f0c 100644 --- a/libs/wgpu/source/pipeline_layout.cpp +++ b/libs/wgpu/source/pipeline_layout.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace psemek::wgpu { @@ -19,4 +20,14 @@ namespace psemek::wgpu wgpuPipelineLayoutRelease((WGPUPipelineLayout)ptr); } + detail::chained_struct_ptr to_chained_struct(pipeline_layout::extras && value) + { + WGPUPipelineLayoutExtras chained = {}; + chained.chain.sType = (WGPUSType)WGPUSType_PipelineLayoutExtras; + static_assert(sizeof(WGPUPushConstantRange) == sizeof(push_constant_range)); + chained.pushConstantRangeCount = value.ranges.size(); + chained.pushConstantRanges = (WGPUPushConstantRange *)value.ranges.data(); + return detail::make_chained_struct(chained, std::move(value)); + } + } diff --git a/libs/wgpu/source/render_pass_encoder.cpp b/libs/wgpu/source/render_pass_encoder.cpp index edb457c1..cba6fb50 100644 --- a/libs/wgpu/source/render_pass_encoder.cpp +++ b/libs/wgpu/source/render_pass_encoder.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace psemek::wgpu { @@ -45,6 +46,11 @@ namespace psemek::wgpu wgpuRenderPassEncoderSetStencilReference((WGPURenderPassEncoder)get(), reference); } + void render_pass_encoder::set_push_constants(shader_stage stages, std::uint32_t offset, util::span data) + { + wgpuRenderPassEncoderSetPushConstants((WGPURenderPassEncoder)get(), (WGPUShaderStageFlags)stages, offset, data.size(), (void *)data.data()); + } + 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); diff --git a/libs/wgpu/source/shader_module.cpp b/libs/wgpu/source/shader_module.cpp index 54192138..f1d434aa 100644 --- a/libs/wgpu/source/shader_module.cpp +++ b/libs/wgpu/source/shader_module.cpp @@ -74,7 +74,7 @@ namespace psemek::wgpu return detail::make_chained_struct(chained); } - detail::chained_struct_ptr to_chained_struct(shader_module::glsl_descriptor const & value) + detail::chained_struct_ptr to_chained_struct(shader_module::glsl_descriptor && value) { WGPUShaderModuleGLSLDescriptor chained = {}; chained.chain.sType = (WGPUSType)WGPUSType_ShaderModuleGLSLDescriptor; @@ -83,7 +83,7 @@ namespace psemek::wgpu chained.defineCount = value.defines.size(); static_assert(sizeof(WGPUShaderDefine) == sizeof(shader_module::define)); chained.defines = (WGPUShaderDefine *)value.defines.data(); - return detail::make_chained_struct(chained); + return detail::make_chained_struct(chained, std::move(value)); } }