74 lines
3.5 KiB
C++
74 lines
3.5 KiB
C++
//SPDX-License-Identifier: LGPL-3.0-only
|
|
//SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts®
|
|
|
|
/*
|
|
Crafter®.Graphics
|
|
Copyright (C) 2026 Catcrafts®
|
|
catcrafts.net
|
|
*/
|
|
|
|
// DOM-mode RT pipeline. Mirrors PipelineRTVulkan's surface — Init takes
|
|
// the same kind of (raygen, miss, hit) shader-group spans plus an SBT.
|
|
// The big difference is implementation: there's no native RT pipeline on
|
|
// WebGPU, so Init assembles a single megakernel WGSL by concatenating
|
|
// 1. library prelude (types, bindings, ray-flag constants)
|
|
// 2. user closesthit / anyhit / miss source files
|
|
// 3. library mega-switches dispatched on per-hit hit-group index
|
|
// 4. library helpers (rayAabb / rayTriangle / traverseBlas / traverseTlas)
|
|
// 5. library traceRay function
|
|
// 6. user raygen source files
|
|
// 7. @compute entry calling the registered raygen
|
|
// and hands the result to wgpuLoadRTPipeline.
|
|
//
|
|
// The library WGSL itself lives in additional/dom-webgpu.js (rtWgslPrelude
|
|
// + rtWgslDispatchTemplate). C++ side only knows the substitution markers.
|
|
|
|
export module Crafter.Graphics:PipelineRTWebGPU;
|
|
#ifdef CRAFTER_GRAPHICS_WINDOW_DOM
|
|
import std;
|
|
import :RT;
|
|
import :WebGPU;
|
|
import :ShaderBindingTableWebGPU;
|
|
import :WebGPUComputeShader;
|
|
|
|
export namespace Crafter {
|
|
class PipelineRTWebGPU {
|
|
public:
|
|
std::uint32_t pipelineHandle = 0;
|
|
// Mirror of the bindings handed to Init. Kept for the example /
|
|
// RTPass to consult when packing the handles[] array at dispatch
|
|
// time (one resolved u32 handle per binding, in declaration order).
|
|
std::vector<UICustomBinding> userBindings;
|
|
// True when Init was given a non-default hdrOutputFormat: RESOLVE
|
|
// writes a user storage texture instead of the canvas, and RTPass
|
|
// must supply its handle via RTPass::outTexHandle.
|
|
bool hdrOutput = false;
|
|
|
|
// Build the megakernel pipeline. Groups carry indices into
|
|
// `sbt.shaders`. The library generates one `case` per registered
|
|
// group: closest-hit groups dispatch to their closestHitShader's
|
|
// entryFn, miss groups to their generalShader's entryFn, etc.
|
|
// The `cmd` parameter is unused on WebGPU; kept for API symmetry.
|
|
// `userBindings` declares extra @group(2)+ resources the user's
|
|
// closest-hit / miss / raygen WGSL touches (material SSBOs,
|
|
// albedo textures, samplers).
|
|
// `hdrOutputFormat` defaults to RGBA8Unorm — the canvas ping-pong
|
|
// path, unchanged. Pass RGBA16Float (or another float format) to
|
|
// have RESOLVE write the linear accumulator into a user storage
|
|
// texture instead, for an HDR post-process chain. The app then owns
|
|
// the composite→swapchain pass and must set RTPass::outTexHandle.
|
|
void Init(WebGPUCommandEncoderRef cmd,
|
|
std::span<const RTShaderGroup> raygenGroups,
|
|
std::span<const RTShaderGroup> missGroups,
|
|
std::span<const RTShaderGroup> hitGroups,
|
|
const ShaderBindingTableWebGPU& sbt,
|
|
std::span<const UICustomBinding> bindings = {},
|
|
WebGPUTexelFormat hdrOutputFormat
|
|
= WebGPUTexelFormat::RGBA8Unorm);
|
|
|
|
PipelineRTWebGPU() = default;
|
|
PipelineRTWebGPU(const PipelineRTWebGPU&) = delete;
|
|
PipelineRTWebGPU& operator=(const PipelineRTWebGPU&) = delete;
|
|
};
|
|
}
|
|
#endif // CRAFTER_GRAPHICS_WINDOW_DOM
|