From 2af6a1000a1d065a75b6312c4e24a92b79e3f0ac Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sat, 30 Dec 2023 22:57:45 +0300 Subject: [PATCH] WebGPU wrapper wip: add buffer object --- libs/wgpu/include/psemek/wgpu/buffer.hpp | 91 ++++++++++++++++++++++++ libs/wgpu/objects-todo | 2 +- libs/wgpu/source/buffer.cpp | 72 +++++++++++++++++++ 3 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 libs/wgpu/include/psemek/wgpu/buffer.hpp create mode 100644 libs/wgpu/source/buffer.cpp diff --git a/libs/wgpu/include/psemek/wgpu/buffer.hpp b/libs/wgpu/include/psemek/wgpu/buffer.hpp new file mode 100644 index 00000000..7d3bce98 --- /dev/null +++ b/libs/wgpu/include/psemek/wgpu/buffer.hpp @@ -0,0 +1,91 @@ +#pragma once + +#include +#include + +#include +#include +#include + +namespace psemek::wgpu +{ + + struct buffer + : detail::object + { + using detail::object::object; + + enum usage : std::uint32_t + { + none = 0x00000000, + map_read = 0x00000001, + map_write = 0x00000002, + copy_src = 0x00000004, + copy_dst = 0x00000008, + index = 0x00000010, + vertex = 0x00000020, + uniform = 0x00000040, + storage = 0x00000080, + indirect = 0x00000100, + query_resolve = 0x00000200, + }; + + enum class map_mode : std::uint32_t + { + none = 0x00000000, + read = 0x00000001, + write = 0x00000002, + }; + + enum class map_state : std::uint32_t + { + unmapped = 0x00000000, + pending = 0x00000001, + mapped = 0x00000002, + }; + + enum class map_async_status : std::uint32_t + { + success = 0x00000000, + validation_error = 0x00000001, + unknown = 0x00000002, + device_lost = 0x00000003, + destroyed_before_callback = 0x00000004, + unmapped_before_callback = 0x00000005, + mapping_already_pending = 0x00000006, + offset_out_of_range = 0x00000007, + size_out_of_range = 0x00000008, + }; + + struct descriptor { + std::vector chain = {}; + std::string label = {}; + enum usage usage; + uint64_t size; + bool mapped_at_creation = false; + }; + + using map_callback = std::function; + + void destroy(); + std::uint64_t get_size(); + usage get_usage(); + map_state get_map_state(); + void const * get_const_mapped_range(std::size_t offset, std::size_t size); + void * get_mapped_range(std::size_t offset, std::size_t size); + void map_async(map_mode flags, std::size_t offset, std::size_t size, map_callback const & callback); + void unmap(); + void set_label(std::string const & label); + + static void reference(void * ptr); + static void release(void * ptr); + + private: + explicit buffer(void * ptr) + : detail::object(ptr) + {} + + friend struct device; + }; + +} diff --git a/libs/wgpu/objects-todo b/libs/wgpu/objects-todo index b13145bd..e275df3d 100644 --- a/libs/wgpu/objects-todo +++ b/libs/wgpu/objects-todo @@ -1,7 +1,7 @@ + WGPUAdapter WGPUBindGroup WGPUBindGroupLayout - WGPUBuffer ++ WGPUBuffer WGPUCommandBuffer WGPUCommandEncoder WGPUComputePassEncoder diff --git a/libs/wgpu/source/buffer.cpp b/libs/wgpu/source/buffer.cpp new file mode 100644 index 00000000..f0bab4e1 --- /dev/null +++ b/libs/wgpu/source/buffer.cpp @@ -0,0 +1,72 @@ +#include +#include + +#include + +namespace psemek::wgpu +{ + + void buffer::destroy() + { + wgpuBufferDestroy((WGPUBuffer)get()); + } + + std::uint64_t buffer::get_size() + { + return wgpuBufferGetSize((WGPUBuffer)get()); + } + + buffer::usage buffer::get_usage() + { + return (usage)wgpuBufferGetUsage((WGPUBuffer)get()); + } + + buffer::map_state buffer::get_map_state() + { + return (map_state)wgpuBufferGetMapState((WGPUBuffer)get()); + } + + void const * buffer::get_const_mapped_range(std::size_t offset, std::size_t size) + { + return wgpuBufferGetConstMappedRange((WGPUBuffer)get(), offset, size); + } + + void * buffer::get_mapped_range(std::size_t offset, std::size_t size) + { + return wgpuBufferGetMappedRange((WGPUBuffer)get(), offset, size); + } + + void buffer::map_async(map_mode flags, std::size_t offset, std::size_t size, map_callback const & callback) + { + auto userdata = new map_callback(callback); + + auto real_callback = [](WGPUBufferMapAsyncStatus status, void * userdata) + { + std::unique_ptr callback((map_callback *)userdata); + if (*callback) (*callback)((map_async_status)status); + }; + + wgpuBufferMapAsync((WGPUBuffer)get(), (WGPUMapModeFlags)flags, offset, size, real_callback, userdata); + } + + void buffer::unmap() + { + wgpuBufferUnmap((WGPUBuffer)get()); + } + + void buffer::set_label(std::string const & label) + { + wgpuBufferSetLabel((WGPUBuffer)get(), label.data()); + } + + void buffer::reference(void * ptr) + { + wgpuBufferReference((WGPUBuffer)ptr); + } + + void buffer::release(void * ptr) + { + wgpuBufferRelease((WGPUBuffer)ptr); + } + +}