From 963bfe317d214d7bfb3d1f1aa3d6ca12599738b4 Mon Sep 17 00:00:00 2001 From: Vanessa Karolek <vaka1997@uni-koblenz.de> Date: Mon, 20 Sep 2021 14:43:33 +0200 Subject: [PATCH] [#92][Doc] add missing docu and edit docu --- include/vkcv/Core.hpp | 4 +- include/vkcv/DescriptorWrites.hpp | 3 + include/vkcv/FeatureManager.hpp | 24 +++++++ include/vkcv/ShaderStage.hpp | 12 ++-- modules/rtx/include/vkcv/rtx/ASManager.hpp | 51 +++++++------- modules/rtx/include/vkcv/rtx/RTX.hpp | 61 +++++++++-------- .../rtx/include/vkcv/rtx/RTXExtensions.hpp | 2 +- modules/rtx/src/vkcv/rtx/ASManager.cpp | 51 ++++---------- modules/rtx/src/vkcv/rtx/RTX.cpp | 36 +++++----- modules/rtx/src/vkcv/rtx/RTXExtensions.cpp | 2 +- modules/scene/src/vkcv/scene/Scene.cpp | 2 +- .../src/vkcv/shader/GLSLCompiler.cpp | 14 ++-- .../resources/shaders/ambientOcclusion.rchit | 2 +- .../resources/shaders/ambientOcclusion.rgen | 66 +++++++++++-------- projects/rtx/src/main.cpp | 36 +++------- projects/rtx/src/teapot.hpp | 35 ++++++---- src/vkcv/Context.cpp | 1 - src/vkcv/Core.cpp | 5 +- src/vkcv/DescriptorManager.cpp | 4 +- src/vkcv/FeatureManager.cpp | 2 - src/vkcv/ShaderProgram.cpp | 1 + 21 files changed, 210 insertions(+), 204 deletions(-) diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index e9fd3eb9..6f5053e9 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -342,8 +342,8 @@ namespace vkcv /** - * Prepares RTXPipeline for Raygeneration by recording the binding Table to the Commandstream. - * Currently only supports closestHit, rayGen and miss shaderstages. + * Prepares the @p rtxPipeline for ray generation by recording the @p shaderBindingTable to the @p cmdStreamHandle. + * Currently only supports @p closestHit, @p rayGen and @c miss shaderstages @c. * @param cmdStreamHandle The command stream handle which receives relevant commands for drawing. * @param rtxPipeline The raytracing pipeline from the RTXModule. * @param rtxPipelineLayout The raytracing pipeline layout from the RTXModule. diff --git a/include/vkcv/DescriptorWrites.hpp b/include/vkcv/DescriptorWrites.hpp index 64f426a7..457e8952 100644 --- a/include/vkcv/DescriptorWrites.hpp +++ b/include/vkcv/DescriptorWrites.hpp @@ -37,6 +37,9 @@ namespace vkcv { SamplerHandle sampler; }; + /** + * @brief Only used for RTX. Used to bind the Acceleration Structure. + */ struct AccelerationDescriptorWrite { inline AccelerationDescriptorWrite(uint32_t binding) : binding(binding) {}; uint32_t binding; diff --git a/include/vkcv/FeatureManager.hpp b/include/vkcv/FeatureManager.hpp index cb4a1f18..e9abd690 100644 --- a/include/vkcv/FeatureManager.hpp +++ b/include/vkcv/FeatureManager.hpp @@ -79,15 +79,39 @@ namespace vkcv { [[nodiscard]] bool checkSupport(const vk::PhysicalDeviceMeshShaderFeaturesNV& features, bool required) const; + /** + * @brief Currently used for RTX. Checks support of the @p vk::PhysicalDeviceVulkan12Features. + * @param features The features. + * @param required True, if the @p features are required, else false. + * @return @p True, if the @p features are supported, else @p false. + */ [[nodiscard]] bool checkSupport(const vk::PhysicalDeviceVulkan12Features& features, bool required) const; + /** + * @brief Currently used for RTX. Checks support of the @p vk::PhysicalDeviceVulkan11Features. + * @param features The features. + * @param required True, if the @p features are required, else false. + * @return @p True, if the @p features are supported, else @p false. + */ [[nodiscard]] bool checkSupport(const vk::PhysicalDeviceVulkan11Features& features, bool required) const; + /** + * @brief Only used for RTX. Checks support of the @p vk::PhysicalDeviceAccelerationStructureFeaturesKHR. + * @param features The features. + * @param required True, if the @p features are required, else false. + * @return @p True, if the @p features are supported, else @p false. + */ [[nodiscard]] bool checkSupport(const vk::PhysicalDeviceAccelerationStructureFeaturesKHR& features, bool required) const; + /** + * @brief Only used for RTX. Checks support of the @p vk::PhysicalDeviceRayTracingPipelineFeaturesKHR. + * @param features The features. + * @param required True, if the @p features are required, else false. + * @return @p True, if the @p features are supported, else @p false. + */ [[nodiscard]] bool checkSupport(const vk::PhysicalDeviceRayTracingPipelineFeaturesKHR& features, bool required) const; diff --git a/include/vkcv/ShaderStage.hpp b/include/vkcv/ShaderStage.hpp index 368cd9ae..0baaaf5b 100644 --- a/include/vkcv/ShaderStage.hpp +++ b/include/vkcv/ShaderStage.hpp @@ -13,12 +13,12 @@ namespace vkcv { COMPUTE = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eCompute), TASK = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eTaskNV), MESH = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eMeshNV), - RAY_GEN = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eRaygenKHR), - RAY_ANY_HIT = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eAnyHitKHR), - RAY_CLOSEST_HIT = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eClosestHitKHR), - RAY_MISS = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eMissKHR), - RAY_INTERSECTION = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eIntersectionKHR), - RAY_CALLABLE = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eCallableKHR) + RAY_GEN = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eRaygenKHR), // RTX + RAY_ANY_HIT = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eAnyHitKHR), // RTX + RAY_CLOSEST_HIT = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eClosestHitKHR), // RTX + RAY_MISS = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eMissKHR), // RTX + RAY_INTERSECTION = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eIntersectionKHR), // RTX + RAY_CALLABLE = static_cast<VkShaderStageFlags>(vk::ShaderStageFlagBits::eCallableKHR) // RTX }; using ShaderStages = vk::Flags<ShaderStage>; diff --git a/modules/rtx/include/vkcv/rtx/ASManager.hpp b/modules/rtx/include/vkcv/rtx/ASManager.hpp index ec49cc6b..0cdb14d1 100644 --- a/modules/rtx/include/vkcv/rtx/ASManager.hpp +++ b/modules/rtx/include/vkcv/rtx/ASManager.hpp @@ -60,23 +60,29 @@ namespace vkcv::rtx { vk::DispatchLoaderDynamic m_rtxDispatcher; /** - TODO - */ + * Creates a command pool. + */ vk::CommandPool createCommandPool(); /** - TODO - */ + * @brief Takes a @p cmdPool, allocates a command buffer and starts recording it. + * @param cmdPool The command pool. + * @return The allocated command buffer. + */ vk::CommandBuffer allocateAndBeginCommandBuffer( vk::CommandPool cmdPool); /** - TODO - */ + * @brief Ends recording, submits, waits, and then frees the @p commandBuffer. + * @param commandPool The command pool. + * @param commandBuffer The command buffer. + */ void submitCommandBuffer(vk::CommandPool commandPool, vk::CommandBuffer& commandBuffer); /** - TODO - */ + * @brief Gets the device address of a @p buffer. + * @param buffer The buffer. + * @return The device address of the @p buffer. + */ vk::DeviceAddress getBufferDeviceAddress(vk::Buffer buffer); /** @@ -102,9 +108,9 @@ namespace vkcv::rtx { ~ASManager(); /** - * @brief Returns a #RTXBuffer object holding data of type uint16_t from given @p data of type uint8_t. - * @param data The input data of type uint8_t. - * @return A @#RTXBuffer object holding @p data. + * @brief Returns a @#RTXBuffer object holding data of type @p T. + * @param data The input data of type @p T. + * @return A @#RTXBuffer object holding @p data of type @p T. */ template<class T> RTXBuffer makeBufferFromData(std::vector<T>& data) { @@ -112,11 +118,6 @@ namespace vkcv::rtx { // first: Staging Buffer creation RTXBuffer stagingBuffer; stagingBuffer.bufferType = RTXBufferType::STAGING; - auto test = sizeof(T); - auto test1 = sizeof(float); - auto test1a = sizeof(uint32_t); - auto test2 = sizeof(data[0]); - auto test3 = data.size(); stagingBuffer.deviceSize = sizeof(T) * data.size(); stagingBuffer.data = data.data(); stagingBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eTransferSrc; @@ -143,17 +144,19 @@ namespace vkcv::rtx { }; /** - * @brief A helper function used by #ASManager::makeBufferFromData. Creates a fully initialized #RTXBuffer object + * @brief A helper function used by @#ASManager::makeBufferFromData. Creates a fully initialized @#RTXBuffer object * from partially specified @p buffer. All missing data of @p buffer will be completed by this function. - * @param buffer The partially specified #RTXBuffer holding that part of information which is required for - * successfully creating a vk::Buffer object. + * @param buffer The partially specified @#RTXBuffer holding that part of information which is required for + * successfully creating a @p vk::Buffer object. */ void createBuffer(RTXBuffer& buffer); /** - * @brief Build a Bottom Level Acceleration Structure (BLAS) object from given @p vertices and @p indices. - * @param[in] vertices The vertex data of type uint8_t. - * @param[in] indices The index data of type uint8_t. + * @brief Build a Bottom Level Acceleration Structure (BLAS) object from given @p vertexBuffer and @p indexBuffer. + * @param[in] vertexBuffer The vertex data. + * @param[in] vertexCount The amount of vertices in @p vertexBuffer. + * @param[in] indexBuffer The index data. + * @param[in] indexCount The amount of indices in @p indexBuffer. */ void buildBLAS(RTXBuffer vertexBuffer, uint32_t vertexCount, RTXBuffer indexBuffer, uint32_t indexCount); @@ -164,8 +167,8 @@ namespace vkcv::rtx { void buildTLAS(); /** - * @brief Returns the top-level acceleration structure buffer. - * @return A @#TopLevelAccelerationStructure object holding the tlas. + * @brief Returns the top-level acceleration structure (TLAS) buffer. + * @return A @#TopLevelAccelerationStructure object holding the TLAS. */ TopLevelAccelerationStructure getTLAS(); diff --git a/modules/rtx/include/vkcv/rtx/RTX.hpp b/modules/rtx/include/vkcv/rtx/RTX.hpp index 78b11853..3712ddb9 100644 --- a/modules/rtx/include/vkcv/rtx/RTX.hpp +++ b/modules/rtx/include/vkcv/rtx/RTX.hpp @@ -14,18 +14,18 @@ namespace vkcv::rtx { ASManager* m_asManager; vk::Pipeline m_pipeline; vk::PipelineLayout m_pipelineLayout; - RTXBuffer m_shaderBindingtableBuffer; + RTXBuffer m_shaderBindingTableBuffer; vk::DeviceSize m_shaderGroupBaseAlignment; public: /** - * TODO - * @brief Initializes the RTXModule with scene data. - * @param core The reference to the #Core. - * @param vertices The scene vertex data of type uint8_t. - * @param indices The scene index data of type uint8_t. - * @param descriptorSetHandles The descriptorSetHandles for RTX + * @brief Initializes the @#RTXModule with scene data. + * @param core The reference to the @#Core. + * @param asManager The reference to the @#ASManager. + * @param vertices The vertex data of the scene. + * @param indices The index data of the scene. + * @param descriptorSetHandles The descriptor set handles for RTX. */ RTXModule(Core* core, ASManager* asManager, std::vector<float>& vertices, std::vector<uint32_t>& indices, std::vector<vkcv::DescriptorSetHandle>& descriptorSetHandles); @@ -36,47 +36,50 @@ namespace vkcv::rtx { ~RTXModule(); /** - * @brief TODO - * @return + * @brief Returns the RTX pipeline. + * @return The RTX pipeline. */ vk::Pipeline getPipeline(); - /** TODO - */ - vk::Buffer getShaderBindingBuffer(); + /** + * @brief Returns the shader binding table buffer. + * @return The shader binding table buffer. + */ + vk::Buffer getShaderBindingTableBuffer(); - /** TODO - */ + /** + * @brief Returns the shader group base alignment for partitioning the shader binding table buffer. + * @return The shader group base alignment. + */ vk::DeviceSize getShaderGroupBaseAlignment(); /** - * @brief TODO - * @return + * @brief Returns the RTX pipeline layout. + * @return The RTX pipeline layout. */ vk::PipelineLayout getPipelineLayout(); - /** TODO - */ + /** + * @brief Sets the shader group base alignment and creates the shader binding table by allocating a shader + * binding table buffer. The allocation depends on @p shaderCount and the shader group base alignment. + * @param shaderCount The amount of shaders to be used for RTX. + */ void createShaderBindingTable(uint32_t shaderCount); /** * @brief Creates Descriptor-Writes for RTX - * @param descriptorSetHandles The descriptorSetHandles for RTX + * @param descriptorSetHandles The descriptorSetHandles for RTX. */ void RTXDescriptors(std::vector<vkcv::DescriptorSetHandle>& descriptorSetHandles); /** - * TODO - * @brief Returns the Vulkan handle of the RTX pipeline. - * @param descriptorSetLayouts The descriptorSetLayouts used for creating a @p vk::PipelineLayoutCreateInfo. - * @param rayGenShader The ray generation shader. - * @param rayMissShader The ray miss shader. - * @param rayClostestHitShader The ray closest hit shader. - * @return The Vulkan handle of the RTX pipeline. + * @brief Creates the RTX pipeline and the RTX pipeline layout. Currently, only RayGen, RayClosestHit and + * RayMiss are supported. + * @param pushConstantSize The size of the push constant used in the RTX shaders. + * @param descriptorSetLayouts The descriptor set layout handles. + * @param rtxShader The RTX shader program. */ - //void createRTXPipeline(uint32_t pushConstantSize, std::vector<DescriptorSetLayoutHandle> descriptorSetLayouts, ShaderProgram &rayGenShader, ShaderProgram &rayMissShader, ShaderProgram &rayClosestHitShader); - - void createRTXPipeline(uint32_t pushConstantSize, std::vector<DescriptorSetLayoutHandle> descriptorSetLayouts, ShaderProgram &rtxShader); + void createRTXPipelineAndLayout(uint32_t pushConstantSize, std::vector<DescriptorSetLayoutHandle> descriptorSetLayouts, ShaderProgram &rtxShader); }; } diff --git a/modules/rtx/include/vkcv/rtx/RTXExtensions.hpp b/modules/rtx/include/vkcv/rtx/RTXExtensions.hpp index b868b568..067428e0 100644 --- a/modules/rtx/include/vkcv/rtx/RTXExtensions.hpp +++ b/modules/rtx/include/vkcv/rtx/RTXExtensions.hpp @@ -8,7 +8,7 @@ class RTXExtensions { private: std::vector<const char*> m_instanceExtensions; // the instance extensions needed for using RTX std::vector<const char*> m_deviceExtensions; // the device extensions needed for using RTX - vkcv::Features m_features; // the features needed to be enabled for using RTX + vkcv::Features m_features; // the features needed to be enabled for using RTX public: RTXExtensions(); diff --git a/modules/rtx/src/vkcv/rtx/ASManager.cpp b/modules/rtx/src/vkcv/rtx/ASManager.cpp index 6501e78e..67bf2048 100644 --- a/modules/rtx/src/vkcv/rtx/ASManager.cpp +++ b/modules/rtx/src/vkcv/rtx/ASManager.cpp @@ -7,12 +7,13 @@ namespace vkcv::rtx { ASManager::ASManager(vkcv::Core *core) : m_core(core), m_device(&(core->getContext().getDevice())){ - // INFO: It seems that we need a dynamic dispatch loader because Vulkan is an ASs ... + // INFO: Using RTX extensions implies that we cannot use the standard dispatcher from Vulkan because using RTX + // specific functions via vk::Device will result in validation errors. Instead we need to use a + // vk::DispatchLoaderDynamic which is used as dispatcher parameter of the device functions. m_rtxDispatcher = vk::DispatchLoaderDynamic( (PFN_vkGetInstanceProcAddr) m_core->getContext().getInstance().getProcAddr("vkGetInstanceProcAddr") ); m_rtxDispatcher.init(m_core->getContext().getInstance()); - // SUGGESTION: recursive call of buildBLAS etc. - + // TODO: Recursive call of buildBLAS for bigger scenes. Currently, the RTX module only supports one mesh. } ASManager::~ASManager() noexcept { @@ -55,7 +56,6 @@ namespace vkcv::rtx { return commandPool; }; - // Allocates and begins a one-time command buffer from the command pool. vk::CommandBuffer ASManager::allocateAndBeginCommandBuffer(vk::CommandPool commandPool) { vk::CommandBufferAllocateInfo commandBufferAllocateInfo{}; @@ -72,7 +72,6 @@ namespace vkcv::rtx { return commandBuffer; } - // Ends recording, submits, waits, and then frees the command buffer. void ASManager::submitCommandBuffer(vk::CommandPool commandPool, vk::CommandBuffer& commandBuffer) { commandBuffer.end(); @@ -90,36 +89,12 @@ namespace vkcv::rtx { m_device->destroyCommandPool(commandPool); } - // Gets the device address of a buffer. vk::DeviceAddress ASManager::getBufferDeviceAddress(vk::Buffer buffer) { vk::BufferDeviceAddressInfo bufferDeviceAddressInfo(buffer); return m_device->getBufferAddress(bufferDeviceAddressInfo); } - - // Find a memory in `memoryTypeBitsRequirement` that includes all of `requiredProperties` - // taken from Vulkan Spec - int32_t findProperties(vk::PhysicalDeviceMemoryProperties* pMemoryProperties, - uint32_t memoryTypeBitsRequirement, - vk::MemoryPropertyFlags requiredProperties) { - const uint32_t memoryCount = pMemoryProperties->memoryTypeCount; - for (uint32_t memoryIndex = 0; memoryIndex < memoryCount; ++memoryIndex) { - const uint32_t memoryTypeBits = (1 << memoryIndex); - const bool isRequiredMemoryType = memoryTypeBitsRequirement & memoryTypeBits; - - const vk::MemoryPropertyFlags properties = - pMemoryProperties->memoryTypes[memoryIndex].propertyFlags; - const bool hasRequiredProperties = - (properties & requiredProperties) == requiredProperties; - - if (isRequiredMemoryType && hasRequiredProperties) - return static_cast<int32_t>(memoryIndex); - } - // failed to find memory type - return -1; - } - void ASManager::createBuffer(RTXBuffer& buffer) { vk::BufferCreateInfo bufferCreateInfo; @@ -140,14 +115,13 @@ namespace vkcv::rtx { uint32_t memoryTypeIndex = -1; for (int i = 0; i < physicalDeviceMemoryProperties.memoryTypeCount; i++) { - if ((memoryRequirements2.memoryRequirements.memoryTypeBits & (1 << i)) && (physicalDeviceMemoryProperties.memoryTypes[i].propertyFlags & buffer.memoryPropertyFlagBits) == buffer.memoryPropertyFlagBits) { + if ((memoryRequirements2.memoryRequirements.memoryTypeBits & (1 << i)) + && (physicalDeviceMemoryProperties.memoryTypes[i].propertyFlags & buffer.memoryPropertyFlagBits) == buffer.memoryPropertyFlagBits) { memoryTypeIndex = i; break; } } - - vk::MemoryAllocateInfo memoryAllocateInfo( memoryRequirements2.memoryRequirements.size, // size of allocation in bytes memoryTypeIndex // index identifying a memory type from the memoryTypes array of the vk::PhysicalDeviceMemoryProperties structure. @@ -186,6 +160,7 @@ namespace vkcv::rtx { } void ASManager::buildBLAS(RTXBuffer vertexBuffer, uint32_t vertexCount, RTXBuffer indexBuffer, uint32_t indexCount) { + // TODO: organize hierarchical structure of multiple BLAS vk::DeviceAddress vertexBufferAddress = getBufferDeviceAddress(vertexBuffer.vulkanHandle); vk::DeviceAddress indexBufferAddress = getBufferDeviceAddress(indexBuffer.vulkanHandle); @@ -239,7 +214,7 @@ namespace vkcv::rtx { ); // create buffer for acceleration structure - RTXBuffer blasBuffer; // NOT scratch Buffer + RTXBuffer blasBuffer; blasBuffer.bufferType = RTXBufferType::ACCELERATION; blasBuffer.deviceSize = asBuildSizesInfo.accelerationStructureSize; blasBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eAccelerationStructureStorageKHR @@ -308,7 +283,9 @@ namespace vkcv::rtx { } void ASManager::buildTLAS() { - // We need an the device address of each BLAS --> TODO: for loop + // TODO: organize hierarchical structure of multiple BLAS + + // We need an the device address of each BLAS --> TODO: for loop for bigger scenes vk::AccelerationStructureDeviceAddressInfoKHR addressInfo( m_bottomLevelAccelerationStructures[0].vulkanHandle ); @@ -389,18 +366,18 @@ namespace vkcv::rtx { {} // vk::GeometryFlagsKHR flags_ = {} ); - // Finally, create the TLAS (--> ASs) + // Finally, create the TLAS vk::AccelerationStructureBuildGeometryInfoKHR asBuildInfo( vk::AccelerationStructureTypeKHR::eTopLevel, // type of the AS: bottom vs. top vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace, // some flags for different purposes, e.g. efficiency vk::BuildAccelerationStructureModeKHR::eBuild, // AS mode: build vs. update {}, // src AS (this seems to be for copying AS) {}, // dst AS (this seems to be for copying AS) - 1, // the geometryCount. TODO: how many do we need? + 1, // the geometryCount. &asGeometry // the next input entry would be a pointer to a pointer to geometries. Maybe geometryCount depends on the next entry? ); - // Query the worst -case AS size and scratch space size based on the number of instances (in this case, 1). + // Query the worst-case AS size and scratch space size based on the number of instances (in this case, 1). vk::AccelerationStructureBuildSizesInfoKHR asSizeInfo; m_core->getContext().getDevice().getAccelerationStructureBuildSizesKHR( vk::AccelerationStructureBuildTypeKHR::eDevice, diff --git a/modules/rtx/src/vkcv/rtx/RTX.cpp b/modules/rtx/src/vkcv/rtx/RTX.cpp index 7a8e48ff..6a64b442 100644 --- a/modules/rtx/src/vkcv/rtx/RTX.cpp +++ b/modules/rtx/src/vkcv/rtx/RTX.cpp @@ -19,8 +19,8 @@ namespace vkcv::rtx { { m_core->getContext().getDevice().destroy(m_pipeline); m_core->getContext().getDevice().destroy(m_pipelineLayout); - m_core->getContext().getDevice().destroy(m_shaderBindingtableBuffer.vulkanHandle); - m_core->getContext().getDevice().freeMemory(m_shaderBindingtableBuffer.deviceMemory); + m_core->getContext().getDevice().destroy(m_shaderBindingTableBuffer.vulkanHandle); + m_core->getContext().getDevice().freeMemory(m_shaderBindingTableBuffer.deviceMemory); } void RTXModule::createShaderBindingTable(uint32_t shaderCount) { @@ -32,14 +32,14 @@ namespace vkcv::rtx { m_core->getContext().getPhysicalDevice().getProperties2(&physicalProperties); vk::DeviceSize shaderBindingTableSize = rayTracingProperties.shaderGroupHandleSize * shaderCount; - - - m_shaderBindingtableBuffer.bufferType = RTXBufferType::SHADER_BINDING; - m_shaderBindingtableBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eShaderBindingTableKHR | vk::BufferUsageFlagBits::eShaderDeviceAddressKHR; - m_shaderBindingtableBuffer.memoryPropertyFlagBits = vk::MemoryPropertyFlagBits::eHostVisible; - m_shaderBindingtableBuffer.deviceSize = shaderBindingTableSize; - m_asManager->createBuffer(m_shaderBindingtableBuffer); + + m_shaderBindingTableBuffer.bufferType = RTXBufferType::SHADER_BINDING; + m_shaderBindingTableBuffer.bufferUsageFlagBits = vk::BufferUsageFlagBits::eShaderBindingTableKHR | vk::BufferUsageFlagBits::eShaderDeviceAddressKHR; + m_shaderBindingTableBuffer.memoryPropertyFlagBits = vk::MemoryPropertyFlagBits::eHostVisible; + m_shaderBindingTableBuffer.deviceSize = shaderBindingTableSize; + + m_asManager->createBuffer(m_shaderBindingTableBuffer); void* shaderHandleStorage = (void*)malloc(sizeof(uint8_t) * shaderBindingTableSize); @@ -49,13 +49,13 @@ namespace vkcv::rtx { } m_shaderGroupBaseAlignment = rayTracingProperties.shaderGroupBaseAlignment; - uint8_t* mapped = (uint8_t*) m_core->getContext().getDevice().mapMemory(m_shaderBindingtableBuffer.deviceMemory, 0, shaderBindingTableSize); + uint8_t* mapped = (uint8_t*) m_core->getContext().getDevice().mapMemory(m_shaderBindingTableBuffer.deviceMemory, 0, shaderBindingTableSize); for (int i = 0; i < shaderCount; i++) { memcpy(mapped, (uint8_t*)shaderHandleStorage + (i * rayTracingProperties.shaderGroupHandleSize), rayTracingProperties.shaderGroupHandleSize); mapped += m_shaderGroupBaseAlignment; } - m_core->getContext().getDevice().unmapMemory(m_shaderBindingtableBuffer.deviceMemory); + m_core->getContext().getDevice().unmapMemory(m_shaderBindingTableBuffer.deviceMemory); free(shaderHandleStorage); } @@ -113,9 +113,7 @@ namespace vkcv::rtx { m_core->getContext().getDevice().updateDescriptorSets(indexWrite, nullptr); } - void RTXModule::createRTXPipeline(uint32_t pushConstantSize, std::vector<DescriptorSetLayoutHandle> descriptorSetLayouts, ShaderProgram &rtxShader) { - // TODO: maybe all of this must be moved to the vkcv::PipelineManager? If we use scene.recordDrawcalls(), this requires a vkcv::PipelineHandle and not a vk::Pipeline - + void RTXModule::createRTXPipelineAndLayout(uint32_t pushConstantSize, std::vector<DescriptorSetLayoutHandle> descriptorSetLayouts, ShaderProgram &rtxShader) { // -- process vkcv::ShaderProgram into vk::ShaderModule std::vector<char> rayGenShaderCode = rtxShader.getShader(ShaderStage::RAY_GEN).shaderCode; @@ -170,7 +168,7 @@ namespace vkcv::rtx { "main" // const char* pName_ = {}, ); - // ray clostest hit + // ray closest hit vk::PipelineShaderStageCreateInfo rayClosestHitShaderStageInfo( vk::PipelineShaderStageCreateFlags(), // vk::PipelineShaderStageCreateFlags flags_ = {} vk::ShaderStageFlagBits::eClosestHitKHR, // vk::ShaderStageFlagBits stage_ = vk::ShaderStageFlagBits::eVertex, @@ -178,13 +176,13 @@ namespace vkcv::rtx { "main" // const char* pName_ = {}, ); - std::vector<vk::PipelineShaderStageCreateInfo> shaderStages = { // HARD CODED + std::vector<vk::PipelineShaderStageCreateInfo> shaderStages = { // HARD CODED. TODO: Support more shader stages. rayGenShaderStageInfo, rayMissShaderStageInfo, rayClosestHitShaderStageInfo }; // -- PipelineLayouts - std::vector<vk::RayTracingShaderGroupCreateInfoKHR> shaderGroups(3); // HARD CODED + std::vector<vk::RayTracingShaderGroupCreateInfoKHR> shaderGroups(shaderStages.size()); // Ray Gen shaderGroups[0] = vk::RayTracingShaderGroupCreateInfoKHR( vk::RayTracingShaderGroupTypeKHR::eGeneral, // vk::RayTracingShaderGroupTypeKHR type_ = vk::RayTracingShaderGroupTypeKHR::eGeneral @@ -283,9 +281,9 @@ namespace vkcv::rtx { return m_pipeline; } - vk::Buffer RTXModule::getShaderBindingBuffer() + vk::Buffer RTXModule::getShaderBindingTableBuffer() { - return m_shaderBindingtableBuffer.vulkanHandle; + return m_shaderBindingTableBuffer.vulkanHandle; } vk::DeviceSize RTXModule::getShaderGroupBaseAlignment() diff --git a/modules/rtx/src/vkcv/rtx/RTXExtensions.cpp b/modules/rtx/src/vkcv/rtx/RTXExtensions.cpp index 0afd3f4e..59a248ac 100644 --- a/modules/rtx/src/vkcv/rtx/RTXExtensions.cpp +++ b/modules/rtx/src/vkcv/rtx/RTXExtensions.cpp @@ -26,7 +26,7 @@ RTXExtensions::RTXExtensions() m_features.requireExtension(deviceExtension); } - /* FIXME : We must disable features that will be mentioned as "not supported" by the FeatureManager. If every unsupported feature is disabled, this should work. + /* FIXME: We must disable features that will be mentioned as "not supported" by the FeatureManager. If every unsupported feature is disabled, this should work. * Maybe we find a better workaround... */ m_features.requireFeature<vk::PhysicalDeviceVulkan12Features>( diff --git a/modules/scene/src/vkcv/scene/Scene.cpp b/modules/scene/src/vkcv/scene/Scene.cpp index 37261c30..cd02004f 100644 --- a/modules/scene/src/vkcv/scene/Scene.cpp +++ b/modules/scene/src/vkcv/scene/Scene.cpp @@ -132,7 +132,7 @@ namespace vkcv::scene { node.recordDrawcalls(viewProjection, pushConstants, drawcalls, record); } - //vkcv_log(LogLevel::RAW_INFO, "Frustum culling: %lu / %lu", drawcalls.size(), count); + vkcv_log(LogLevel::RAW_INFO, "Frustum culling: %lu / %lu", drawcalls.size(), count); m_core->recordDrawcallsToCmdStream( cmdStream, diff --git a/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp b/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp index 28e92aa1..c639118f 100644 --- a/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp +++ b/modules/shader_compiler/src/vkcv/shader/GLSLCompiler.cpp @@ -56,17 +56,17 @@ namespace vkcv::shader { return EShLangTaskNV; case ShaderStage::MESH: return EShLangMeshNV; - case ShaderStage::RAY_GEN: + case ShaderStage::RAY_GEN: // for RTX return EShLangRayGen; - case ShaderStage::RAY_CLOSEST_HIT: + case ShaderStage::RAY_CLOSEST_HIT: // for RTX return EShLangClosestHit; - case ShaderStage::RAY_MISS: + case ShaderStage::RAY_MISS: // for RTX return EShLangMiss; - case ShaderStage::RAY_INTERSECTION: + case ShaderStage::RAY_INTERSECTION: // for RTX return EShLangIntersect; - case ShaderStage::RAY_ANY_HIT: + case ShaderStage::RAY_ANY_HIT: // for RTX return EShLangAnyHit; - case ShaderStage::RAY_CALLABLE: + case ShaderStage::RAY_CALLABLE: // for RTX return EShLangCallable; default: return EShLangCount; @@ -227,7 +227,7 @@ namespace vkcv::shader { glslang::TShader shader (language); - //configure environment for rt shaders + // configure environment for rtx shaders by adjusting versions of Vulkan and SPIR-V, else rtx shader cannot be compiled. if((shaderStage == ShaderStage::RAY_GEN) || (shaderStage == ShaderStage::RAY_ANY_HIT) || (shaderStage == ShaderStage::RAY_CLOSEST_HIT) || (shaderStage == ShaderStage::RAY_MISS) || (shaderStage == ShaderStage::RAY_INTERSECTION) || (shaderStage == ShaderStage::RAY_CALLABLE)){ diff --git a/projects/rtx/resources/shaders/ambientOcclusion.rchit b/projects/rtx/resources/shaders/ambientOcclusion.rchit index 55bd6531..b073916e 100644 --- a/projects/rtx/resources/shaders/ambientOcclusion.rchit +++ b/projects/rtx/resources/shaders/ambientOcclusion.rchit @@ -10,7 +10,7 @@ layout(location = 0) rayPayloadInEXT Payload { vec3 worldNormal; } payload; -layout(binding = 2, set = 0) uniform accelerationStructureEXT tlas; // top level acceleration structure (for the noobs here (you!)) +layout(binding = 2, set = 0) uniform accelerationStructureEXT tlas; // top level acceleration structure layout(binding = 3, set = 0, scalar) buffer rtxVertices { diff --git a/projects/rtx/resources/shaders/ambientOcclusion.rgen b/projects/rtx/resources/shaders/ambientOcclusion.rgen index 7790ef16..ca74919d 100644 --- a/projects/rtx/resources/shaders/ambientOcclusion.rgen +++ b/projects/rtx/resources/shaders/ambientOcclusion.rgen @@ -3,6 +3,8 @@ #define M_PI 3.1415926535897932384626433832795 +// TODO: credits!!! + // A location for a ray payload (we can have multiple of these) layout(location = 0) rayPayloadEXT Payload { float hitSky; @@ -10,32 +12,36 @@ layout(location = 0) rayPayloadEXT Payload { vec3 worldNormal; } payload; -layout(binding = 0, set = 0, rgba16) uniform image2D outImg; // the output image -> maybe use 16 bit values? -layout(binding = 1, set = 0) uniform accelerationStructureEXT tlas; // top level acceleration structure (for the noobs here (you!)) +layout(binding = 0, set = 0, rgba16) uniform image2D outImg; // the output image -> maybe use 16 bit values? +layout(binding = 1, set = 0) uniform accelerationStructureEXT tlas; // top level acceleration structure layout( push_constant ) uniform constants { vec4 camera_position; // as origin for ray generation vec4 camera_right; // for computing ray direction vec4 camera_up; // for computing ray direction vec4 camera_forward; // for computing ray direction +} camera; - uint frameCount; // resets when camera moves, otherwise frameCount++ -}camera; +uint rngState = gl_LaunchIDEXT.x * 2000 + gl_LaunchIDEXT.y; // each shader call has its own rngState float random(vec2 uv, float seed) { return fract(sin(mod(dot(uv, vec2(12.9898, 78.233)) + 1113.1 * seed, M_PI)) * 43758.5453);; } +/** + * Retrieves pixel information. + * @param[in,out] hitSky Defines if the ray has hit the sky + * @param[in,out] pos The position of intersection + * @param[in,out] norm The normal at the position of intersection + */ void GetPixelInfo(out bool hitSky, out vec3 pos, out vec3 norm){ // Use a camera model to generate a ray for this pixel. - //const vec2 pixelCenter = vec2(gl_LaunchIDEXT.xy) + 0.5; - //const uvec2 resolution = gl_LaunchSizeEXT.xy; vec2 uv = gl_LaunchIDEXT.xy + vec2(random(gl_LaunchIDEXT.xy, 0), random(gl_LaunchIDEXT.xy, 1)); uv /= vec2(gl_LaunchSizeEXT.xy); - uv = vec2(1.0, -1.0) * (uv * 2.0 - 1.0); - //const float fovVerticalSlope = 1.0 / 5.0; + uv = (uv * 2.0 - 1.0) // normalize uv coordinates into Vulkan viewport space + * vec2(1.0, -1.0); // flips y-axis const vec3 orig = camera.camera_position.xyz; - const vec3 dir = normalize((-1) * uv.x * camera.camera_right + uv.y * camera.camera_up + camera.camera_forward).xyz; + const vec3 dir = normalize(uv.x * camera.camera_right + uv.y * camera.camera_up + camera.camera_forward).xyz; // Trace a ray into the scene; get back data in the payload. traceRayEXT(tlas, // Acceleration structure @@ -56,6 +62,11 @@ void GetPixelInfo(out bool hitSky, out vec3 pos, out vec3 norm){ norm = payload.worldNormal; } +/** + * @brief Casts a shadow ray. Returns @p true, if the shadow ray hit the sky. + * @param[in] orig The point of origin of the shadow ray. + * @param[in] dir The direction of the shadow ray. + */ float ShadowRay(vec3 orig, vec3 dir){ payload.hitSky = 0.0f; // Assume ray is occluded traceRayEXT(tlas, // Acceleration structure @@ -72,6 +83,11 @@ float ShadowRay(vec3 orig, vec3 dir){ return payload.hitSky; } +/** + * @brief Computes the offset position at @p worldPosition and its @p normal to avoid self-intersection. + * @param[in] worldPosition The point of intersection. + * @param[in] normal The normal at the point of intersection. + */ vec3 OffsetPositionAlongNormal(vec3 worldPosition, vec3 normal){ // Convert the normal to an integer offset. const float int_scale = 256.0f; @@ -93,8 +109,9 @@ vec3 OffsetPositionAlongNormal(vec3 worldPosition, vec3 normal){ abs(worldPosition.z) < origin ? worldPosition.z + floatScale * normal.z : p_i.z); } -uint rngState = gl_LaunchIDEXT.x * 2000 + gl_LaunchIDEXT.y; - +/** + * @brief Used for creating random float numbers. + */ float StepAndOutputRNGFloat(){ // Condensed version of pcg_output_rxs_m_xs_32_32, with simple conversion to floating-point [0,1]. rngState = rngState * 747796405 + 1; @@ -103,21 +120,25 @@ float StepAndOutputRNGFloat(){ return float(word) / 4294967295.0f; } -// Gets a randomly chosen cosine-weighted direction within the unit hemisphere -// defined by the surface normal. + +/** + * @brief Gets a randomly chosen cosine-weighted direction within the unit hemisphere defined by @p norm. + * @param[in] norm The surface normal. + */ vec3 GetRandCosDir(vec3 norm){ // To generate a cosine-weighted normal, generate a random point on a sphere: float theta = 6.2831853 * StepAndOutputRNGFloat(); // Random in [0, 2pi] float z = 2 * StepAndOutputRNGFloat() - 1.0; // Random in [-1, 1] float r = sqrt(1.0 - z * z); vec3 ptOnSphere = vec3(r * cos(theta), r * sin(theta), z); - // Then add the normal to it and normalize to make it cosine-weighted on a - // hemisphere: + // Then add the normal to it and normalize to make it cosine-weighted on a hemisphere: return normalize(ptOnSphere + norm); } void main(){ + uint rays = 64; // the amount of rays to be casted + uvec2 pixel = gl_LaunchIDEXT.xy; bool pixelIsSky; // Does the pixel show the sky (not an object)? vec3 pos, norm; // AO rays from where? @@ -131,20 +152,9 @@ void main(){ // Compute ambient occlusion pos = OffsetPositionAlongNormal(pos, norm); // Avoid self-intersection float aoColor = 0.0; - for(uint i = 0; i < 64; i++){ // Use 64 rays. - aoColor += ShadowRay(pos, GetRandCosDir(norm)) / 64.0; + for(uint i = 0; i < rays; i++){ + aoColor += ShadowRay(pos, GetRandCosDir(norm)) / rays; } vec4 aoColorVec = vec4(aoColor); - if (camera.frameCount > 0) { - vec4 previousColor = imageLoad(outImg, ivec2(gl_LaunchIDEXT.xy)); - previousColor *= camera.frameCount; - - aoColorVec += previousColor; - aoColorVec /= (camera.frameCount + 1); - } imageStore(outImg, ivec2(pixel), aoColorVec); - - //color=vec4(0.0001*camera.frameCount,0,0,1);//DEBUG - //color=vec4(1,0,0,1);//DEBUG - //imageStore(outImg, ivec2(gl_LaunchIDEXT.xy), color); } diff --git a/projects/rtx/src/main.cpp b/projects/rtx/src/main.cpp index dccf6154..99304c07 100644 --- a/projects/rtx/src/main.cpp +++ b/projects/rtx/src/main.cpp @@ -38,18 +38,13 @@ int main(int argc, const char** argv) { vkcv::WindowHandle windowHandle = core.createWindow(applicationName, windowWidth, windowHeight, false); vkcv::camera::CameraManager cameraManager(core.getWindow(windowHandle)); - uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - uint32_t camIndex1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); - - cameraManager.getCamera(camIndex0).setPosition(glm::vec3(-8, 1, -0.5)); - cameraManager.getCamera(camIndex0).setNearFar(0.1f, 30.0f); - - cameraManager.getCamera(camIndex1).setNearFar(0.1f, 30.0f); + uint32_t camIndex = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); + cameraManager.getCamera(camIndex).setNearFar(0.1f, 30.0f); // get Teapot vertices and indices - std::vector<float> vertices; - std::vector<uint32_t> indices; - Teapot teapot(vertices,indices); + Teapot teapot; + std::vector<float> vertices = teapot.getVertices(); + std::vector<uint32_t> indices = teapot.getIndices(); vkcv::shader::GLSLCompiler compiler; @@ -85,12 +80,11 @@ int main(int argc, const char** argv) { glm::vec4 camera_right; // for computing ray direction glm::vec4 camera_up; // for computing ray direction glm::vec4 camera_forward; // for computing ray direction - glm::uint frameCount; // resets when camera moves, otherwise frameCount++ }; uint32_t pushConstantSize = sizeof(RaytracingPushConstantData); - rtxModule.createRTXPipeline(pushConstantSize, descriptorSetLayoutHandles, rtxShaderProgram); + rtxModule.createRTXPipelineAndLayout(pushConstantSize, descriptorSetLayoutHandles, rtxShaderProgram); vk::Pipeline rtxPipeline = rtxModule.getPipeline(); vk::PipelineLayout rtxPipelineLayout = rtxModule.getPipelineLayout(); @@ -102,11 +96,8 @@ int main(int argc, const char** argv) { vkcv::DescriptorWrites rtxWrites; auto start = std::chrono::system_clock::now(); - uint32_t frameCount = 0; while (vkcv::Window::hasOpenWindow()) { vkcv::Window::pollEvents(); - glm::vec4 camMove1; - glm::vec4 camMove2; if(core.getWindow(windowHandle).getHeight() == 0 || core.getWindow(windowHandle).getWidth() == 0) continue; @@ -133,21 +124,10 @@ int main(int argc, const char** argv) { RaytracingPushConstantData raytracingPushData; raytracingPushData.camera_position = glm::vec4(cameraManager.getActiveCamera().getPosition(),0); - raytracingPushData.camera_right = glm::vec4(glm::cross(cameraManager.getActiveCamera().getFront(), cameraManager.getActiveCamera().getUp()), 0); + raytracingPushData.camera_right = glm::vec4(glm::cross(cameraManager.getActiveCamera().getUp(), cameraManager.getActiveCamera().getFront()), 0); raytracingPushData.camera_up = glm::vec4(cameraManager.getActiveCamera().getUp(),0); raytracingPushData.camera_forward = glm::vec4(cameraManager.getActiveCamera().getFront(),0); - // reset frameCount if camera movement is detected - if (camMove1 != glm::vec4(cameraManager.getActiveCamera().getFront(),0) - || camMove2 != glm::vec4(cameraManager.getActiveCamera().getPosition(),0)){ - raytracingPushData.frameCount = 0; - frameCount = 0; - } else { - raytracingPushData.frameCount = frameCount++; - } - camMove1 = glm::vec4(cameraManager.getActiveCamera().getFront(),0); - camMove2 = glm::vec4(cameraManager.getActiveCamera().getPosition(),0); - vkcv::PushConstants pushConstantsRTX(sizeof(RaytracingPushConstantData)); pushConstantsRTX.appendDrawcall(raytracingPushData); @@ -162,7 +142,7 @@ int main(int argc, const char** argv) { cmdStream, rtxPipeline, rtxPipelineLayout, - rtxModule.getShaderBindingBuffer(), + rtxModule.getShaderBindingTableBuffer(), rtxModule.getShaderGroupBaseAlignment(), { vkcv::DescriptorSetUsage(0, core.getDescriptorSet(rtxShaderDescriptorSet).vulkanHandle)}, pushConstantsRTX, diff --git a/projects/rtx/src/teapot.hpp b/projects/rtx/src/teapot.hpp index 6225c25d..1f35400a 100644 --- a/projects/rtx/src/teapot.hpp +++ b/projects/rtx/src/teapot.hpp @@ -4,27 +4,34 @@ class Teapot { public: /** - * constructor fills given vectors @p vertices and @p indices with vertex data and index data respectively - * @param vertices - * @param indices + * @brief The default constructor. */ - Teapot(std::vector<float> &vertices, std::vector<uint32_t> &indices) { - for (size_t i = 0; i < std::size(m_teapotVertices); i++) { - vertices.push_back(m_teapotVertices[i]); - } - for (size_t i = 0; i < std::size(m_teapotIndices); i++) { - indices.push_back(m_teapotIndices[i]); - } - }; + Teapot() = default; /** * default destructor */ - ~Teapot()=default; + ~Teapot() = default; + + /** + * @brief Returns the vertex data of the teapot. + * @return The vertex data of the teapot. + */ + std::vector<float> getVertices() { + return m_teapotVertices; + } + + /** + * @brief Returns the index data of the teapot. + * @return The index data of the teapot. + */ + std::vector<uint32_t> getIndices() { + return m_teapotIndices; + } private: - float m_teapotVertices[3872 * 3] = + std::vector<float> m_teapotVertices = { 0.69999999f, 0.45000005f, 0.00000001f, 0.69098389f, 0.44999996f, 0.11485600f, @@ -3900,7 +3907,7 @@ private: 1.39999998f, 0.45000005f, 0.00000001f, }; - uint32_t m_teapotIndices[19200] = + std::vector<uint32_t> m_teapotIndices = { 0, 1, 11, 11, 1, 12, 1, 2, 12, 12, 2, 13, diff --git a/src/vkcv/Context.cpp b/src/vkcv/Context.cpp index de960373..60ee3562 100644 --- a/src/vkcv/Context.cpp +++ b/src/vkcv/Context.cpp @@ -326,7 +326,6 @@ namespace vkcv queuePairsTransfer ); - // TODO ?vma::AllocatorCreateFlagBits::eKhrDedicatedAllocation? vma::AllocatorCreateFlags vmaFlags; const vma::AllocatorCreateInfo allocatorCreateInfo ( vma::AllocatorCreateFlags(), diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index d2082bd4..7b097c01 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -436,14 +436,17 @@ namespace vkcv pushConstants.getSizePerDrawcall(), pushConstants.getData()); } + // Define offsets for the RTX shaders. RayGen is the first allocated shader. Each following shader is + // shifted by shaderGroupBaseAlignment. vk::DeviceSize rayGenOffset = 0; vk::DeviceSize missOffset = shaderGroupBaseAlignment; vk::DeviceSize closestHitOffset = 2 * shaderGroupBaseAlignment; - vk::DeviceSize shaderBindingTableSize = shaderGroupBaseAlignment * 3; //4 hardcoded to rtx-shader count + vk::DeviceSize shaderBindingTableSize = shaderGroupBaseAlignment * 3; // 3 hardcoded to rtx-shader count auto m_rtxDispatcher = vk::DispatchLoaderDynamic((PFN_vkGetInstanceProcAddr)m_Context.getInstance().getProcAddr("vkGetInstanceProcAddr")); m_rtxDispatcher.init(m_Context.getInstance()); + // Create regions for the shader binding table buffer which are used for vk::CommandBuffer::traceRaysKHR vk::StridedDeviceAddressRegionKHR rgenRegion; vk::BufferDeviceAddressInfoKHR shaderBindingTableAddressInfo(shaderBindingTable); rgenRegion.deviceAddress = m_Context.getDevice().getBufferAddressKHR(shaderBindingTableAddressInfo, m_rtxDispatcher) + rayGenOffset; diff --git a/src/vkcv/DescriptorManager.cpp b/src/vkcv/DescriptorManager.cpp index 1b471d61..69a35685 100644 --- a/src/vkcv/DescriptorManager.cpp +++ b/src/vkcv/DescriptorManager.cpp @@ -15,8 +15,8 @@ namespace vkcv vk::DescriptorPoolSize(vk::DescriptorType::eUniformBuffer, 1000), vk::DescriptorPoolSize(vk::DescriptorType::eStorageBuffer, 1000), vk::DescriptorPoolSize(vk::DescriptorType::eUniformBufferDynamic, 1000), - vk::DescriptorPoolSize(vk::DescriptorType::eStorageBufferDynamic, 1000), - vk::DescriptorPoolSize(vk::DescriptorType::eAccelerationStructureKHR, 1000) + vk::DescriptorPoolSize(vk::DescriptorType::eStorageBufferDynamic, 1000), // for RTX + vk::DescriptorPoolSize(vk::DescriptorType::eAccelerationStructureKHR, 1000) // for RTX }; m_PoolInfo = vk::DescriptorPoolCreateInfo( diff --git a/src/vkcv/FeatureManager.cpp b/src/vkcv/FeatureManager.cpp index 2800058e..2dd5585d 100644 --- a/src/vkcv/FeatureManager.cpp +++ b/src/vkcv/FeatureManager.cpp @@ -362,8 +362,6 @@ m_physicalDevice.getFeatures2(&query) vkcv_check_feature(variablePointers); vkcv_check_feature(variablePointersStorageBuffer); - // TODO: (Validation Error) if using VulkanFeatures11, disable VkPhysicalDevice16BitStorageFeatures - return true; } diff --git a/src/vkcv/ShaderProgram.cpp b/src/vkcv/ShaderProgram.cpp index 65e4cab5..4d2165aa 100644 --- a/src/vkcv/ShaderProgram.cpp +++ b/src/vkcv/ShaderProgram.cpp @@ -254,6 +254,7 @@ namespace vkcv { } } + // Used to reflect acceleration structure bindings for RTX. for (uint32_t i = 0; i < resources.acceleration_structures.size(); i++) { auto& u = resources.acceleration_structures[i]; const spirv_cross::SPIRType& base_type = comp.get_type(u.base_type_id); -- GitLab