Crafter.Graphics/interfaces/Crafter.Graphics-WebGPUBuffer.cppm
2026-05-18 04:58:52 +02:00

85 lines
2.6 KiB
C++

/*
Crafter®.Graphics
Copyright (C) 2026 Catcrafts®
catcrafts.net
*/
// WebGPU buffer wrapper — DOM-mode parallel to VulkanBuffer<T, Mapped>.
// Holds a JS-side GPUBuffer handle + (when Mapped) a wasm-memory staging
// array. `.value` points to the staging memory; the user writes into it
// directly, and `.Flush(cmd)` copies to the GPU via queue.writeBuffer.
export module Crafter.Graphics:WebGPUBuffer;
#ifdef CRAFTER_GRAPHICS_WINDOW_DOM
import std;
import :WebGPU;
export namespace Crafter {
class WebGPUBufferBase {
public:
WebGPUBufferRef handle = 0;
std::uint32_t size = 0; // bytes
};
template<typename T>
class WebGPUBufferMapped {
public:
T* value = nullptr;
};
class WebGPUBufferMappedEmpty {};
template<typename T, bool Mapped>
using WebGPUBufferMappedConditional =
std::conditional_t<Mapped, WebGPUBufferMapped<T>, WebGPUBufferMappedEmpty>;
template<typename T, bool Mapped>
class WebGPUBuffer : public WebGPUBufferBase, public WebGPUBufferMappedConditional<T, Mapped> {
public:
WebGPUBuffer() = default;
WebGPUBuffer(const WebGPUBuffer&) = delete;
WebGPUBuffer& operator=(const WebGPUBuffer&) = delete;
WebGPUBuffer(WebGPUBuffer&& other) noexcept {
handle = other.handle;
size = other.size;
other.handle = 0;
if constexpr (Mapped) {
this->value = other.value;
other.value = nullptr;
}
}
void Create(std::uint32_t count) {
size = static_cast<std::uint32_t>(count * sizeof(T));
handle = WebGPU::wgpuCreateBuffer(static_cast<std::int32_t>(size));
if constexpr (Mapped) {
this->value = new T[count]();
}
}
void Clear() {
if (handle != 0) {
WebGPU::wgpuDestroyBuffer(handle);
handle = 0;
}
if constexpr (Mapped) {
if (this->value) { delete[] this->value; this->value = nullptr; }
}
}
void Resize(std::uint32_t count) {
if (handle != 0) Clear();
Create(count);
}
void Flush(WebGPUCommandEncoderRef /*cmd*/) requires(Mapped) {
WebGPU::wgpuWriteBuffer(handle, this->value, static_cast<std::int32_t>(size));
}
void FlushDevice() requires(Mapped) {
WebGPU::wgpuWriteBuffer(handle, this->value, static_cast<std::int32_t>(size));
}
~WebGPUBuffer() { Clear(); }
};
}
#endif // CRAFTER_GRAPHICS_WINDOW_DOM