/* * Extended sample base class for ray tracing based samples * * Copyright (C) 2020-2025 by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ #pragma once #include "vulkan/vulkan.h" #include "vulkanexamplebase.h" #include "VulkanTools.h" #include "VulkanDevice.h" // Base sample class with added features specific to hardware ray traced samples class VulkanRaytracingSample : public VulkanExampleBase { protected: // Update the default render pass with different color attachment load ops virtual void setupRenderPass(); virtual void setupFrameBuffer(); public: // Function pointers for ray tracing related stuff PFN_vkGetBufferDeviceAddressKHR vkGetBufferDeviceAddressKHR{ nullptr }; PFN_vkCreateAccelerationStructureKHR vkCreateAccelerationStructureKHR{ nullptr }; PFN_vkDestroyAccelerationStructureKHR vkDestroyAccelerationStructureKHR{ nullptr }; PFN_vkGetAccelerationStructureBuildSizesKHR vkGetAccelerationStructureBuildSizesKHR{ nullptr }; PFN_vkGetAccelerationStructureDeviceAddressKHR vkGetAccelerationStructureDeviceAddressKHR{ nullptr }; PFN_vkBuildAccelerationStructuresKHR vkBuildAccelerationStructuresKHR{ nullptr }; PFN_vkCmdBuildAccelerationStructuresKHR vkCmdBuildAccelerationStructuresKHR{ nullptr }; PFN_vkCmdTraceRaysKHR vkCmdTraceRaysKHR{ nullptr }; PFN_vkGetRayTracingShaderGroupHandlesKHR vkGetRayTracingShaderGroupHandlesKHR{ nullptr }; PFN_vkCreateRayTracingPipelinesKHR vkCreateRayTracingPipelinesKHR{ nullptr }; // Available features and properties VkPhysicalDeviceRayTracingPipelinePropertiesKHR rayTracingPipelineProperties{}; VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationStructureFeatures{}; // Enabled features and properties VkPhysicalDeviceBufferDeviceAddressFeatures enabledBufferDeviceAddresFeatures{}; VkPhysicalDeviceRayTracingPipelineFeaturesKHR enabledRayTracingPipelineFeatures{}; VkPhysicalDeviceAccelerationStructureFeaturesKHR enabledAccelerationStructureFeatures{}; // Holds information for a ray tracing scratch buffer that is used as a temporary storage struct ScratchBuffer { uint64_t deviceAddress{ 0 }; VkBuffer handle{ VK_NULL_HANDLE }; VkDeviceMemory memory{ VK_NULL_HANDLE }; }; // Holds information for a ray tracing acceleration structure struct AccelerationStructure { VkAccelerationStructureKHR handle{ VK_NULL_HANDLE }; uint64_t deviceAddress{ 0 }; VkDeviceMemory memory{ VK_NULL_HANDLE }; VkBuffer buffer{ VK_NULL_HANDLE }; }; // Holds information for a storage image that the ray tracing shaders output to struct StorageImage { VkDeviceMemory memory{ VK_NULL_HANDLE }; VkImage image{ VK_NULL_HANDLE }; VkImageView view{ VK_NULL_HANDLE }; VkFormat format; } storageImage; // Extends the buffer class and holds information for a shader binding table class ShaderBindingTable : public vks::Buffer { public: VkStridedDeviceAddressRegionKHR stridedDeviceAddressRegion{}; }; // Set to true, to denote that the sample only uses ray queries (changes extension and render pass handling) bool rayQueryOnly = false; void enableExtensions(); ScratchBuffer createScratchBuffer(VkDeviceSize size); void deleteScratchBuffer(ScratchBuffer& scratchBuffer); void createAccelerationStructure(AccelerationStructure& accelerationStructure, VkAccelerationStructureTypeKHR type, VkAccelerationStructureBuildSizesInfoKHR buildSizeInfo); void deleteAccelerationStructure(AccelerationStructure& accelerationStructure); uint64_t getBufferDeviceAddress(VkBuffer buffer); void createStorageImage(VkFormat format, VkExtent3D extent); void deleteStorageImage(); VkStridedDeviceAddressRegionKHR getSbtEntryStridedDeviceAddressRegion(VkBuffer buffer, uint32_t handleCount); void createShaderBindingTable(ShaderBindingTable& shaderBindingTable, uint32_t handleCount); // Draw the ImGUI UI overlay using a render pass void drawUI(VkCommandBuffer commandBuffer, VkFramebuffer framebuffer); virtual void prepare(); };