85 lines
2.6 KiB
Text
85 lines
2.6 KiB
Text
|
|
/*
|
||
|
|
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
|