WebGPU wrapper wip: add push constants support

This commit is contained in:
Nikita Lisitsa 2024-01-01 17:29:30 +03:00
parent 0a088684d9
commit 082b8e0493
7 changed files with 59 additions and 11 deletions

View file

@ -17,31 +17,47 @@ namespace psemek::wgpu
virtual void * ptr() = 0;
};
template <typename T>
struct empty_storage
{};
template <typename ChainedType, typename StorageType>
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<chained_struct> const & chain);
using chained_struct_ptr = std::shared_ptr<chained_struct_base>;
template <typename T>
chained_struct_ptr make_chained_struct(T const & value)
template <typename ChainedType>
chained_struct_ptr make_chained_struct(ChainedType const & chained)
{
return std::make_shared<chained_struct_impl<T>>(value);
return std::make_shared<chained_struct_impl<ChainedType, empty_storage>>(chained, empty_storage{});
}
template <typename ChainedType, typename StorageType>
chained_struct_ptr make_chained_struct(ChainedType const & chained, StorageType && storage)
{
return std::make_shared<chained_struct_impl<ChainedType, std::remove_cvref_t<StorageType>>>(chained, std::forward<StorageType>(storage));
}
}

View file

@ -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<pipeline_layout>
{
@ -22,6 +29,11 @@ namespace psemek::wgpu
std::vector<bind_group_layout> layouts;
};
struct extras
{
std::vector<push_constant_range> 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);
}

View file

@ -85,6 +85,7 @@ namespace psemek::wgpu
void set_scissor_rect(geom::box<std::uint32_t, 2> const & rect);
void set_blend_constant(geom::vector<double, 4> const & color);
void set_stencil_reference(std::uint32_t reference);
void set_push_constants(shader_stage stages, std::uint32_t offset, util::span<char const> 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);

View file

@ -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);
}

View file

@ -1,5 +1,6 @@
#include <psemek/wgpu/pipeline_layout.hpp>
#include <psemek/wgpu/external/webgpu.h>
#include <psemek/wgpu/external/wgpu.h>
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));
}
}

View file

@ -1,5 +1,6 @@
#include <psemek/wgpu/render_pass_encoder.hpp>
#include <psemek/wgpu/external/webgpu.h>
#include <psemek/wgpu/external/wgpu.h>
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<char const> 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);

View file

@ -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));
}
}