From 20b584b5e0a5bedcef2dd6fea094106fe76ca1fa Mon Sep 17 00:00:00 2001 From: lisyarus Date: Mon, 1 Jan 2024 14:43:12 +0300 Subject: [PATCH] WebGPU wrapper wip: add bind group layout object --- .../include/psemek/wgpu/bind_group_layout.hpp | 81 +++++++++++++++++++ libs/wgpu/include/psemek/wgpu/device.hpp | 2 + .../include/psemek/wgpu/shader_module.hpp | 8 +- .../wgpu/include/psemek/wgpu/shader_stage.hpp | 21 +++++ libs/wgpu/include/psemek/wgpu/texture.hpp | 10 +++ libs/wgpu/objects-todo | 2 +- libs/wgpu/source/bind_group_layout.cpp | 5 ++ libs/wgpu/source/device.cpp | 34 ++++++++ 8 files changed, 155 insertions(+), 8 deletions(-) create mode 100644 libs/wgpu/include/psemek/wgpu/shader_stage.hpp diff --git a/libs/wgpu/include/psemek/wgpu/bind_group_layout.hpp b/libs/wgpu/include/psemek/wgpu/bind_group_layout.hpp index 89403b1e..d9b0726f 100644 --- a/libs/wgpu/include/psemek/wgpu/bind_group_layout.hpp +++ b/libs/wgpu/include/psemek/wgpu/bind_group_layout.hpp @@ -1,15 +1,96 @@ #pragma once #include +#include +#include +#include +#include + +#include +#include namespace psemek::wgpu { + enum class buffer_binding_type : std::uint32_t + { + undefined = 0x00000000, + uniform = 0x00000001, + storage = 0x00000002, + read_only_storage = 0x00000003, + }; + + struct buffer_binding_layout + { + std::vector chain = {}; + buffer_binding_type type = buffer_binding_type::undefined; + bool has_dynamic_offset = false; + std::uint64_t min_binding_size = 0; + }; + + enum class sampler_binding_type : std::uint32_t + { + undefined = 0x00000000, + filtering = 0x00000001, + nonfiltering = 0x00000002, + comparison = 0x00000003, + }; + + struct sampler_binding_layout + { + std::vector chain = {}; + sampler_binding_type type = sampler_binding_type::undefined; + }; + + struct texture_binding_layout + { + std::vector chain = {}; + texture::sample_type sample_type = texture::sample_type::undefined; + texture_view::dimension view_dimension = texture_view::dimension::undefined; + bool multisampled = false; + }; + + enum class storage_texture_access : std::uint32_t + { + undefined = 0x00000000, + write_only = 0x00000001, + read_only = 0x00000002, + read_write = 0x00000003, + }; + + struct storage_texture_binding_layout + { + std::vector chain = {}; + storage_texture_access access = storage_texture_access::undefined; + texture::format format = texture::format::undefined; + texture_view::dimension view_dimension = texture_view::dimension::undefined; + }; + struct bind_group_layout : detail::object { using detail::object::object; + struct entry + { + std::vector chain = {}; + std::uint32_t binding; + shader_stage visibility; + buffer_binding_layout buffer = {}; + sampler_binding_layout sampler = {}; + texture_binding_layout texture = {}; + storage_texture_binding_layout storage_texture = {}; + }; + + struct descriptor + { + std::vector chain = {}; + std::string label = {}; + std::vector entries; + }; + + void set_label(std::string const & label); + static void reference(void * ptr); static void release(void * ptr); diff --git a/libs/wgpu/include/psemek/wgpu/device.hpp b/libs/wgpu/include/psemek/wgpu/device.hpp index 8ee3589c..52b460f3 100644 --- a/libs/wgpu/include/psemek/wgpu/device.hpp +++ b/libs/wgpu/include/psemek/wgpu/device.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -111,6 +112,7 @@ namespace psemek::wgpu queue get_queue(); bind_group create_bind_group(bind_group::descriptor const & desc); + bind_group_layout create_bind_group_layout(bind_group_layout::descriptor const & desc); buffer create_buffer(buffer::descriptor const & desc); command_encoder create_command_encoder(command_encoder::descriptor const & desc); compute_pipeline create_compute_pipeline(compute_pipeline::descriptor const & desc); diff --git a/libs/wgpu/include/psemek/wgpu/shader_module.hpp b/libs/wgpu/include/psemek/wgpu/shader_module.hpp index fb357df1..c943286b 100644 --- a/libs/wgpu/include/psemek/wgpu/shader_module.hpp +++ b/libs/wgpu/include/psemek/wgpu/shader_module.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -13,13 +14,6 @@ namespace psemek::wgpu { - enum class shader_stage { - none = 0x00000000, - vertex = 0x00000001, - fragment = 0x00000002, - compute = 0x00000004, - }; - struct shader_module : detail::object { diff --git a/libs/wgpu/include/psemek/wgpu/shader_stage.hpp b/libs/wgpu/include/psemek/wgpu/shader_stage.hpp new file mode 100644 index 00000000..e5a38c1d --- /dev/null +++ b/libs/wgpu/include/psemek/wgpu/shader_stage.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include + +namespace psemek::wgpu +{ + + enum class shader_stage : std::uint32_t + { + none = 0x00000000, + vertex = 0x00000001, + fragment = 0x00000002, + compute = 0x00000004, + }; + + inline shader_stage operator | (shader_stage s1, shader_stage s2) + { + return static_cast(static_cast(s1) | static_cast(s2)); + } + +} diff --git a/libs/wgpu/include/psemek/wgpu/texture.hpp b/libs/wgpu/include/psemek/wgpu/texture.hpp index a3a165cd..836c80c6 100644 --- a/libs/wgpu/include/psemek/wgpu/texture.hpp +++ b/libs/wgpu/include/psemek/wgpu/texture.hpp @@ -141,6 +141,16 @@ namespace psemek::wgpu depth_only = 0x00000002, }; + enum class sample_type : std::uint32_t + { + undefined = 0x00000000, + _float = 0x00000001, + unfilterable_float = 0x00000002, + depth = 0x00000003, + sint = 0x00000004, + uint = 0x00000005, + }; + struct descriptor { std::vector chain = {}; diff --git a/libs/wgpu/objects-todo b/libs/wgpu/objects-todo index 73721b40..419cc38f 100644 --- a/libs/wgpu/objects-todo +++ b/libs/wgpu/objects-todo @@ -1,6 +1,6 @@ + WGPUAdapter + WGPUBindGroup -- WGPUBindGroupLayout ++ WGPUBindGroupLayout + WGPUBuffer + WGPUCommandBuffer - WGPUCommandEncoder diff --git a/libs/wgpu/source/bind_group_layout.cpp b/libs/wgpu/source/bind_group_layout.cpp index edeee21d..a32e18e5 100644 --- a/libs/wgpu/source/bind_group_layout.cpp +++ b/libs/wgpu/source/bind_group_layout.cpp @@ -4,6 +4,11 @@ namespace psemek::wgpu { + void bind_group_layout::set_label(std::string const & label) + { + wgpuBindGroupLayoutSetLabel((WGPUBindGroupLayout)get(), label.data()); + } + void bind_group_layout::reference(void * ptr) { wgpuBindGroupLayoutReference((WGPUBindGroupLayout)ptr); diff --git a/libs/wgpu/source/device.cpp b/libs/wgpu/source/device.cpp index 3f1129ea..1d28f4c1 100644 --- a/libs/wgpu/source/device.cpp +++ b/libs/wgpu/source/device.cpp @@ -38,6 +38,40 @@ namespace psemek::wgpu return bind_group(wgpuDeviceCreateBindGroup((WGPUDevice)get(), &descriptor)); } + bind_group_layout device::create_bind_group_layout(bind_group_layout::descriptor const & desc) + { + std::vector entries; + for (auto const & entry_in : desc.entries) + { + auto & entry_out = entries.emplace_back(); + entry_out.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(entry_in.chain); + entry_out.binding = entry_in.binding; + entry_out.visibility = (WGPUShaderStageFlags)entry_in.visibility; + entry_out.buffer.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(entry_in.buffer.chain); + entry_out.buffer.type = (WGPUBufferBindingType)entry_in.buffer.type; + entry_out.buffer.hasDynamicOffset = entry_in.buffer.has_dynamic_offset; + entry_out.buffer.minBindingSize = entry_in.buffer.min_binding_size; + entry_out.sampler.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(entry_in.sampler.chain); + entry_out.sampler.type = (WGPUSamplerBindingType)entry_in.sampler.type; + entry_out.texture.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(entry_in.texture.chain); + entry_out.texture.sampleType = (WGPUTextureSampleType)entry_in.texture.sample_type; + entry_out.texture.viewDimension = (WGPUTextureViewDimension)entry_in.texture.view_dimension; + entry_out.texture.multisampled = entry_in.texture.multisampled; + entry_out.storageTexture.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(entry_in.storage_texture.chain); + entry_out.storageTexture.access = (WGPUStorageTextureAccess)entry_in.storage_texture.access; + entry_out.storageTexture.format = (WGPUTextureFormat)entry_in.storage_texture.format; + entry_out.storageTexture.viewDimension = (WGPUTextureViewDimension)entry_in.storage_texture.view_dimension; + } + + WGPUBindGroupLayoutDescriptor descriptor = {}; + descriptor.nextInChain = (WGPUChainedStruct const *)detail::fill_chain(desc.chain); + descriptor.label = desc.label.data(); + descriptor.entryCount = entries.size(); + descriptor.entries = entries.data(); + + return bind_group_layout(wgpuDeviceCreateBindGroupLayout((WGPUDevice)get(), &descriptor)); + } + buffer device::create_buffer(buffer::descriptor const & desc) { WGPUBufferDescriptor descriptor = {};