/* Crafter®.Graphics Copyright (C) 2026 Catcrafts® 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; */ // Portable RT types & constants. // // Native: aliases the Vulkan struct so existing code that passes // `RenderingElement3D::instance` directly into vkCmdBuildAccelerationStructuresKHR // is a no-op layout-wise. // DOM: provides a POD with the same byte layout + the same field names, so // user code touching `instance.mask`, `instance.flags`, `instance.transform` // etc. compiles unchanged. // // Flag constants are spelled out as Crafter::kRT* so portable user code can // avoid referencing VK_* on the DOM target. The values match // VkGeometryInstanceFlagBitsKHR / VkRayTracingShaderGroupTypeKHR so the // constants compare-equal on Vulkan if the user wants to mix surfaces. module; #ifndef CRAFTER_GRAPHICS_WINDOW_DOM #include "vulkan/vulkan.h" #endif export module Crafter.Graphics:RT; import std; export namespace Crafter { #ifndef CRAFTER_GRAPHICS_WINDOW_DOM using RTTransformMatrix = VkTransformMatrixKHR; using RTInstance = VkAccelerationStructureInstanceKHR; #else // Mirrors VkTransformMatrixKHR: row-major affine 3x4. struct RTTransformMatrix { float matrix[3][4]; }; static_assert(sizeof(RTTransformMatrix) == 48); // Mirrors VkAccelerationStructureInstanceKHR byte-for-byte. // On WebGPU the `accelerationStructureReference` slot holds the BLAS // handle returned by MeshWebGPU::blasHandle (a u32 widened to u64). struct RTInstance { RTTransformMatrix transform; std::uint32_t instanceCustomIndex : 24; std::uint32_t mask : 8; std::uint32_t instanceShaderBindingTableRecordOffset : 24; std::uint32_t flags : 8; std::uint64_t accelerationStructureReference; }; static_assert(sizeof(RTInstance) == 64); #endif // VkGeometryInstanceFlagBitsKHR mirror. Values verbatim so equal on both. inline constexpr std::uint8_t kRTGeometryInstanceTriangleFacingCullDisable = 0x1; inline constexpr std::uint8_t kRTGeometryInstanceTriangleFlipFacing = 0x2; inline constexpr std::uint8_t kRTGeometryInstanceForceOpaque = 0x4; inline constexpr std::uint8_t kRTGeometryInstanceForceNoOpaque = 0x8; // Hit-group identification. Matches VkRayTracingShaderGroupTypeKHR. // General — raygen / miss / callable // TrianglesHitGroup — closest-hit/any-hit over triangle geometry // ProceduralHitGroup — closest-hit/any-hit + an intersection shader // over AABB (VK_GEOMETRY_TYPE_AABBS_KHR) geometry enum class RTShaderGroupType : std::uint8_t { General = 0, // raygen / miss / callable TrianglesHitGroup = 1, ProceduralHitGroup = 2, }; // Cross-backend description of one entry in the shader-group array // passed to PipelineRT::Init. Mirrors the meaningful subset of // VkRayTracingShaderGroupCreateInfoKHR: per group, the type and the // indices (into the SBT's shader array) for general / closestHit / // anyHit / intersection, with kRTShaderUnused == VK_SHADER_UNUSED_KHR // for "none". `intersectionShader` is only consulted for // ProceduralHitGroup; it names the shader run for each AABB the ray // enters (the analog of VkRayTracingShaderGroupCreateInfoKHR:: // intersectionShader). inline constexpr std::uint32_t kRTShaderUnused = 0xFFFFFFFFu; struct RTShaderGroup { RTShaderGroupType type = RTShaderGroupType::General; std::uint32_t generalShader = kRTShaderUnused; std::uint32_t closestHitShader = kRTShaderUnused; std::uint32_t anyHitShader = kRTShaderUnused; std::uint32_t intersectionShader = kRTShaderUnused; }; }