2025-11-25 19:54:03 +01:00
|
|
|
|
/*
|
|
|
|
|
|
Crafter®.Graphics
|
2026-03-09 20:10:19 +01:00
|
|
|
|
Copyright (C) 2026 Catcrafts®
|
2025-11-25 19:54:03 +01:00
|
|
|
|
catcrafts.net
|
|
|
|
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
|
|
modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
|
License version 3.0 as published by the Free Software Foundation;
|
|
|
|
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
|
|
Lesser General Public License for more details.
|
|
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
|
License along with this library; if not, write to the Free Software
|
|
|
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
|
|
*/
|
2026-05-01 23:35:37 +02:00
|
|
|
|
module;
|
2026-05-18 02:07:48 +02:00
|
|
|
|
#ifndef CRAFTER_GRAPHICS_WINDOW_DOM
|
2026-05-01 23:35:37 +02:00
|
|
|
|
#include "vulkan/vulkan.h"
|
2026-05-18 02:07:48 +02:00
|
|
|
|
#endif // !CRAFTER_GRAPHICS_WINDOW_DOM
|
2026-05-01 23:35:37 +02:00
|
|
|
|
export module Crafter.Graphics:RTPass;
|
2026-05-18 02:07:48 +02:00
|
|
|
|
#ifndef CRAFTER_GRAPHICS_WINDOW_DOM
|
2025-11-25 19:54:03 +01:00
|
|
|
|
import std;
|
2026-05-01 23:35:37 +02:00
|
|
|
|
import :RenderPass;
|
|
|
|
|
|
import :Window;
|
|
|
|
|
|
import :Device;
|
|
|
|
|
|
import :PipelineRTVulkan;
|
2026-06-03 01:59:54 +00:00
|
|
|
|
import :RenderingElement3D;
|
2025-11-25 19:54:03 +01:00
|
|
|
|
|
|
|
|
|
|
export namespace Crafter {
|
2026-05-01 23:35:37 +02:00
|
|
|
|
struct RTPass : RenderPass {
|
|
|
|
|
|
PipelineRTVulkan* pipeline;
|
2026-03-09 20:10:19 +01:00
|
|
|
|
|
2026-05-01 23:35:37 +02:00
|
|
|
|
RTPass(PipelineRTVulkan* p) : pipeline(p) {}
|
|
|
|
|
|
|
2026-06-03 01:59:54 +00:00
|
|
|
|
void Record(VkCommandBuffer cmd, std::uint32_t frameIdx, Window& window) override {
|
2026-05-01 23:35:37 +02:00
|
|
|
|
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline->pipeline);
|
2026-06-03 01:59:54 +00:00
|
|
|
|
// NVIDIA descriptor-heap AS-read workaround (issue #15 / #7): feed
|
|
|
|
|
|
// the active frame's TLAS device address into the push-constant
|
|
|
|
|
|
// block that VulkanShader synthesizes, so the rewritten raygen can
|
|
|
|
|
|
// reach the acceleration structure by address instead of through
|
|
|
|
|
|
// the faulting heap descriptor. Inert on every other driver.
|
|
|
|
|
|
if (Device::workaroundDescriptorHeapAS) {
|
|
|
|
|
|
VkDeviceAddress tlasAddr = RenderingElement3D::tlases[frameIdx].address;
|
|
|
|
|
|
VkPushDataInfoEXT pushInfo {
|
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PUSH_DATA_INFO_EXT,
|
2026-06-03 02:28:02 +00:00
|
|
|
|
// Where the rewritten raygen reads the TLAS address: 0 when
|
|
|
|
|
|
// VulkanShader synthesized a fresh block, or the offset of
|
|
|
|
|
|
// the member it appended to the shader's existing block.
|
|
|
|
|
|
.offset = Device::workaroundTlasPushOffset,
|
2026-06-03 01:59:54 +00:00
|
|
|
|
.data = { .address = &tlasAddr, .size = sizeof(tlasAddr) },
|
|
|
|
|
|
};
|
|
|
|
|
|
Device::vkCmdPushDataEXT(cmd, &pushInfo);
|
|
|
|
|
|
}
|
2026-05-01 23:35:37 +02:00
|
|
|
|
Device::vkCmdTraceRaysKHR(cmd,
|
|
|
|
|
|
&pipeline->raygenRegion,
|
|
|
|
|
|
&pipeline->missRegion,
|
|
|
|
|
|
&pipeline->hitRegion,
|
|
|
|
|
|
&pipeline->callableRegion,
|
|
|
|
|
|
window.width, window.height, 1);
|
|
|
|
|
|
}
|
2025-11-25 19:54:03 +01:00
|
|
|
|
};
|
2026-05-01 23:35:37 +02:00
|
|
|
|
}
|
2026-05-18 02:07:48 +02:00
|
|
|
|
#endif // !CRAFTER_GRAPHICS_WINDOW_DOM
|
2026-05-18 18:43:30 +02:00
|
|
|
|
|
|
|
|
|
|
#ifdef CRAFTER_GRAPHICS_WINDOW_DOM
|
|
|
|
|
|
import std;
|
|
|
|
|
|
import :RenderPass;
|
|
|
|
|
|
import :Window;
|
|
|
|
|
|
import :WebGPU;
|
|
|
|
|
|
import :PipelineRTWebGPU;
|
|
|
|
|
|
import :RenderingElement3D;
|
|
|
|
|
|
|
|
|
|
|
|
export namespace Crafter {
|
|
|
|
|
|
// DOM-mode RT pass — dispatches the megakernel pipeline at frame Record
|
|
|
|
|
|
// time. Picks up the current TLAS for the frame and the application's
|
|
|
|
|
|
// raygen-side push data (typically empty in v1; pass via window.passes
|
|
|
|
|
|
// wiring if needed later).
|
|
|
|
|
|
struct RTPass : RenderPass {
|
|
|
|
|
|
PipelineRTWebGPU* pipeline;
|
|
|
|
|
|
// Optional per-dispatch push data forwarded after the standard
|
|
|
|
|
|
// RTDispatchHeader. Null means "no extra data".
|
|
|
|
|
|
const void* pushPtr = nullptr;
|
|
|
|
|
|
std::uint32_t pushBytes = 0;
|
2026-05-19 00:27:09 +02:00
|
|
|
|
// Resolved WebGPU resource handles for each user binding the
|
|
|
|
|
|
// pipeline was loaded with, in declaration order. The example
|
|
|
|
|
|
// owns the storage (typically a small std::array of u32). Null /
|
|
|
|
|
|
// 0 means "no user bindings".
|
|
|
|
|
|
const void* handlesPtr = nullptr;
|
|
|
|
|
|
std::uint32_t handlesCount = 0;
|
2026-05-31 16:24:41 +00:00
|
|
|
|
// Wavefront bounce budget: number of (TRACE; SHADE) iterations.
|
|
|
|
|
|
// 1 = primary rays only; 2 = primary + one continuation/shadow
|
|
|
|
|
|
// bounce; etc. The library unrolls GENERATE; (PREP; TRACE; SHADE)
|
|
|
|
|
|
// ×maxDepth; RESOLVE.
|
|
|
|
|
|
std::uint32_t maxDepth = 1;
|
2026-05-18 18:43:30 +02:00
|
|
|
|
|
|
|
|
|
|
RTPass(PipelineRTWebGPU* p) : pipeline(p) {}
|
|
|
|
|
|
|
|
|
|
|
|
void Record(WebGPUCommandEncoderRef /*cmd*/, std::uint32_t frameIdx, Window& window) override {
|
|
|
|
|
|
const std::uint32_t gx = (window.width + 7u) / 8u;
|
|
|
|
|
|
const std::uint32_t gy = (window.height + 7u) / 8u;
|
|
|
|
|
|
auto& tlas = RenderingElement3D::tlases[frameIdx];
|
|
|
|
|
|
WebGPU::wgpuDispatchRT(
|
|
|
|
|
|
pipeline->pipelineHandle,
|
|
|
|
|
|
pushPtr,
|
|
|
|
|
|
static_cast<std::int32_t>(pushBytes),
|
|
|
|
|
|
tlas.buffer.handle,
|
|
|
|
|
|
static_cast<std::int32_t>(tlas.builtInstanceCount),
|
|
|
|
|
|
static_cast<std::int32_t>(gx),
|
2026-05-19 00:27:09 +02:00
|
|
|
|
static_cast<std::int32_t>(gy),
|
|
|
|
|
|
handlesPtr,
|
2026-05-31 16:24:41 +00:00
|
|
|
|
static_cast<std::int32_t>(handlesCount),
|
|
|
|
|
|
static_cast<std::int32_t>(maxDepth));
|
2026-05-18 18:43:30 +02:00
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif // CRAFTER_GRAPHICS_WINDOW_DOM
|