Crafter.Graphics/interfaces/Crafter.Graphics-RenderingElement3D.cppm

89 lines
4 KiB
Text
Raw Normal View History

2026-01-28 01:07:41 +01:00
/*
Crafter®.Graphics
2026-01-28 18:51:11 +01:00
Copyright (C) 2026 Catcrafts®
2026-01-28 01:07:41 +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
*/
module;
2026-05-18 02:07:48 +02:00
#ifndef CRAFTER_GRAPHICS_WINDOW_DOM
2026-03-02 23:53:13 +01:00
#include "vulkan/vulkan.h"
2026-05-18 02:07:48 +02:00
#endif // !CRAFTER_GRAPHICS_WINDOW_DOM
2026-03-09 20:10:19 +01:00
export module Crafter.Graphics:RenderingElement3D;
2026-05-18 02:07:48 +02:00
#ifndef CRAFTER_GRAPHICS_WINDOW_DOM
2026-01-28 01:07:41 +01:00
import std;
2026-01-28 18:51:11 +01:00
import :Mesh;
import :VulkanBuffer;
2026-01-29 20:35:55 +01:00
import Crafter.Math;
2026-04-05 22:53:59 +02:00
import :Window;
2026-01-28 01:07:41 +01:00
export namespace Crafter {
2026-01-29 19:46:53 +01:00
struct TlasWithBuffer {
2026-05-05 23:49:29 +02:00
VkDeviceAddress address = 0;
2026-04-10 22:26:15 +02:00
VulkanBuffer<char, false> buffer;
2026-05-05 23:49:29 +02:00
VkAccelerationStructureKHR accelerationStructure = VK_NULL_HANDLE;
2026-04-10 22:26:15 +02:00
VulkanBuffer<VkAccelerationStructureInstanceKHR, true> instanceBuffer;
2026-04-30 23:15:43 +02:00
VulkanBuffer<char, false> scratchBuffer;
2026-05-05 23:49:29 +02:00
// Parallel to instanceBuffer, indexed by TLAS instance ID. Filled
// from each element's userMetadata during BuildTLAS. Consumers
// (e.g. ray-query collision) bind this in the descriptor heap and
// look up via rayQueryGetIntersectionInstanceIdEXT to recover
// application-side per-instance data without touching the
// Vulkan-mandated instanceCustomIndex (which renderers may already
// use for their own encoding).
VulkanBuffer<std::uint32_t, true> metadataBuffer;
// Last instance count this TLAS was built (not refit) for. When
// elements.size() matches this, BuildTLAS does an in-place refit
// (UPDATE mode) which is dramatically cheaper than a full rebuild
// — refit walks the existing BVH and updates AABBs, while rebuild
// reconstructs the topology from scratch. A change in count forces
// a fresh rebuild because the AS is sized for that primitive count.
std::uint32_t builtInstanceCount = 0;
2026-01-29 19:46:53 +01:00
};
2026-03-09 20:10:19 +01:00
class RenderingElement3D {
2026-01-28 19:16:28 +01:00
public:
VkAccelerationStructureInstanceKHR instance;
2026-05-05 23:49:29 +02:00
// Position in `elements`, maintained by Add/Remove for O(1) swap-and-pop.
// Sentinel value = not currently registered.
std::uint32_t indexInElements = std::numeric_limits<std::uint32_t>::max();
// Application-defined per-instance tag, copied verbatim into
// tlases[*].metadataBuffer at this element's TLAS instance ID
// every BuildTLAS. Crafter doesn't interpret it.
std::uint32_t userMetadata = 0;
// When true, BuildTLAS skips copying instance.transform into the
// TLAS instance buffer — the application's compute shader writes
// the transform field directly into instanceBuffer at this
// element's TLAS instance ID. Other instance fields (mask,
// customIndex, SBT offset, BLAS reference) are still copied from
// the CPU instance struct.
//
// Used to take per-frame transform updates off the CPU for bodies
// whose transforms derive from GPU-side state (physics nodes that
// already live on the GPU).
bool transformOwnedByGpu = false;
2026-03-09 20:10:19 +01:00
static std::vector<RenderingElement3D*> elements;
2026-04-05 22:53:59 +02:00
inline static TlasWithBuffer tlases[Window::numFrames];
2026-01-29 19:46:53 +01:00
static void BuildTLAS(VkCommandBuffer cmd, std::uint32_t index);
2026-05-05 23:49:29 +02:00
// Register / unregister with `elements`. Use these instead of touching
// the vector directly: linear find+erase is O(n) and pathological at
// the body counts physics targets (millions of braces).
static void Add(RenderingElement3D* e);
static void Remove(RenderingElement3D* e);
2026-01-28 18:51:11 +01:00
};
2026-05-18 02:07:48 +02:00
}
#endif // !CRAFTER_GRAPHICS_WINDOW_DOM