RT descriptors

This commit is contained in:
Jorijn van der Graaf 2026-01-29 01:31:17 +01:00
commit e4e7c66808
9 changed files with 160 additions and 59 deletions

View file

@ -30,17 +30,21 @@ import :DescriptorLayoutVulkan;
import Crafter.Event;
export namespace Crafter {
template <std::uint32_t PoolCount, typename... Shaders>
class DescriptorPool {
class DescriptorPoolBase {
public:
inline static Event<void> onDescriptorRefresh;
inline static std::uint32_t setIndex = 0;
inline static std::uint32_t setsCount = 0;
inline static std::vector<VkDescriptorSet> sets;
inline static VkDescriptorPool descriptorPool[PoolCount] = { VK_NULL_HANDLE };
std::vector<VkDescriptorSet> sets;
};
template <std::uint32_t PoolCount, typename... Shaders>
class DescriptorPool : public DescriptorPoolBase {
public:
Event<void> onDescriptorRefresh;
std::uint32_t setIndex = 0;
std::uint32_t setsCount = 0;
VkDescriptorPool descriptorPool[PoolCount] = { VK_NULL_HANDLE };
public:
static void BuildPool(std::uint32_t poolIndex) {
void BuildPool(std::uint32_t poolIndex) {
if(descriptorPool[poolIndex] != VK_NULL_HANDLE) {
vkDestroyDescriptorPool(VulkanDevice::device, descriptorPool[poolIndex], nullptr);
}

View file

@ -26,6 +26,8 @@ export module Crafter.Graphics:PipelineRTVulkan;
import std;
import :VulkanDevice;
import :DescriptorLayoutVulkan;
import :VulkanBuffer;
import :Types;
export namespace Crafter {
template <typename Raygen, typename... Shaders>
@ -33,6 +35,12 @@ export namespace Crafter {
public:
inline static VkPipeline pipeline;
inline static VkPipelineLayout pipelineLayout;
inline static std::vector<std::uint8_t> shaderHandles;
inline static VulkanBuffer<std::uint8_t, true, true, false> sbtBuffer;
inline static VkStridedDeviceAddressRegionKHR raygenRegion;
inline static VkStridedDeviceAddressRegionKHR missRegion;
inline static VkStridedDeviceAddressRegionKHR hitRegion;
inline static VkStridedDeviceAddressRegionKHR callableRegion;
static void Init() {
VkPipelineLayoutCreateInfo pipelineLayoutInfo {
@ -71,7 +79,48 @@ export namespace Crafter {
.layout = pipelineLayout
};
VulkanDevice::vkCreateRayTracingPipelinesKHR(VulkanDevice::device, {}, {}, 1, &rtPipelineInfo, nullptr, &pipeline);
VulkanDevice::CheckVkResult(VulkanDevice::vkCreateRayTracingPipelinesKHR(VulkanDevice::device, {}, {}, 1, &rtPipelineInfo, nullptr, &pipeline));
std::uint32_t handleSize = VulkanDevice::rayTracingProperties.shaderGroupHandleSize;
std::uint32_t handleAlignment = VulkanDevice::rayTracingProperties.shaderGroupHandleAlignment;
std::uint32_t baseAlignment = VulkanDevice::rayTracingProperties.shaderGroupBaseAlignment;
std::uint32_t groupCount = rtPipelineInfo.groupCount;
std::size_t dataSize = handleSize * groupCount;
shaderHandles.resize(dataSize);
VulkanDevice::CheckVkResult(VulkanDevice::vkGetRayTracingShaderGroupHandlesKHR(VulkanDevice::device, pipeline, 0, groupCount, dataSize, shaderHandles.data()));
std::uint32_t raygenSize = AlignUp(handleSize, handleAlignment);
std::uint32_t missSize = AlignUp(handleSize, handleAlignment);
std::uint32_t hitSize = AlignUp(handleSize, handleAlignment);
std::uint32_t callableSize = 0;
std::uint32_t raygenOffset = 0;
std::uint32_t missOffset = AlignUp(raygenSize, baseAlignment);
std::uint32_t hitOffset = AlignUp(missOffset + missSize, baseAlignment);
std::uint32_t callableOffset = AlignUp(hitOffset + hitSize, baseAlignment);
std::size_t bufferSize = callableOffset + callableSize;
sbtBuffer.Create(VK_BUFFER_USAGE_2_SHADER_BINDING_TABLE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferSize);
// Ray generation shader (group 0)
std::memcpy(sbtBuffer.value + raygenOffset, shaderHandles.data() + 0 * handleSize, handleSize);
raygenRegion.deviceAddress = sbtBuffer.address + raygenOffset;
raygenRegion.stride = raygenSize;
raygenRegion.size = raygenSize;
missRegion.deviceAddress = 0;
missRegion.stride = 0;
missRegion.size = 0;
hitRegion.deviceAddress = 0;
hitRegion.stride = 0;
hitRegion.size = 0;
callableRegion.deviceAddress = 0;
callableRegion.stride = 0;
callableRegion.size = 0;
}
};
}

View file

@ -343,6 +343,11 @@ export namespace Crafter {
CrafterKeysMax
};
template <typename T, typename T2>
constexpr T AlignUp(T value, T2 alignment) {
return (value + alignment - 1) & ~(alignment - 1);
}
#ifdef CRAFTER_GRAPHICS_VULKAN
struct DescriptorBinding {
VkDescriptorType type;

View file

@ -45,7 +45,11 @@ export namespace Crafter {
inline static PFN_vkCmdBuildAccelerationStructuresKHR vkCmdBuildAccelerationStructuresKHR;
inline static PFN_vkGetAccelerationStructureDeviceAddressKHR vkGetAccelerationStructureDeviceAddressKHR;
inline static PFN_vkCreateRayTracingPipelinesKHR vkCreateRayTracingPipelinesKHR;
inline static PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR;
inline static VkPhysicalDeviceMemoryProperties memoryProperties;
inline static VkPhysicalDeviceRayTracingPipelinePropertiesKHR rayTracingProperties = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR
};
static void CreateDevice();
static void CheckVkResult(VkResult result);
static std::uint32_t GetMemoryType(std::uint32_t typeBits, VkMemoryPropertyFlags properties);

View file

@ -67,6 +67,9 @@ export module Crafter.Graphics:Window;
import std;
import :Types;
import Crafter.Event;
#ifdef CRAFTER_GRAPHICS_VULKAN
import :PipelineRTVulkan;
#endif
export namespace Crafter {
class Transform;
@ -297,6 +300,7 @@ export namespace Crafter {
xkb_keymap* xkb_keymap;
xkb_context* xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
xkb_state* xkb_state;
std::vector<VkDescriptorSet> descriptorsRt;
void Render();
void QueueRender();
void Resize(std::uint32_t width, std::uint32_t height);
@ -306,6 +310,16 @@ export namespace Crafter {
void SetTitle(const std::string_view title) override;
VkCommandBuffer StartInit();
void FinishInit();
template <typename Raygen, typename... Shaders>
void SetPipelineRT() {
rtPipeline = PipelineRTVulkan<Raygen, Shaders...>::pipeline;
rtPipelineLayout = PipelineRTVulkan<Raygen, Shaders...>::pipelineLayout;
raygenRegion = PipelineRTVulkan<Raygen, Shaders...>::raygenRegion;
missRegion = PipelineRTVulkan<Raygen, Shaders...>::missRegion;
hitRegion = PipelineRTVulkan<Raygen, Shaders...>::hitRegion;
callableRegion = PipelineRTVulkan<Raygen, Shaders...>::callableRegion;
}
inline static wl_compositor* compositor = nullptr;
static void wl_surface_frame_done(void *data, wl_callback *cb, uint32_t time);
static void PointerListenerHandleMotion(void* data, wl_pointer* wl_pointer, uint time, wl_fixed_t surface_x, wl_fixed_t surface_y);
@ -381,7 +395,13 @@ export namespace Crafter {
Semaphores semaphores;
uint32_t currentBuffer = 0;
VkPipelineStageFlags submitPipelineStages = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkRenderPass renderPass = VK_NULL_HANDLE;
//VkRenderPass renderPass = VK_NULL_HANDLE;
VkPipeline rtPipeline;
VkPipelineLayout rtPipelineLayout;
VkStridedDeviceAddressRegionKHR raygenRegion;
VkStridedDeviceAddressRegionKHR missRegion;
VkStridedDeviceAddressRegionKHR hitRegion;
VkStridedDeviceAddressRegionKHR callableRegion;
};
#endif
}