webgpu triangle
This commit is contained in:
parent
64116cd980
commit
5553ded476
22 changed files with 2107 additions and 42 deletions
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
Crafter®.Graphics
|
||||
Copyright (C) 2026 Catcrafts®
|
||||
catcrafts.net
|
||||
*/
|
||||
|
||||
// DOM-mode TLAS upkeep. BuildTLAS copies the per-element RTInstance into
|
||||
// the host-visible instance buffer (skipping the transform for elements
|
||||
// whose transform is GPU-owned), uploads it, then dispatches the JS-side
|
||||
// TLAS-build compute pass — which consults the per-BLAS records published
|
||||
// at Mesh::Build() time to produce world-space AABBs and inverse
|
||||
// transforms in the format `traceRay` / `rayQuery` consume.
|
||||
|
||||
module;
|
||||
module Crafter.Graphics:RenderingElement3D_implWebGPU;
|
||||
|
||||
import :RenderingElement3D;
|
||||
import :Mesh;
|
||||
import :WebGPU;
|
||||
import :WebGPUBuffer;
|
||||
import std;
|
||||
|
||||
using namespace Crafter;
|
||||
|
||||
std::vector<RenderingElement3D*> RenderingElement3D::elements;
|
||||
|
||||
void RenderingElement3D::Add(RenderingElement3D* e) {
|
||||
e->indexInElements = static_cast<std::uint32_t>(elements.size());
|
||||
elements.push_back(e);
|
||||
}
|
||||
|
||||
void RenderingElement3D::Remove(RenderingElement3D* e) {
|
||||
std::uint32_t idx = e->indexInElements;
|
||||
if (idx == std::numeric_limits<std::uint32_t>::max()) return;
|
||||
std::uint32_t last = static_cast<std::uint32_t>(elements.size() - 1);
|
||||
if (idx != last) {
|
||||
elements[idx] = elements[last];
|
||||
elements[idx]->indexInElements = idx;
|
||||
}
|
||||
elements.pop_back();
|
||||
e->indexInElements = std::numeric_limits<std::uint32_t>::max();
|
||||
}
|
||||
|
||||
void RenderingElement3D::BuildTLAS(WebGPUCommandEncoderRef /*cmd*/, std::uint32_t index) {
|
||||
auto& tlas = tlases[index];
|
||||
const std::uint32_t primitiveCount = static_cast<std::uint32_t>(elements.size());
|
||||
if (primitiveCount == 0) {
|
||||
tlas.builtInstanceCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// (Re)allocate instance + metadata + output TLAS buffers if the count
|
||||
// changed. WebGPUBuffer::Resize destroys and recreates the GPU buffer;
|
||||
// bind-group caches keyed on the buffer handle are invalidated in the
|
||||
// JS bridge automatically.
|
||||
if (primitiveCount != tlas.builtInstanceCount) {
|
||||
tlas.instanceBuffer.Resize(primitiveCount);
|
||||
tlas.metadataBuffer.Resize(primitiveCount);
|
||||
// TLASEntry layout in WGSL is 144 bytes due to vec3 align/pad
|
||||
// rules. Must match the struct declared in the rtWgslTypes
|
||||
// block in additional/dom-webgpu.js.
|
||||
tlas.buffer.Resize(primitiveCount * 144);
|
||||
}
|
||||
|
||||
for (std::uint32_t i = 0; i < primitiveCount; ++i) {
|
||||
auto& dst = tlas.instanceBuffer.value[i];
|
||||
const auto& src = elements[i]->instance;
|
||||
if (elements[i]->transformOwnedByGpu) {
|
||||
// Preserve whatever the GPU compute shader most recently
|
||||
// wrote into dst.transform. Update only the non-transform
|
||||
// fields.
|
||||
dst.instanceCustomIndex = src.instanceCustomIndex;
|
||||
dst.mask = src.mask;
|
||||
dst.instanceShaderBindingTableRecordOffset = src.instanceShaderBindingTableRecordOffset;
|
||||
dst.flags = src.flags;
|
||||
dst.accelerationStructureReference = src.accelerationStructureReference;
|
||||
} else {
|
||||
dst = src;
|
||||
}
|
||||
tlas.metadataBuffer.value[i] = elements[i]->userMetadata;
|
||||
}
|
||||
|
||||
tlas.instanceBuffer.FlushDevice();
|
||||
tlas.metadataBuffer.FlushDevice();
|
||||
|
||||
WebGPU::wgpuBuildTLAS(tlas.instanceBuffer.handle,
|
||||
static_cast<std::int32_t>(primitiveCount),
|
||||
tlas.buffer.handle);
|
||||
|
||||
tlas.builtInstanceCount = primitiveCount;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue