diff options
| author | azhirnov <zh1dron@gmail.com> | 2020-12-08 14:56:12 +0000 |
|---|---|---|
| committer | azhirnov <zh1dron@gmail.com> | 2020-12-09 15:49:14 +0000 |
| commit | 1f9e0a4cd484687c13999d4a6686e104e0a93470 (patch) | |
| tree | d8851006fcedaa7b1db632873f85a9953d9c57a5 /Graphics/GraphicsEngineVulkan | |
| parent | Disable validation layers if they are not compatible with headers, fixed comp... (diff) | |
| download | DiligentCore-1f9e0a4cd484687c13999d4a6686e104e0a93470.tar.gz DiligentCore-1f9e0a4cd484687c13999d4a6686e104e0a93470.zip | |
some improvements for ray tracing
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
7 files changed, 59 insertions, 29 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp index 2aaf4c69..2b8408ce 100644 --- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp @@ -215,6 +215,8 @@ public: const Uint32 MaxShaderRecordStride; const Uint32 ShaderGroupBaseAlignment; const Uint32 MaxDrawMeshTasksCount; + const Uint32 MaxRayTracingRecursionDepth; + const Uint32 MaxRayGenThreads; }; const Properties& GetProperties() const diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp index 8f90a914..405e9bfa 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp +++ b/Graphics/GraphicsEngineVulkan/include/VulkanTypeConversions.hpp @@ -67,6 +67,7 @@ VkBorderColor BorderColorToVkBorderColor(const Float32 BorderColor[]); VkPipelineStageFlags ResourceStateFlagsToVkPipelineStageFlags(RESOURCE_STATE StateFlags, VkPipelineStageFlags ShaderStages); VkAccessFlags ResourceStateFlagsToVkAccessFlags(RESOURCE_STATE StateFlags); +VkAccessFlags AccelStructStateFlagsToVkAccessFlags(RESOURCE_STATE StateFlags); VkImageLayout ResourceStateToVkImageLayout(RESOURCE_STATE StateFlag, bool IsInsideRenderPass = false); RESOURCE_STATE VkAccessFlagsToResourceStates(VkAccessFlags AccessFlags); diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index e34f52f2..48b7df04 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -2514,8 +2514,8 @@ void DeviceContextVkImpl::TransitionBLASState(BottomLevelASVkImpl& BLAS, if ((OldState & NewState) != NewState || AfterWrite) { EnsureVkCmdBuffer(); - auto OldAccessFlags = ResourceStateFlagsToVkAccessFlags(OldState); - auto NewAccessFlags = ResourceStateFlagsToVkAccessFlags(NewState); + auto OldAccessFlags = AccelStructStateFlagsToVkAccessFlags(OldState); + auto NewAccessFlags = AccelStructStateFlagsToVkAccessFlags(NewState); auto OldStages = ResourceStateFlagsToVkPipelineStageFlags(OldState, m_CommandBuffer.GetEnabledShaderStages()); auto NewStages = ResourceStateFlagsToVkPipelineStageFlags(NewState, m_CommandBuffer.GetEnabledShaderStages()); m_CommandBuffer.ASMemoryBarrier(OldAccessFlags, NewAccessFlags, OldStages, NewStages); @@ -2560,8 +2560,8 @@ void DeviceContextVkImpl::TransitionTLASState(TopLevelASVkImpl& TLAS, if ((OldState & NewState) != NewState || AfterWrite) { EnsureVkCmdBuffer(); - auto OldAccessFlags = ResourceStateFlagsToVkAccessFlags(OldState); - auto NewAccessFlags = ResourceStateFlagsToVkAccessFlags(NewState); + auto OldAccessFlags = AccelStructStateFlagsToVkAccessFlags(OldState); + auto NewAccessFlags = AccelStructStateFlagsToVkAccessFlags(NewState); auto OldStages = ResourceStateFlagsToVkPipelineStageFlags(OldState, m_CommandBuffer.GetEnabledShaderStages()); auto NewStages = ResourceStateFlagsToVkPipelineStageFlags(NewState, m_CommandBuffer.GetEnabledShaderStages()); m_CommandBuffer.ASMemoryBarrier(OldAccessFlags, NewAccessFlags, OldStages, NewStages); @@ -2792,7 +2792,7 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs) vkTris.maxVertex = SrcTris.VertexCount; vkTris.vertexData.deviceAddress = pVB->GetVkDeviceAddress() + SrcTris.VertexOffset; - TransitionOrVerifyBufferState(*pVB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, OpName); + TransitionOrVerifyBufferState(*pVB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VK_ACCESS_SHADER_READ_BIT, OpName); if (SrcTris.pIndexBuffer) { @@ -2802,7 +2802,7 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs) vkTris.indexType = TypeToVkIndexType(TriDesc.IndexType); vkTris.indexData.deviceAddress = pIB->GetVkDeviceAddress() + SrcTris.IndexOffset; - TransitionOrVerifyBufferState(*pIB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, OpName); + TransitionOrVerifyBufferState(*pIB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VK_ACCESS_SHADER_READ_BIT, OpName); } else { @@ -2815,7 +2815,7 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs) auto* const pTB = ValidatedCast<BufferVkImpl>(SrcTris.pTransformBuffer); vkTris.transformData.deviceAddress = pTB->GetVkDeviceAddress() + SrcTris.TransformBufferOffset; - TransitionOrVerifyBufferState(*pTB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, OpName); + TransitionOrVerifyBufferState(*pTB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VK_ACCESS_SHADER_READ_BIT, OpName); } else { @@ -2863,7 +2863,7 @@ void DeviceContextVkImpl::BuildBLAS(const BuildBLASAttribs& Attribs) VERIFY(vkAABBs.data.deviceAddress % 8 == 0, "AABB start address is not properly aligned"); - TransitionOrVerifyBufferState(*pBB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, OpName); + TransitionOrVerifyBufferState(*pBB, Attribs.GeometryTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VK_ACCESS_SHADER_READ_BIT, OpName); off.firstVertex = 0; off.transformOffset = 0; @@ -2956,7 +2956,7 @@ void DeviceContextVkImpl::BuildTLAS(const BuildTLASAttribs& Attribs) UpdateBufferRegion(pInstancesVk, Attribs.InstanceBufferOffset, Size, TmpSpace.vkBuffer, TmpSpace.AlignedOffset, Attribs.InstanceBufferTransitionMode); } - TransitionOrVerifyBufferState(*pInstancesVk, Attribs.InstanceBufferTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR, OpName); + TransitionOrVerifyBufferState(*pInstancesVk, Attribs.InstanceBufferTransitionMode, RESOURCE_STATE_BUILD_AS_READ, VK_ACCESS_SHADER_READ_BIT, OpName); VkAccelerationStructureBuildGeometryInfoKHR vkASBuildInfo = {}; VkAccelerationStructureBuildRangeInfoKHR vkRange = {}; @@ -3128,10 +3128,10 @@ void DeviceContextVkImpl::TraceRays(const TraceRaysAttribs& Attribs) pSBTVk->GetData(pBuffer, RayGenShaderRecord, MissShaderTable, HitGroupTable, CallableShaderTable); - auto* pBufferVk = ValidatedCast<BufferVkImpl>(pBuffer); + auto* pSBTBufferVk = ValidatedCast<BufferVkImpl>(pBuffer); const char* OpName = "Trace rays (DeviceContextVkImpl::TraceRays)"; - TransitionOrVerifyBufferState(*pBufferVk, Attribs.SBTTransitionMode, RESOURCE_STATE_COPY_DEST, VK_ACCESS_TRANSFER_WRITE_BIT, OpName); + TransitionOrVerifyBufferState(*pSBTBufferVk, Attribs.SBTTransitionMode, RESOURCE_STATE_COPY_DEST, VK_ACCESS_TRANSFER_WRITE_BIT, OpName); // buffer ranges are not intersected, so we don't need to add barriers between them if (RayGenShaderRecord.pData) @@ -3146,13 +3146,13 @@ void DeviceContextVkImpl::TraceRays(const TraceRaysAttribs& Attribs) if (CallableShaderTable.pData) UpdateBuffer(pBuffer, CallableShaderTable.Offset, CallableShaderTable.Size, CallableShaderTable.pData, RESOURCE_STATE_TRANSITION_MODE_VERIFY); - TransitionOrVerifyBufferState(*pBufferVk, Attribs.SBTTransitionMode, RESOURCE_STATE_RAY_TRACING, VK_ACCESS_SHADER_READ_BIT, OpName); + TransitionOrVerifyBufferState(*pSBTBufferVk, Attribs.SBTTransitionMode, RESOURCE_STATE_RAY_TRACING, VK_ACCESS_SHADER_READ_BIT, OpName); // clang-format off - VkStridedDeviceAddressRegionKHR RaygenShaderBindingTable = {pBufferVk->GetVkDeviceAddress() + RayGenShaderRecord.Offset, RayGenShaderRecord.Stride, RayGenShaderRecord.Size }; - VkStridedDeviceAddressRegionKHR MissShaderBindingTable = {pBufferVk->GetVkDeviceAddress() + MissShaderTable.Offset, MissShaderTable.Stride, MissShaderTable.Size }; - VkStridedDeviceAddressRegionKHR HitShaderBindingTable = {pBufferVk->GetVkDeviceAddress() + HitGroupTable.Offset, HitGroupTable.Stride, HitGroupTable.Size }; - VkStridedDeviceAddressRegionKHR CallableShaderBindingTable = {pBufferVk->GetVkDeviceAddress() + CallableShaderTable.Offset, CallableShaderTable.Stride, CallableShaderTable.Size}; + VkStridedDeviceAddressRegionKHR RaygenShaderBindingTable = {pSBTBufferVk->GetVkDeviceAddress() + RayGenShaderRecord.Offset, RayGenShaderRecord.Stride, RayGenShaderRecord.Size }; + VkStridedDeviceAddressRegionKHR MissShaderBindingTable = {pSBTBufferVk->GetVkDeviceAddress() + MissShaderTable.Offset, MissShaderTable.Stride, MissShaderTable.Size }; + VkStridedDeviceAddressRegionKHR HitShaderBindingTable = {pSBTBufferVk->GetVkDeviceAddress() + HitGroupTable.Offset, HitGroupTable.Stride, HitGroupTable.Size }; + VkStridedDeviceAddressRegionKHR CallableShaderBindingTable = {pSBTBufferVk->GetVkDeviceAddress() + CallableShaderTable.Offset, CallableShaderTable.Stride, CallableShaderTable.Size}; // clang-format on PrepareForRayTracing(); diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp index 514ca01d..ed537333 100644 --- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp +++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp @@ -418,7 +418,6 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E DeviceExtensions.push_back(VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); // required for VK_KHR_acceleration_structure DeviceExtensions.push_back(VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME); // required for VK_KHR_acceleration_structure DeviceExtensions.push_back(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME); // required for VK_KHR_acceleration_structure - DeviceExtensions.push_back(VK_KHR_PIPELINE_LIBRARY_EXTENSION_NAME); // required for VK_KHR_ray_tracing_pipeline DeviceExtensions.push_back(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); // required for ray tracing DeviceExtensions.push_back(VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME); // required for ray tracing diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 00bb54d9..7d846b90 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -346,12 +346,7 @@ static void CreateRayTracingPipeline(RenderDeviceVkImpl* const RayTracingPipelineDesc& RayTracingPipeline, VulkanUtilities::PipelineWrapper& Pipeline) { - const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); - const auto& PhysicalDevice = pDeviceVk->GetPhysicalDevice(); - const auto& RTLimits = PhysicalDevice.GetExtProperties().RayTracingPipeline; - - DEV_CHECK_ERR(RayTracingPipeline.MaxRecursionDepth <= RTLimits.maxRayRecursionDepth, - "RayTracingPipeline.MaxRecursionDepth must not exceed ", RTLimits.maxRayRecursionDepth); + const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); VkRayTracingPipelineCreateInfoKHR PipelineCI = {}; @@ -365,7 +360,7 @@ static void CreateRayTracingPipeline(RenderDeviceVkImpl* PipelineCI.pStages = Stages.data(); PipelineCI.groupCount = static_cast<Uint32>(ShaderGroups.size()); PipelineCI.pGroups = ShaderGroups.data(); - PipelineCI.maxPipelineRayRecursionDepth = RayTracingPipeline.MaxRecursionDepth; + PipelineCI.maxPipelineRayRecursionDepth = std::max(1u, Uint32{RayTracingPipeline.MaxRecursionDepth}) - 1; // for compatibility with D3D12, zero means only one ray tracing depth. PipelineCI.pLibraryInfo = nullptr; PipelineCI.pLibraryInterface = nullptr; PipelineCI.pDynamicState = nullptr; diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp index c44d5642..44bc0eb8 100644 --- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp @@ -165,13 +165,21 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters* m_PhysicalDevice->GetExtProperties().RayTracingPipeline.shaderGroupHandleSize, m_PhysicalDevice->GetExtProperties().RayTracingPipeline.maxShaderGroupStride, m_PhysicalDevice->GetExtProperties().RayTracingPipeline.shaderGroupBaseAlignment, - m_PhysicalDevice->GetExtProperties().MeshShader.maxDrawMeshTasksCount + m_PhysicalDevice->GetExtProperties().MeshShader.maxDrawMeshTasksCount, + m_PhysicalDevice->GetExtProperties().RayTracingPipeline.maxRayRecursionDepth + 1, // for compatibility with D3D12 + m_PhysicalDevice->GetExtProperties().RayTracingPipeline.maxRayDispatchInvocationCount } // clang-format on { static_assert(sizeof(VulkanDescriptorPoolSize) == sizeof(Uint32) * 11, "Please add new descriptors to m_DescriptorSetAllocator and m_DynamicDescriptorPool constructors"); static_assert(sizeof(DeviceObjectSizes) == sizeof(size_t) * 15, "Please add new objects to DeviceObjectSizes constructor"); + // set device properties + { + static_assert(sizeof(DeviceProperties) == sizeof(Uint32) * 1, "Please set new properties below"); + m_DeviceProperties.MaxRayTracingRecursionDepth = m_Properties.MaxRayTracingRecursionDepth; + } + m_DeviceCaps.DevType = RENDER_DEVICE_TYPE_VULKAN; m_DeviceCaps.MajorVersion = 1; m_DeviceCaps.MinorVersion = 0; diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp index edfa7625..17c129c1 100644 --- a/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp +++ b/Graphics/GraphicsEngineVulkan/src/VulkanTypeConversions.cpp @@ -1239,9 +1239,9 @@ static VkAccessFlags ResourceStateFlagToVkAccessFlags(RESOURCE_STATE StateFlag) case RESOURCE_STATE_RESOLVE_SOURCE: return VK_ACCESS_TRANSFER_READ_BIT; case RESOURCE_STATE_INPUT_ATTACHMENT: return VK_ACCESS_INPUT_ATTACHMENT_READ_BIT; case RESOURCE_STATE_PRESENT: return 0; - case RESOURCE_STATE_BUILD_AS_READ: return VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR; - case RESOURCE_STATE_BUILD_AS_WRITE: return VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR; - case RESOURCE_STATE_RAY_TRACING: return VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_SHADER_READ_BIT; // for TLAS & SBT + case RESOURCE_STATE_BUILD_AS_READ: return VK_ACCESS_SHADER_READ_BIT; // for vertex, index, transform, AABB, instance buffers + case RESOURCE_STATE_BUILD_AS_WRITE: return VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR; // for scratch buffer + case RESOURCE_STATE_RAY_TRACING: return VK_ACCESS_SHADER_READ_BIT; // for SBT // clang-format on default: @@ -1290,6 +1290,30 @@ VkAccessFlags ResourceStateFlagsToVkAccessFlags(RESOURCE_STATE StateFlags) return AccessFlags; } +VkAccessFlags AccelStructStateFlagsToVkAccessFlags(RESOURCE_STATE StateFlags) +{ + VERIFY(Uint32{StateFlags} < (RESOURCE_STATE_MAX_BIT << 1), "Resource state flags are out of range"); + static_assert(RESOURCE_STATE_MAX_BIT == RESOURCE_STATE_RAY_TRACING, "This function must be updated to handle new resource state flag"); + + VkAccessFlags AccessFlags = 0; + Uint32 Bits = StateFlags; + while (Bits != 0) + { + auto Bit = static_cast<RESOURCE_STATE>(1 << PlatformMisc::GetLSB(Bits)); + switch (Bit) + { + // clang-format off + case RESOURCE_STATE_BUILD_AS_READ: AccessFlags |= VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR; break; + case RESOURCE_STATE_BUILD_AS_WRITE: AccessFlags |= VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR; break; + case RESOURCE_STATE_RAY_TRACING: AccessFlags |= VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR; break; + default: UNEXPECTED("Unexpected resource state flag"); + // clang-format on + } + Bits &= ~Bit; + } + return AccessFlags; +} + static RESOURCE_STATE VkAccessFlagToResourceStates(VkAccessFlagBits AccessFlagBit) { VERIFY((AccessFlagBit & (AccessFlagBit - 1)) == 0, "Single access flag bit is expected"); @@ -1302,7 +1326,7 @@ static RESOURCE_STATE VkAccessFlagToResourceStates(VkAccessFlagBits AccessFlagBi case VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT: return RESOURCE_STATE_VERTEX_BUFFER; case VK_ACCESS_UNIFORM_READ_BIT: return RESOURCE_STATE_CONSTANT_BUFFER; case VK_ACCESS_INPUT_ATTACHMENT_READ_BIT: return RESOURCE_STATE_INPUT_ATTACHMENT; - case VK_ACCESS_SHADER_READ_BIT: return RESOURCE_STATE_SHADER_RESOURCE; + case VK_ACCESS_SHADER_READ_BIT: return RESOURCE_STATE_SHADER_RESOURCE; // or RESOURCE_STATE_BUILD_AS_READ case VK_ACCESS_SHADER_WRITE_BIT: return RESOURCE_STATE_UNORDERED_ACCESS; case VK_ACCESS_COLOR_ATTACHMENT_READ_BIT: return RESOURCE_STATE_RENDER_TARGET; case VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT: return RESOURCE_STATE_RENDER_TARGET; @@ -1310,6 +1334,7 @@ static RESOURCE_STATE VkAccessFlagToResourceStates(VkAccessFlagBits AccessFlagBi case VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT: return RESOURCE_STATE_DEPTH_WRITE; case VK_ACCESS_TRANSFER_READ_BIT: return RESOURCE_STATE_COPY_SOURCE; case VK_ACCESS_TRANSFER_WRITE_BIT: return RESOURCE_STATE_COPY_DEST; + case VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR: return RESOURCE_STATE_BUILD_AS_WRITE; case VK_ACCESS_HOST_READ_BIT: return RESOURCE_STATE_UNKNOWN; case VK_ACCESS_HOST_WRITE_BIT: return RESOURCE_STATE_UNKNOWN; case VK_ACCESS_MEMORY_READ_BIT: return RESOURCE_STATE_UNKNOWN; |
