From 4a5dbd8a807cade5199ba658855f4ac10d04e123 Mon Sep 17 00:00:00 2001 From: michal_jakubek Date: Fri, 11 Feb 2022 01:29:17 +0100 Subject: [PATCH] maintenance1: Pass VkTraceRaysIndirectCommand2KHR in various ways. New tests: dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.* Components: Vulkan VK-GL-CTS issue: 3242 Change-Id: I224b0fea1c6e96b2075116343623aabe9c80f0b7 --- .../vk-master-2021-03-01/ray-tracing-pipeline.txt | 32 + .../cts/main/vk-master/ray-tracing-pipeline.txt | 32 + .../framework/vulkan/vkRayTracingUtil.cpp | 581 +++++++++++++++- .../framework/vulkan/vkRayTracingUtil.hpp | 57 ++ .../vktRayTracingAccelerationStructuresTests.cpp | 15 + .../vulkan/ray_tracing/vktRayTracingTests.cpp | 1 + .../ray_tracing/vktRayTracingTraceRaysTests.cpp | 748 ++++++++++++++++++++- .../ray_tracing/vktRayTracingTraceRaysTests.hpp | 3 +- .../main/vk-default/ray-tracing-pipeline.txt | 32 + 9 files changed, 1434 insertions(+), 67 deletions(-) diff --git a/android/cts/main/vk-master-2021-03-01/ray-tracing-pipeline.txt b/android/cts/main/vk-master-2021-03-01/ray-tracing-pipeline.txt index 06ebada..9070dbb 100644 --- a/android/cts/main/vk-master-2021-03-01/ray-tracing-pipeline.txt +++ b/android/cts/main/vk-master-2021-03-01/ray-tracing-pipeline.txt @@ -9847,3 +9847,35 @@ dEQP-VK.ray_tracing_pipeline.pipeline_no_null_shaders_flag.cpu.tri_and_box.strid dEQP-VK.ray_tracing_pipeline.pipeline_no_null_shaders_flag.cpu.tri_and_box.stride_5.offset_7.no_libs.any_or_chit_or_isect dEQP-VK.ray_tracing_pipeline.pipeline_no_null_shaders_flag.cpu.tri_and_box.stride_5.offset_7.no_libs.any_or_chit dEQP-VK.ray_tracing_pipeline.pipeline_no_null_shaders_flag.cpu.tri_and_box.stride_5.offset_7.no_libs.any_or_chit_or_miss +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_graphics.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_graphics.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_graphics.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_graphics.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_compute.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_compute.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_compute.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_compute.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_graphics.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_graphics.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_graphics.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_graphics.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_compute.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_compute.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_compute.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_compute.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_graphics.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_graphics.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_graphics.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_graphics.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_compute.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_compute.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_compute.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_compute.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_graphics.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_graphics.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_graphics.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_graphics.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_compute.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_compute.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_compute.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_compute.47x19x4 diff --git a/android/cts/main/vk-master/ray-tracing-pipeline.txt b/android/cts/main/vk-master/ray-tracing-pipeline.txt index 06ebada..9070dbb 100644 --- a/android/cts/main/vk-master/ray-tracing-pipeline.txt +++ b/android/cts/main/vk-master/ray-tracing-pipeline.txt @@ -9847,3 +9847,35 @@ dEQP-VK.ray_tracing_pipeline.pipeline_no_null_shaders_flag.cpu.tri_and_box.strid dEQP-VK.ray_tracing_pipeline.pipeline_no_null_shaders_flag.cpu.tri_and_box.stride_5.offset_7.no_libs.any_or_chit_or_isect dEQP-VK.ray_tracing_pipeline.pipeline_no_null_shaders_flag.cpu.tri_and_box.stride_5.offset_7.no_libs.any_or_chit dEQP-VK.ray_tracing_pipeline.pipeline_no_null_shaders_flag.cpu.tri_and_box.stride_5.offset_7.no_libs.any_or_chit_or_miss +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_graphics.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_graphics.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_graphics.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_graphics.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_compute.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_compute.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_compute.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_compute.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_graphics.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_graphics.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_graphics.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_graphics.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_compute.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_compute.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_compute.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_compute.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_graphics.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_graphics.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_graphics.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_graphics.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_compute.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_compute.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_compute.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_compute.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_graphics.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_graphics.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_graphics.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_graphics.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_compute.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_compute.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_compute.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_compute.47x19x4 diff --git a/external/vulkancts/framework/vulkan/vkRayTracingUtil.cpp b/external/vulkancts/framework/vulkan/vkRayTracingUtil.cpp index 554a57f..20c8a1c 100644 --- a/external/vulkancts/framework/vulkan/vkRayTracingUtil.cpp +++ b/external/vulkancts/framework/vulkan/vkRayTracingUtil.cpp @@ -35,6 +35,8 @@ #include #include #include +#include +#include namespace vk { @@ -794,29 +796,42 @@ VkDeviceSize BottomLevelAccelerationStructure::getStructureSize() const return m_structureSize; } -BufferWithMemory* createVertexBuffer (const DeviceInterface& vk, - const VkDevice device, - Allocator& allocator, - const std::vector>& geometriesData) +VkDeviceSize getVertexBufferSize (const std::vector>& geometriesData) { DE_ASSERT(geometriesData.size() != 0); - VkDeviceSize bufferSizeBytes = 0; for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx) bufferSizeBytes += deAlignSize(geometriesData[geometryNdx]->getVertexByteSize(),8); + return bufferSizeBytes; +} - const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); +BufferWithMemory* createVertexBuffer (const DeviceInterface& vk, + const VkDevice device, + Allocator& allocator, + const VkDeviceSize bufferSizeBytes) +{ + const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); return new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress); } +BufferWithMemory* createVertexBuffer (const DeviceInterface& vk, + const VkDevice device, + Allocator& allocator, + const std::vector>& geometriesData) +{ + return createVertexBuffer(vk, device, allocator, getVertexBufferSize(geometriesData)); +} + void updateVertexBuffer (const DeviceInterface& vk, const VkDevice device, const std::vector>& geometriesData, - BufferWithMemory* vertexBuffer) + BufferWithMemory* vertexBuffer, + VkDeviceSize geometriesOffset = 0) { const Allocation& geometryAlloc = vertexBuffer->getAllocation(); deUint8* bufferStart = static_cast(geometryAlloc.getHostPtr()); - VkDeviceSize bufferOffset = 0; + const VkDeviceSize bufferSize = getVertexBufferSize(geometriesData); + VkDeviceSize bufferOffset = geometriesOffset; for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx) { @@ -828,36 +843,51 @@ void updateVertexBuffer (const DeviceInterface& vk, bufferOffset += deAlignSize(geometryPtrSize,8); } - flushMappedMemoryRange(vk, device, geometryAlloc.getMemory(), geometryAlloc.getOffset(), VK_WHOLE_SIZE); + flushMappedMemoryRange(vk, device, geometryAlloc.getMemory(), geometryAlloc.getOffset()+geometriesOffset, bufferSize); } -BufferWithMemory* createIndexBuffer (const DeviceInterface& vk, - const VkDevice device, - Allocator& allocator, - const std::vector>& geometriesData) +VkDeviceSize getIndexBufferSize (const std::vector>& geometriesData) { DE_ASSERT(!geometriesData.empty()); - VkDeviceSize bufferSizeBytes = 0; + VkDeviceSize bufferSizeBytes = 0; for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx) if(geometriesData[geometryNdx]->getIndexType() != VK_INDEX_TYPE_NONE_KHR) bufferSizeBytes += deAlignSize(geometriesData[geometryNdx]->getIndexByteSize(),8); + return bufferSizeBytes; +} - if (bufferSizeBytes == 0) - return DE_NULL; - +BufferWithMemory* createIndexBuffer (const DeviceInterface& vk, + const VkDevice device, + Allocator& allocator, + const VkDeviceSize bufferSizeBytes) +{ + DE_ASSERT(bufferSizeBytes); const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSizeBytes, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); return new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress); } +BufferWithMemory* createIndexBuffer (const DeviceInterface& vk, + const VkDevice device, + Allocator& allocator, + const std::vector>& geometriesData) +{ + + + const VkDeviceSize bufferSizeBytes = getIndexBufferSize(geometriesData); + return bufferSizeBytes ? createIndexBuffer(vk, device, allocator, bufferSizeBytes) : nullptr; +} + void updateIndexBuffer (const DeviceInterface& vk, const VkDevice device, const std::vector>& geometriesData, - BufferWithMemory* indexBuffer) + BufferWithMemory* indexBuffer, + VkDeviceSize geometriesOffset) { const Allocation& indexAlloc = indexBuffer->getAllocation(); deUint8* bufferStart = static_cast(indexAlloc.getHostPtr()); - VkDeviceSize bufferOffset = 0; + const VkDeviceSize bufferSize = getIndexBufferSize(geometriesData); + VkDeviceSize bufferOffset = geometriesOffset; for (size_t geometryNdx = 0; geometryNdx < geometriesData.size(); ++geometryNdx) { @@ -872,7 +902,7 @@ void updateIndexBuffer (const DeviceInterface& vk, } } - flushMappedMemoryRange(vk, device, indexAlloc.getMemory(), indexAlloc.getOffset(), VK_WHOLE_SIZE); + flushMappedMemoryRange(vk, device, indexAlloc.getMemory(), indexAlloc.getOffset()+geometriesOffset, bufferSize); } class BottomLevelAccelerationStructureKHR : public BottomLevelAccelerationStructure @@ -948,7 +978,19 @@ protected: std::vector& accelerationStructureGeometriesKHR, std::vector& accelerationStructureGeometriesKHRPointers, std::vector& accelerationStructureBuildRangeInfoKHR, - std::vector& maxPrimitiveCounts); + std::vector& maxPrimitiveCounts, + VkDeviceSize vertexBufferOffset = 0, + VkDeviceSize indexBufferOffset = 0); + + virtual BufferWithMemory* getAccelerationStructureBuffer () { return m_accelerationStructureBuffer.get(); } + virtual BufferWithMemory* getDeviceScratchBuffer () { return m_deviceScratchBuffer.get(); } + virtual BufferWithMemory* getVertexBuffer () { return m_vertexBuffer.get(); } + virtual BufferWithMemory* getIndexBuffer () { return m_indexBuffer.get(); } + + virtual VkDeviceSize getAccelerationStructureBufferOffset () const { return 0; } + virtual VkDeviceSize getDeviceScratchBufferOffset () const { return 0; } + virtual VkDeviceSize getVertexBufferOffset () const { return 0; } + virtual VkDeviceSize getIndexBufferOffset () const { return 0; } }; deUint32 BottomLevelAccelerationStructureKHR::getRequiredAllocationCount (void) @@ -1122,8 +1164,8 @@ void BottomLevelAccelerationStructureKHR::create (const DeviceInterface& vk, VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR, // VkStructureType sType; DE_NULL, // const void* pNext; m_createFlags, // VkAccelerationStructureCreateFlagsKHR createFlags; - m_accelerationStructureBuffer->get(), // VkBuffer buffer; - 0u, // VkDeviceSize offset; + getAccelerationStructureBuffer()->get(), // VkBuffer buffer; + getAccelerationStructureBufferOffset(), // VkDeviceSize offset; m_structureSize, // VkDeviceSize size; structureType, // VkAccelerationStructureTypeKHR type; deviceAddress // VkDeviceAddress deviceAddress; @@ -1162,9 +1204,9 @@ void BottomLevelAccelerationStructureKHR::build (const DeviceInterface& vk, if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) { - updateVertexBuffer(vk, device, m_geometriesData, m_vertexBuffer.get()); - if(m_indexBuffer.get() != DE_NULL) - updateIndexBuffer(vk, device, m_geometriesData, m_indexBuffer.get()); + updateVertexBuffer(vk, device, m_geometriesData, getVertexBuffer(), getVertexBufferOffset()); + if(getIndexBuffer() != DE_NULL) + updateIndexBuffer(vk, device, m_geometriesData, getIndexBuffer(), getIndexBufferOffset()); } { @@ -1173,12 +1215,13 @@ void BottomLevelAccelerationStructureKHR::build (const DeviceInterface& vk, std::vector accelerationStructureBuildRangeInfoKHR; std::vector maxPrimitiveCounts; - prepareGeometries(vk, device, accelerationStructureGeometriesKHR, accelerationStructureGeometriesKHRPointers, accelerationStructureBuildRangeInfoKHR, maxPrimitiveCounts); + prepareGeometries(vk, device, accelerationStructureGeometriesKHR, accelerationStructureGeometriesKHRPointers, + accelerationStructureBuildRangeInfoKHR, maxPrimitiveCounts, getVertexBufferOffset(), getIndexBufferOffset()); const VkAccelerationStructureGeometryKHR* accelerationStructureGeometriesKHRPointer = accelerationStructureGeometriesKHR.data(); const VkAccelerationStructureGeometryKHR* const* accelerationStructureGeometry = accelerationStructureGeometriesKHRPointers.data(); VkDeviceOrHostAddressKHR scratchData = (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) - ? makeDeviceOrHostAddressKHR(vk, device, m_deviceScratchBuffer->get(), 0) + ? makeDeviceOrHostAddressKHR(vk, device, getDeviceScratchBuffer()->get(), getDeviceScratchBufferOffset()) : makeDeviceOrHostAddressKHR(m_hostScratchBuffer.data()); const deUint32 geometryCount = (m_buildWithoutGeometries ? 0u @@ -1379,32 +1422,32 @@ void BottomLevelAccelerationStructureKHR::prepareGeometries (const DeviceInterfa std::vector& accelerationStructureGeometriesKHR, std::vector& accelerationStructureGeometriesKHRPointers, std::vector& accelerationStructureBuildRangeInfoKHR, - std::vector& maxPrimitiveCounts) + std::vector& maxPrimitiveCounts, + VkDeviceSize vertexBufferOffset, + VkDeviceSize indexBufferOffset) { accelerationStructureGeometriesKHR.resize(m_geometriesData.size()); accelerationStructureGeometriesKHRPointers.resize(m_geometriesData.size()); accelerationStructureBuildRangeInfoKHR.resize(m_geometriesData.size()); maxPrimitiveCounts.resize(m_geometriesData.size()); - VkDeviceSize vertexBufferOffset = 0, indexBufferOffset = 0; - for (size_t geometryNdx = 0; geometryNdx < m_geometriesData.size(); ++geometryNdx) { de::SharedPtr& geometryData = m_geometriesData[geometryNdx]; VkDeviceOrHostAddressConstKHR vertexData, indexData; if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) { - if (m_vertexBuffer.get() != DE_NULL) + if (getVertexBuffer() != DE_NULL) { - vertexData = makeDeviceOrHostAddressConstKHR(vk, device, m_vertexBuffer->get(), vertexBufferOffset); + vertexData = makeDeviceOrHostAddressConstKHR(vk, device, getVertexBuffer()->get(), vertexBufferOffset); vertexBufferOffset += deAlignSize(geometryData->getVertexByteSize(), 8); } else vertexData = makeDeviceOrHostAddressConstKHR(DE_NULL); - if (m_indexBuffer.get() != DE_NULL && geometryData->getIndexType() != VK_INDEX_TYPE_NONE_KHR) + if (getIndexBuffer() != DE_NULL && geometryData->getIndexType() != VK_INDEX_TYPE_NONE_KHR) { - indexData = makeDeviceOrHostAddressConstKHR(vk, device, m_indexBuffer->get(), indexBufferOffset); + indexData = makeDeviceOrHostAddressConstKHR(vk, device, getIndexBuffer()->get(), indexBufferOffset); indexBufferOffset += deAlignSize(geometryData->getIndexByteSize(), 8); } else @@ -1517,6 +1560,456 @@ de::MovePtr makeBottomLevelAccelerationStructu return de::MovePtr(new BottomLevelAccelerationStructureKHR); } +// Forward declaration +struct BottomLevelAccelerationStructurePoolImpl; + +class BottomLevelAccelerationStructurePoolMember : public BottomLevelAccelerationStructureKHR +{ +public: + friend class BottomLevelAccelerationStructurePool; + + BottomLevelAccelerationStructurePoolMember (BottomLevelAccelerationStructurePoolImpl& pool); + BottomLevelAccelerationStructurePoolMember (const BottomLevelAccelerationStructurePoolMember&) = delete; + BottomLevelAccelerationStructurePoolMember (BottomLevelAccelerationStructurePoolMember&&) = delete; + virtual ~BottomLevelAccelerationStructurePoolMember () = default; + + virtual void create (const DeviceInterface&, + const VkDevice, + Allocator&, + VkDeviceSize, + VkDeviceAddress) override + { + DE_ASSERT(0); // Silent this method + } + +protected: + struct Info; + virtual void preCreateComputeSizesAndOffsets (const DeviceInterface& vk, + const VkDevice device, + const VkDeviceSize accStrSize, + Info& info); + virtual void createAccellerationStructure (const DeviceInterface& vk, + const VkDevice device, + VkDeviceAddress deviceAddress); + + virtual BufferWithMemory* getAccelerationStructureBuffer () override; + virtual BufferWithMemory* getDeviceScratchBuffer () override; + virtual BufferWithMemory* getVertexBuffer () override; + virtual BufferWithMemory* getIndexBuffer () override; + + virtual VkDeviceSize getAccelerationStructureBufferOffset () const override { return m_info.accStrOffset; } + virtual VkDeviceSize getDeviceScratchBufferOffset () const override { return m_info.scratchBuffOffset; } + virtual VkDeviceSize getVertexBufferOffset () const override { return m_info.vertBuffOffset; } + virtual VkDeviceSize getIndexBufferOffset () const override { return m_info.indexBuffOffset; } + + BottomLevelAccelerationStructurePoolImpl& m_pool; + + struct Info + { + deUint32 accStrIndex; + VkDeviceSize accStrSize; + VkDeviceSize accStrOffset; + deUint32 vertBuffIndex; + VkDeviceSize vertBuffSize; + VkDeviceSize vertBuffOffset; + deUint32 indexBuffIndex; + VkDeviceSize indexBuffSize; + VkDeviceSize indexBuffOffset; + deUint32 scratchBuffIndex; + VkDeviceSize scratchBuffSize; + VkDeviceSize scratchBuffOffset; + } m_info; +}; + +template inline X negz(const X&) +{ + return (~static_cast(0)); +} +template inline bool isnegz(const X& x) +{ + return x == negz(x); +} + +BottomLevelAccelerationStructurePoolMember::BottomLevelAccelerationStructurePoolMember (BottomLevelAccelerationStructurePoolImpl& pool) + : m_pool (pool) + , m_info {} +{ +} + +struct BottomLevelAccelerationStructurePoolImpl +{ + BottomLevelAccelerationStructurePoolImpl (BottomLevelAccelerationStructurePoolImpl&&) = delete; + BottomLevelAccelerationStructurePoolImpl (const BottomLevelAccelerationStructurePoolImpl&) = delete; + BottomLevelAccelerationStructurePoolImpl (BottomLevelAccelerationStructurePool& pool); + + BottomLevelAccelerationStructurePool& m_pool; + std::vector> m_accellerationStructureBuffers; + std::vector> m_deviceScratchBuffers; + std::vector> m_vertexBuffers; + std::vector> m_indexBuffers; +}; +BottomLevelAccelerationStructurePoolImpl::BottomLevelAccelerationStructurePoolImpl (BottomLevelAccelerationStructurePool& pool) + : m_pool (pool) + , m_accellerationStructureBuffers () + , m_deviceScratchBuffers () + , m_vertexBuffers () + , m_indexBuffers () +{ +} +BufferWithMemory* BottomLevelAccelerationStructurePoolMember::getAccelerationStructureBuffer () +{ + BufferWithMemory* result = nullptr; + if (m_pool.m_accellerationStructureBuffers.size()) + { + DE_ASSERT(!isnegz(m_info.accStrIndex)); + result = m_pool.m_accellerationStructureBuffers[m_info.accStrIndex].get(); + } + return result; +} +BufferWithMemory* BottomLevelAccelerationStructurePoolMember::getDeviceScratchBuffer () +{ + return m_pool.m_deviceScratchBuffers.size() && !isnegz(m_info.scratchBuffIndex) + ? m_pool.m_deviceScratchBuffers[m_info.scratchBuffIndex].get() + : nullptr; +} +BufferWithMemory* BottomLevelAccelerationStructurePoolMember::getVertexBuffer () +{ + BufferWithMemory* result = nullptr; + if (m_pool.m_vertexBuffers.size()) + { + DE_ASSERT(!isnegz(m_info.vertBuffIndex)); + result = m_pool.m_vertexBuffers[m_info.vertBuffIndex].get(); + } + return result; +} +BufferWithMemory* BottomLevelAccelerationStructurePoolMember::getIndexBuffer () +{ + BufferWithMemory* result = nullptr; + if (m_pool.m_indexBuffers.size()) + { + DE_ASSERT(!isnegz(m_info.indexBuffIndex)); + result = m_pool.m_indexBuffers[m_info.indexBuffIndex].get(); + } + return result; +} + +struct BottomLevelAccelerationStructurePool::Impl : BottomLevelAccelerationStructurePoolImpl +{ + friend class BottomLevelAccelerationStructurePool; + friend class BottomLevelAccelerationStructurePoolMember; + + Impl (BottomLevelAccelerationStructurePool& pool) + : BottomLevelAccelerationStructurePoolImpl(pool) { } +}; + +BottomLevelAccelerationStructurePool::BottomLevelAccelerationStructurePool () + : m_batchStructCount (4) + , m_batchGeomCount (0) + , m_infos () + , m_structs () + , m_createOnce () + , m_impl (new Impl(*this)) +{ +} + +BottomLevelAccelerationStructurePool::~BottomLevelAccelerationStructurePool() +{ + delete m_impl; +} + +void BottomLevelAccelerationStructurePool::batchStructCount (const size_t& value) +{ + DE_ASSERT(value >= 1); m_batchStructCount = value; +} + +auto BottomLevelAccelerationStructurePool::add (VkDeviceSize structureSize, + VkDeviceAddress deviceAddress) -> BottomLevelAccelerationStructurePool::BlasPtr +{ + // Prevent a programmer from calling this method after batchCreate(...) method has been called. + if (m_createOnce) DE_ASSERT(0); + + auto blas = new BottomLevelAccelerationStructurePoolMember(*m_impl); + m_infos.push_back({structureSize, deviceAddress}); + m_structs.emplace_back(blas); + return m_structs.back(); +} + +size_t BottomLevelAccelerationStructurePool::getAllocationCount () const +{ + return m_impl->m_accellerationStructureBuffers.size() + + m_impl->m_vertexBuffers.size() + + m_impl->m_indexBuffers.size() + + m_impl->m_deviceScratchBuffers.size(); +} + +void BottomLevelAccelerationStructurePool::batchCreate (const DeviceInterface& vk, + const VkDevice device, + Allocator& allocator) +{ + // Prevent a programmer from calling this method more than once. + if (m_createOnce) DE_ASSERT(0); m_createOnce = true; + DE_ASSERT(m_structs.size() != 0); + + auto createAccellerationStructureBuffer = [&](VkDeviceSize bufferSize) -> typename std::add_pointer::type + { + typename std::add_pointer::type result = nullptr; + const VkBufferCreateInfo bci = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); + try + { + result = new BufferWithMemory(vk, device, allocator, bci, + MemoryRequirement::Cached | MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress); + } + catch (const tcu::NotSupportedError&) + { + // retry without Cached flag + result = new BufferWithMemory(vk, device, allocator, bci, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress); + } + return result; + }; + + auto createScratchBuffer = [&](VkDeviceSize bufferSize) -> typename std::add_pointer::type + { + const VkBufferCreateInfo bci = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT); + return new BufferWithMemory(vk, device, allocator, bci, MemoryRequirement::HostVisible | MemoryRequirement::Coherent | MemoryRequirement::DeviceAddress); + }; + + std::vector> accellerationStructureBuffers; + std::vector> deviceScratchBuffers; + std::vector> vertexBuffers; + std::vector> indexBuffers; + + BottomLevelAccelerationStructurePoolMember::Info info { /* initialized with zeros */ }; + typename std::map::size_type iter = 0; + std::map accStrSizes; + std::map vertBuffSizes; + std::map indexBuffSizes; + std::map scratchBuffSizes; + + deUint32 indexBuffIndexControl = 0; + deUint32 scratchBuffIndexControl = 0; + + const size_t realBatchGeomCount = batchGeomCount() ? batchGeomCount() : batchStructCount(); + + for (size_t i = 0; i < structCount(); ++i) + { + auto& str = *dynamic_cast(m_structs[i].get()); + str.preCreateComputeSizesAndOffsets(vk, device, m_infos[i].structureSize, info); + + { + const deUint32 accStrIndex = deUint32(i / batchStructCount()); + accStrSizes[accStrIndex] += deAlign64(info.accStrSize, 256); + if (((i + 1) % batchStructCount()) == 0) + { + info.accStrOffset = 0; + info.accStrIndex = accStrIndex + 1; + } + else + { + info.accStrIndex = accStrIndex; + info.accStrOffset += deAlign64(info.accStrSize, 256); + } + } + + { + const deUint32 vertexBuffIndex = deUint32(i / realBatchGeomCount); + vertBuffSizes[vertexBuffIndex] += info.vertBuffOffset += deAlign64(info.vertBuffSize, 8); + if (((i + 1) % realBatchGeomCount) == 0) + { + info.vertBuffOffset = 0; + info.vertBuffIndex = vertexBuffIndex + 1; + } + else + { + info.vertBuffIndex = vertexBuffIndex; + info.vertBuffOffset += deAlign64(info.vertBuffSize, 8); + } + } + + if (info.indexBuffSize) + { + const deUint32 indexBuffIndex = deUint32(indexBuffIndexControl / realBatchGeomCount); + indexBuffSizes[indexBuffIndex] += deAlign64(info.indexBuffSize, 8); + if (((indexBuffIndexControl + 1) % realBatchGeomCount) == 0) + { + info.indexBuffOffset = 0; + info.indexBuffIndex = indexBuffIndex + 1; + } + else + { + info.indexBuffIndex = indexBuffIndex; + info.indexBuffOffset += deAlign64(info.indexBuffSize, 8); + } + indexBuffIndexControl += 1; + } + + if (info.scratchBuffSize) + { + const deUint32 scratchBuffIndex = deUint32(scratchBuffIndexControl / batchStructCount()); + scratchBuffSizes[scratchBuffIndex] += deAlign64(info.scratchBuffSize, 256); + if (((scratchBuffIndexControl + 1) % batchStructCount()) == 0) + { + info.scratchBuffOffset = 0; + info.scratchBuffIndex = scratchBuffIndex + 1; + } + else + { + info.scratchBuffIndex = scratchBuffIndex; + info.scratchBuffOffset += deAlign64(info.scratchBuffSize, 256); + } + scratchBuffIndexControl += 1; + } + } + + for (iter = 0; iter < accStrSizes.size(); ++iter) + { + m_impl->m_accellerationStructureBuffers.emplace_back(createAccellerationStructureBuffer(accStrSizes[deUint32(iter)])); + } + for (iter = 0; iter < vertBuffSizes.size(); ++iter) + { + m_impl->m_vertexBuffers.emplace_back(createVertexBuffer(vk, device, allocator, vertBuffSizes[deUint32(iter)])); + } + for (iter = 0; iter < indexBuffSizes.size(); ++iter) + { + m_impl->m_indexBuffers.emplace_back(createIndexBuffer(vk, device, allocator, indexBuffSizes[deUint32(iter)])); + } + for (iter = 0; iter < scratchBuffSizes.size(); ++iter) + { + m_impl->m_deviceScratchBuffers.emplace_back(createScratchBuffer(scratchBuffSizes[deUint32(iter)])); + } + + for (deUint32 i = 0; i < structCount(); ++i) + { + auto& str = *dynamic_cast(m_structs[i].get()); + str.createAccellerationStructure(vk, device, m_infos[i].deviceAddress); + } +} + +void BottomLevelAccelerationStructurePool::batchBuild (const DeviceInterface& vk, + const VkDevice device, + VkCommandBuffer cmdBuffer) +{ + for (const auto& str : m_structs) + { + str->build(vk, device, cmdBuffer); + } +} + + +void BottomLevelAccelerationStructurePoolMember::preCreateComputeSizesAndOffsets (const DeviceInterface& vk, + const VkDevice device, + const VkDeviceSize accStrSize, + Info& ioinfo) +{ + // AS may be built from geometries using vkCmdBuildAccelerationStructuresKHR / vkBuildAccelerationStructuresKHR + // or may be copied/compacted/deserialized from other AS ( in this case AS does not need geometries, but it needs to know its size before creation ). + DE_ASSERT(!m_geometriesData.empty() != !(accStrSize == 0)); // logical xor + + if (accStrSize == 0) + { + std::vector accelerationStructureGeometriesKHR; + std::vector accelerationStructureGeometriesKHRPointers; + std::vector accelerationStructureBuildRangeInfoKHR; + std::vector maxPrimitiveCounts; + prepareGeometries(vk, device, accelerationStructureGeometriesKHR, accelerationStructureGeometriesKHRPointers, accelerationStructureBuildRangeInfoKHR, maxPrimitiveCounts); + + const VkAccelerationStructureGeometryKHR* accelerationStructureGeometriesKHRPointer = accelerationStructureGeometriesKHR.data(); + const VkAccelerationStructureGeometryKHR* const* accelerationStructureGeometry = accelerationStructureGeometriesKHRPointers.data(); + + VkAccelerationStructureBuildGeometryInfoKHR accelerationStructureBuildGeometryInfoKHR = + { + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR, // VkAccelerationStructureTypeKHR type; + m_buildFlags, // VkBuildAccelerationStructureFlagsKHR flags; + VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR, // VkBuildAccelerationStructureModeKHR mode; + DE_NULL, // VkAccelerationStructureKHR srcAccelerationStructure; + DE_NULL, // VkAccelerationStructureKHR dstAccelerationStructure; + static_cast(accelerationStructureGeometriesKHR.size()), // deUint32 geometryCount; + m_useArrayOfPointers ? DE_NULL : accelerationStructureGeometriesKHRPointer, // const VkAccelerationStructureGeometryKHR* pGeometries; + m_useArrayOfPointers ? accelerationStructureGeometry : DE_NULL, // const VkAccelerationStructureGeometryKHR* const* ppGeometries; + makeDeviceOrHostAddressKHR(DE_NULL) // VkDeviceOrHostAddressKHR scratchData; + }; + VkAccelerationStructureBuildSizesInfoKHR sizeInfo = + { + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0, // VkDeviceSize accelerationStructureSize; + 0, // VkDeviceSize updateScratchSize; + 0 // VkDeviceSize buildScratchSize; + }; + + vk.getAccelerationStructureBuildSizesKHR(device, m_buildType, &accelerationStructureBuildGeometryInfoKHR, maxPrimitiveCounts.data(), &sizeInfo); + + m_structureSize = sizeInfo.accelerationStructureSize; + m_updateScratchSize = sizeInfo.updateScratchSize; + m_buildScratchSize = sizeInfo.buildScratchSize; + } + else + { + m_structureSize = accStrSize; + m_updateScratchSize = 0u; + m_buildScratchSize = 0u; + } + + ioinfo.accStrSize = m_structureSize; + m_info.accStrIndex = ioinfo.accStrIndex; + m_info.accStrOffset = ioinfo.accStrOffset; + + ioinfo.scratchBuffSize = m_buildScratchSize; + if (m_buildScratchSize > 0u) + { + if (m_buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) + { + m_info.scratchBuffIndex = ioinfo.scratchBuffIndex; + m_info.scratchBuffOffset = ioinfo.scratchBuffOffset; + } + else + { + m_hostScratchBuffer.resize(static_cast(m_buildScratchSize)); + m_info.scratchBuffIndex = negz(m_info.scratchBuffIndex); + m_info.scratchBuffOffset = negz(m_info.scratchBuffOffset); + } + } + + ioinfo.vertBuffSize = getVertexBufferSize(m_geometriesData); + m_info.vertBuffIndex = ioinfo.vertBuffIndex; + m_info.vertBuffOffset = ioinfo.vertBuffOffset; + + ioinfo.indexBuffSize = getIndexBufferSize(m_geometriesData); + if (ioinfo.indexBuffSize) + { + m_info.indexBuffIndex = ioinfo.indexBuffIndex; + m_info.indexBuffOffset = ioinfo.indexBuffOffset; + } + else + { + m_info.indexBuffIndex = negz(m_info.indexBuffIndex); + m_info.indexBuffOffset = negz(m_info.indexBuffOffset); + } +} + +void BottomLevelAccelerationStructurePoolMember::createAccellerationStructure (const DeviceInterface& vk, + const VkDevice device, + VkDeviceAddress deviceAddress) +{ + const VkAccelerationStructureTypeKHR structureType = (m_createGeneric + ? VK_ACCELERATION_STRUCTURE_TYPE_GENERIC_KHR + : VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR); + const VkAccelerationStructureCreateInfoKHR accelerationStructureCreateInfoKHR + { + VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + m_createFlags, // VkAccelerationStructureCreateFlagsKHR createFlags; + getAccelerationStructureBuffer()->get(), // VkBuffer buffer; + getAccelerationStructureBufferOffset(), // VkDeviceSize offset; + m_structureSize, // VkDeviceSize size; + structureType, // VkAccelerationStructureTypeKHR type; + deviceAddress // VkDeviceAddress deviceAddress; + }; + + m_accelerationStructureKHR = createAccelerationStructureKHR(vk, device, &accelerationStructureCreateInfoKHR, DE_NULL); +} + TopLevelAccelerationStructure::~TopLevelAccelerationStructure () { } @@ -2279,7 +2772,7 @@ void TopLevelAccelerationStructureKHR::createAndDeserializeBottoms (const Device { const deUint64& lookAddr = addresses[i+1]; auto end = matches.end(); - auto match = std::find_if(matches.begin(), end, [&](const std::pair& item){ return item.first == lookAddr; }); + auto match = std::find_if(matches.begin(), end, [&](const std::pair& item){ return item.first == lookAddr; }); if (match != end) { m_bottomLevelInstances .emplace_back(m_bottomLevelInstances[match->second]); @@ -2986,4 +3479,20 @@ void cmdTraceRaysIndirect (const DeviceInterface& vk, indirectDeviceAddress); } +static inline void cmdTraceRaysIndirect2KHR (const DeviceInterface& vk, + VkCommandBuffer commandBuffer, + VkDeviceAddress indirectDeviceAddress ) +{ + DE_ASSERT(indirectDeviceAddress != 0); + + return vk.cmdTraceRaysIndirect2KHR(commandBuffer, indirectDeviceAddress); +} + +void cmdTraceRaysIndirect2 (const DeviceInterface& vk, + VkCommandBuffer commandBuffer, + VkDeviceAddress indirectDeviceAddress) +{ + return cmdTraceRaysIndirect2KHR(vk, commandBuffer, indirectDeviceAddress); +} + } // vk diff --git a/external/vulkancts/framework/vulkan/vkRayTracingUtil.hpp b/external/vulkancts/framework/vulkan/vkRayTracingUtil.hpp index 948ff6f..e368e71 100644 --- a/external/vulkancts/framework/vulkan/vkRayTracingUtil.hpp +++ b/external/vulkancts/framework/vulkan/vkRayTracingUtil.hpp @@ -647,6 +647,58 @@ protected: de::MovePtr makeBottomLevelAccelerationStructure (); +/** + * @brief Implements a pool of BottomLevelAccelerationStructure + */ +class BottomLevelAccelerationStructurePool +{ +public: + typedef de::SharedPtr BlasPtr; + struct BlasInfo { + VkDeviceSize structureSize; + VkDeviceAddress deviceAddress; + }; + + BottomLevelAccelerationStructurePool(); + virtual ~BottomLevelAccelerationStructurePool(); + + BlasPtr at (deUint32 index) const { return m_structs[index]; } + BlasPtr operator[] (deUint32 index) const { return m_structs[index]; } + auto structures () const -> const std::vector& { return m_structs; } + size_t structCount () const { return m_structs.size(); } + + size_t batchStructCount () const {return m_batchStructCount; } + void batchStructCount (const size_t& value); + + size_t batchGeomCount () const {return m_batchGeomCount; } + void batchGeomCount (const size_t& value) { m_batchGeomCount = value; } + + BlasPtr add (VkDeviceSize structureSize = 0, + VkDeviceAddress deviceAddress = 0); + /** + * @brief Creates previously added bottoms at a time. + * @note All geometries must be known before call this method. + */ + void batchCreate (const DeviceInterface& vk, + const VkDevice device, + Allocator& allocator); + void batchBuild (const DeviceInterface& vk, + const VkDevice device, + VkCommandBuffer cmdBuffer); + size_t getAllocationCount () const; + +protected: + size_t m_batchStructCount; // default is 4 + size_t m_batchGeomCount; // default is 0, if zero then batchStructCount is used + std::vector m_infos; + std::vector m_structs; + bool m_createOnce; + +protected: + struct Impl; + Impl* m_impl; +}; + struct InstanceData { InstanceData (VkTransformMatrixKHR matrix_, @@ -903,6 +955,11 @@ void cmdTraceRaysIndirect (const DeviceInterface& vk, const VkStridedDeviceAddressRegionKHR* hitShaderBindingTableRegion, const VkStridedDeviceAddressRegionKHR* callableShaderBindingTableRegion, VkDeviceAddress indirectDeviceAddress); + +void cmdTraceRaysIndirect2 (const DeviceInterface& vk, + VkCommandBuffer commandBuffer, + VkDeviceAddress indirectDeviceAddress); + } // vk #endif // _VKRAYTRACINGUTIL_HPP diff --git a/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingAccelerationStructuresTests.cpp b/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingAccelerationStructuresTests.cpp index 14c71ae..e5798c4 100644 --- a/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingAccelerationStructuresTests.cpp +++ b/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingAccelerationStructuresTests.cpp @@ -800,6 +800,21 @@ void SingleTriangleConfiguration::initShaderBindingTables(de::MovePtrcreateShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1 ); } +bool pointInTriangle2D(const tcu::Vec3& p, const tcu::Vec3& p0, const tcu::Vec3& p1, const tcu::Vec3& p2) +{ + float s = p0.y() * p2.x() - p0.x() * p2.y() + (p2.y() - p0.y()) * p.x() + (p0.x() - p2.x()) * p.y(); + float t = p0.x() * p1.y() - p0.y() * p1.x() + (p0.y() - p1.y()) * p.x() + (p1.x() - p0.x()) * p.y(); + + if ((s < 0) != (t < 0)) + return false; + + float a = -p1.y() * p2.x() + p0.y() * (p2.x() - p1.x()) + p0.x() * (p1.y() - p2.y()) + p1.x() * p2.y(); + + return a < 0 ? + (s <= 0 && s + t >= a) : + (s >= 0 && s + t <= a); +} + bool SingleTriangleConfiguration::verifyImage(BufferWithMemory* resultBuffer, Context& context, TestParams& testParams) { tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat()); diff --git a/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingTests.cpp b/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingTests.cpp index 820a28d..62d31e0 100644 --- a/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingTests.cpp +++ b/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingTests.cpp @@ -85,6 +85,7 @@ tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx) group->addChild(createBarycentricCoordinatesTests(testCtx)); group->addChild(createNonUniformArgsTests(testCtx)); group->addChild(createPipelineFlagsTests(testCtx)); + group->addChild(createTraceRays2Tests(testCtx)); return group.release(); } diff --git a/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingTraceRaysTests.cpp b/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingTraceRaysTests.cpp index a4e0d3b..89856c1 100644 --- a/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingTraceRaysTests.cpp +++ b/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingTraceRaysTests.cpp @@ -2,7 +2,7 @@ * Vulkan Conformance Tests * ------------------------ * - * Copyright (c) 2020 The Khronos Group Inc. + * Copyright (c) 2020-2022 The Khronos Group Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,6 +37,9 @@ #include "vkRayTracingUtil.hpp" +#include +#include + namespace vkt { namespace RayTracing @@ -73,6 +76,13 @@ struct TestParams bool useKhrMaintenance1Semantics; VkTraceRaysIndirectCommand2KHR extendedTraceDimensions; }; +struct TestParams2 +{ + TraceType traceType; + VkExtent3D traceDimensions; + bool partialCopy; + VkQueueFlagBits submitQueue; +}; deUint32 getShaderGroupSize (const InstanceInterface& vki, const VkPhysicalDevice physicalDevice) @@ -104,6 +114,16 @@ VkExtent3D getImageExtent (const T cmd) return (isNullTrace(cmd) ? makeExtent3D(8u, 8u, 1u) : makeExtent3D(cmd.width, cmd.height, cmd.depth)); } +bool isNullExtent (const VkExtent3D& extent) +{ + return (extent.width == 0u || extent.height == 0u || extent.depth == 0u); +} + +VkExtent3D getNonNullImageExtent (const VkExtent3D& extent) +{ + return (isNullExtent(extent) ? makeExtent3D(8u, 8u, 1u) : makeExtent3D(extent.width, extent.height, extent.depth)); +} + VkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, deUint32 depth, VkFormat format) { const VkImageCreateInfo imageCreateInfo = @@ -128,6 +148,70 @@ VkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, deUint32 return imageCreateInfo; } +std::tuple getQueueFamilyIndexAtExact (const DeviceInterface& vkd, + const InstanceInterface& vki, + VkPhysicalDevice physDevice, + VkDevice device, + VkQueueFlagBits bits, + deUint32 queueIndex = 0) +{ + bool found = false; + VkQueue queue = 0; + deUint32 queueFamilyCount = 0; + deUint32 queueFamilyIndex = std::numeric_limits::max(); + + vki.getPhysicalDeviceQueueFamilyProperties(physDevice, &queueFamilyCount, nullptr); + + std::vector queueFamilies(queueFamilyCount); + vki.getPhysicalDeviceQueueFamilyProperties(physDevice, &queueFamilyCount, queueFamilies.data()); + + for (uint32_t index = 0; index < queueFamilyCount; ++index) + { + if ((queueFamilies[index].queueFlags & bits) == bits) + { + queueFamilyIndex = index; + break; + } + } + + if (std::numeric_limits::max() != queueFamilyIndex) + { + found = true; + vkd.getDeviceQueue(device, queueFamilyIndex, queueIndex, &queue); + } + + return { found, queue, queueFamilyIndex }; +} + +typedef std::vector> BlasVec; +auto initTopAccelerationStructure (VkCommandBuffer cmdBuffer, + const BlasVec& bottomLevelAccelerationStructures, + Context& context, + const VkExtent3D& imageExtent) -> de::MovePtr +{ + const DeviceInterface& vkd = context.getDeviceInterface(); + const VkDevice device = context.getDevice(); + Allocator& allocator = context.getDefaultAllocator(); + const deUint32 instanceCount = imageExtent.depth * imageExtent.height * imageExtent.width / 2; + + de::MovePtr result = makeTopLevelAccelerationStructure(); + result->setInstanceCount(instanceCount); + + deUint32 currentInstanceIndex = 0; + + for (deUint32 z = 0; z < imageExtent.depth; ++z) + for (deUint32 y = 0; y < imageExtent.height; ++y) + for (deUint32 x = 0; x < imageExtent.width; ++x) + { + if (((x + y + z) % 2) == 0) + continue; + result->addInstance(bottomLevelAccelerationStructures[currentInstanceIndex++]); + } + result->createAndBuild(vkd, device, cmdBuffer, allocator); + + return result; +} + class RayTracingTraceRaysIndirectTestCase : public TestCase { public: @@ -150,9 +234,8 @@ public: protected: std::vector> initBottomAccelerationStructures (VkCommandBuffer cmdBuffer); - de::MovePtr initTopAccelerationStructure (VkCommandBuffer cmdBuffer, - std::vector >& bottomLevelAccelerationStructures); de::MovePtr runTest (); + private: TestParams m_data; VkExtent3D m_imageExtent; @@ -366,32 +449,6 @@ std::vector > RayTracingTraceRay return result; } -de::MovePtr RayTracingTraceRaysIndirectTestInstance::initTopAccelerationStructure (VkCommandBuffer cmdBuffer, - std::vector >& bottomLevelAccelerationStructures) -{ - const DeviceInterface& vkd = m_context.getDeviceInterface(); - const VkDevice device = m_context.getDevice(); - Allocator& allocator = m_context.getDefaultAllocator(); - const deUint32 instanceCount = m_imageExtent.depth * m_imageExtent.height * m_imageExtent.width / 2; - - de::MovePtr result = makeTopLevelAccelerationStructure(); - result->setInstanceCount(instanceCount); - - deUint32 currentInstanceIndex = 0; - - for (deUint32 z = 0; z < m_imageExtent.depth; ++z) - for (deUint32 y = 0; y < m_imageExtent.height; ++y) - for (deUint32 x = 0; x < m_imageExtent.width; ++x) - { - if (((x + y + z) % 2) == 0) - continue; - result->addInstance(bottomLevelAccelerationStructures[currentInstanceIndex++]); - } - result->createAndBuild(vkd, device, cmdBuffer, allocator); - - return result; -} - de::MovePtr RayTracingTraceRaysIndirectTestInstance::runTest() { const InstanceInterface& vki = m_context.getInstanceInterface(); @@ -563,7 +620,7 @@ de::MovePtr RayTracingTraceRaysIndirectTestInstance::runTest() cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier); bottomLevelAccelerationStructures = initBottomAccelerationStructures(*cmdBuffer); - topLevelAccelerationStructure = initTopAccelerationStructure(*cmdBuffer, bottomLevelAccelerationStructures); + topLevelAccelerationStructure = initTopAccelerationStructure(*cmdBuffer, bottomLevelAccelerationStructures, m_context, m_imageExtent); if (m_data.traceType == TraceType::INDIRECT_GPU) { @@ -701,6 +758,573 @@ std::string makeDimensionsName (const T cmd) return name.str(); } +using namespace tcu; + +class TraceRaysIndirect2Instance : public TestInstance +{ +public: + TraceRaysIndirect2Instance (Context& context, + const TestParams2& params); + virtual ~TraceRaysIndirect2Instance (void) override = default; + virtual TestStatus iterate (void) override; + +protected: + void makeIndirectStructAndFlush (BufferWithMemory& buffer, + const bool source, + const BufferWithMemory& rgenSbt, + const BufferWithMemory& hitSbt, + const BufferWithMemory& missSbt, + const BufferWithMemory& callSbt) const; + void initBottomAccellStructures (VkCommandBuffer cmdBuffer, + BottomLevelAccelerationStructurePool& pool, + const size_t& batchStructCount) const; +private: + TestParams2 m_params; + const VkExtent3D m_imageExtent; +}; + +class TraceRaysIndirect2Case : public TestCase +{ +public: + TraceRaysIndirect2Case (TestContext& testCtx, const std::string& name, const TestParams2& params); + virtual ~TraceRaysIndirect2Case (void) override = default; + virtual void initPrograms (SourceCollections& programCollection) const override; + virtual TestInstance* createInstance (Context& context) const override; + virtual void checkSupport (Context& context) const override; +private: + TestParams2 m_params; +}; + +TraceRaysIndirect2Case::TraceRaysIndirect2Case (TestContext& testCtx, const std::string& name, const TestParams2& params) + : TestCase (testCtx, name, std::string()) + , m_params (params) +{ +} + +TestInstance* TraceRaysIndirect2Case::createInstance (Context& context) const +{ + return new TraceRaysIndirect2Instance(context, m_params); +} + +// note that this/these name(s) should be auto-generated but they do not +#ifndef VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME +#define VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME "VK_KHR_acceleration_structure" +#endif + +void TraceRaysIndirect2Case::checkSupport (Context& context) const +{ + context.requireInstanceFunctionality(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); + context.requireDeviceFunctionality(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME); + context.requireDeviceFunctionality(VK_KHR_RAY_TRACING_MAINTENANCE_1_EXTENSION_NAME); + + const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures(); + if (features.shaderInt64 == VK_FALSE) + TCU_THROW(NotSupportedError, "64-bit integers not supported by device"); + + const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures(); + if (accelerationStructureFeaturesKHR.accelerationStructure == VK_FALSE) + TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceAccelerationStructureFeaturesKHR::accelerationStructure"); + + const VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR& maintenance1FeaturesKHR = context.getRayTracingMaintenance1Features(); + if (maintenance1FeaturesKHR.rayTracingMaintenance1 == VK_FALSE) + TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR::rayTracingMaintenance1"); + if (maintenance1FeaturesKHR.rayTracingPipelineTraceRaysIndirect2 == VK_FALSE) + TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR::rayTracingPipelineTraceRaysIndirect2"); + + auto desiredQueue = getQueueFamilyIndexAtExact(context.getDeviceInterface(), + context.getInstanceInterface(), + context.getPhysicalDevice(), + context.getDevice(), + m_params.submitQueue); + if (!std::get<0>(desiredQueue)) + { + std::stringstream errorMsg; + errorMsg << "Desired queue " << m_params.submitQueue << " is not supported by device"; + errorMsg.flush(); + TCU_THROW(NotSupportedError, errorMsg.str()); + } +} + +void TraceRaysIndirect2Case::initPrograms (SourceCollections& programCollection) const +{ + const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true); + { + std::stringstream css; + std::string comp(R"( + #version 460 core + #extension GL_ARB_gpu_shader_int64: enable + struct TraceRaysIndirectCommand + { + uint64_t raygenShaderRecordAddress; + uint64_t raygenShaderRecordSize; + uint64_t missShaderBindingTableAddress; + uint64_t missShaderBindingTableSize; + uint64_t missShaderBindingTableStride; + uint64_t hitShaderBindingTableAddress; + uint64_t hitShaderBindingTableSize; + uint64_t hitShaderBindingTableStride; + uint64_t callableShaderBindingTableAddress; + uint64_t callableShaderBindingTableSize; + uint64_t callableShaderBindingTableStride; + uint width; + uint height; + uint depth; + }; + layout(push_constant) uniform CopyStyle { + uint full; + } cs; + layout(binding = 0) uniform IndirectCommandsUBO { + TraceRaysIndirectCommand indirectCommands; + } ubo; + layout(binding = 1) buffer IndirectCommandsSBO { + TraceRaysIndirectCommand indirectCommands; + }; + void main() + { + if (cs.full != 0) { + indirectCommands.raygenShaderRecordAddress = ubo.indirectCommands.raygenShaderRecordAddress; + indirectCommands.raygenShaderRecordSize = ubo.indirectCommands.raygenShaderRecordSize; + indirectCommands.missShaderBindingTableAddress = ubo.indirectCommands.missShaderBindingTableAddress; + indirectCommands.missShaderBindingTableSize = ubo.indirectCommands.missShaderBindingTableSize; + indirectCommands.missShaderBindingTableStride = ubo.indirectCommands.missShaderBindingTableStride; + indirectCommands.hitShaderBindingTableAddress = ubo.indirectCommands.hitShaderBindingTableAddress; + indirectCommands.hitShaderBindingTableSize = ubo.indirectCommands.hitShaderBindingTableSize; + indirectCommands.hitShaderBindingTableStride = ubo.indirectCommands.hitShaderBindingTableStride; + indirectCommands.callableShaderBindingTableAddress = ubo.indirectCommands.callableShaderBindingTableAddress; + indirectCommands.callableShaderBindingTableSize = ubo.indirectCommands.callableShaderBindingTableSize; + indirectCommands.callableShaderBindingTableStride = ubo.indirectCommands.callableShaderBindingTableStride; + } + else { + indirectCommands.raygenShaderRecordAddress = ubo.indirectCommands.raygenShaderRecordAddress; + + indirectCommands.missShaderBindingTableStride = ubo.indirectCommands.missShaderBindingTableStride; + + indirectCommands.hitShaderBindingTableSize = ubo.indirectCommands.hitShaderBindingTableSize; + + indirectCommands.callableShaderBindingTableAddress = ubo.indirectCommands.callableShaderBindingTableAddress; + indirectCommands.callableShaderBindingTableStride = ubo.indirectCommands.callableShaderBindingTableStride; + } + + indirectCommands.width = ubo.indirectCommands.width; + indirectCommands.height = ubo.indirectCommands.height; + indirectCommands.depth = ubo.indirectCommands.depth; + + })"); + + programCollection.glslSources.add("compute_indirect_command") << glu::ComputeSource(comp) << buildOptions; + } + + { + std::stringstream css; + css << + "#version 460 core\n" + "#extension GL_EXT_ray_tracing : require\n" + "layout(location = 0) rayPayloadEXT uvec4 hitValue;\n" + "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n" + "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n" + "\n" + "void main()\n" + "{\n" + " float tmin = 0.0;\n" + " float tmax = 1.0;\n" + " vec3 origin = vec3(float(gl_LaunchIDEXT.x) + 0.5f, float(gl_LaunchIDEXT.y) + 0.5f, float(gl_LaunchIDEXT.z + 0.5f));\n" + " vec3 direct = vec3(0.0, 0.0, -1.0);\n" + " hitValue = uvec4(0,0,0,0);\n" + " traceRayEXT(topLevelAS, 0, 0xFF, 0, 0, 0, origin, tmin, direct, tmax, 0);\n" + " imageStore(result, ivec3(gl_LaunchIDEXT), hitValue);\n" + "}\n"; + programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions; + } + + { + std::stringstream css; + css << + "#version 460 core\n" + "#extension GL_EXT_ray_tracing : require\n" + "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n" + "void main()\n" + "{\n" + " hitValue = uvec4(" << kHitColorValue << ",0,0,1);\n" + "}\n"; + programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions; + } + + { + std::stringstream css; + css << + "#version 460 core\n" + "#extension GL_EXT_ray_tracing : require\n" + "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n" + "void main()\n" + "{\n" + " hitValue = uvec4(" << kMissColorValue << ",0,0,1);\n" + "}\n"; + + programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions; + } +} + +TraceRaysIndirect2Instance::TraceRaysIndirect2Instance (Context& context, const TestParams2& params) + : TestInstance (context) + , m_params (params) + , m_imageExtent (getNonNullImageExtent(params.traceDimensions)) +{ +} + +void TraceRaysIndirect2Instance::makeIndirectStructAndFlush (BufferWithMemory& buffer, + const bool source, + const BufferWithMemory& rgenSbt, + const BufferWithMemory& hitSbt, + const BufferWithMemory& missSbt, + const BufferWithMemory& callSbt) const +{ + DE_UNREF(callSbt); + + const DeviceInterface& vkd = m_context.getDeviceInterface(); + const InstanceInterface& vki = m_context.getInstanceInterface(); + const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); + const VkDevice device = m_context.getDevice(); + const deUint32 shaderGroupHandleSize = getShaderGroupSize(vki, physicalDevice); + Allocation& alloc = buffer.getAllocation(); + + VkTraceRaysIndirectCommand2KHR data {}; + + if (m_params.traceType == TraceType::INDIRECT_GPU && m_params.partialCopy) + { + if (source) + { + data.raygenShaderRecordAddress = getBufferDeviceAddress(vkd, device, *rgenSbt, 0); + data.missShaderBindingTableStride = shaderGroupHandleSize; + data.hitShaderBindingTableSize = shaderGroupHandleSize; + data.callableShaderBindingTableAddress = 0; + data.callableShaderBindingTableStride = 0; + } + else + { + data.raygenShaderRecordSize = shaderGroupHandleSize; + data.missShaderBindingTableAddress = getBufferDeviceAddress(vkd, device, *missSbt, 0); + data.missShaderBindingTableSize = shaderGroupHandleSize; + data.hitShaderBindingTableAddress = getBufferDeviceAddress(vkd, device, *hitSbt, 0); + data.hitShaderBindingTableStride = shaderGroupHandleSize; + data.callableShaderBindingTableSize = 0; + } + } + else + { + data.raygenShaderRecordAddress = getBufferDeviceAddress(vkd, device, *rgenSbt, 0); + data.raygenShaderRecordSize = shaderGroupHandleSize; + + data.missShaderBindingTableAddress = getBufferDeviceAddress(vkd, device, *missSbt, 0); + data.missShaderBindingTableSize = shaderGroupHandleSize; + data.missShaderBindingTableStride = shaderGroupHandleSize; + + data.hitShaderBindingTableAddress = getBufferDeviceAddress(vkd, device, *hitSbt, 0); + data.hitShaderBindingTableSize = shaderGroupHandleSize; + data.hitShaderBindingTableStride = shaderGroupHandleSize; + + data.callableShaderBindingTableAddress = 0; + data.callableShaderBindingTableSize = 0; + data.callableShaderBindingTableStride = 0; + } + + data.width = m_params.traceDimensions.width; + data.height = m_params.traceDimensions.height; + data.depth = m_params.traceDimensions.depth; + + deMemcpy(alloc.getHostPtr(), &data, sizeof(data)); + flushMappedMemoryRange(vkd, device, alloc.getMemory(), alloc.getOffset(), VK_WHOLE_SIZE); +} + +void TraceRaysIndirect2Instance::initBottomAccellStructures (VkCommandBuffer cmdBuffer, + BottomLevelAccelerationStructurePool& pool, + const size_t& batchStructCount) const +{ + const DeviceInterface& vkd = m_context.getDeviceInterface(); + const VkDevice device = m_context.getDevice(); + Allocator& allocator = m_context.getDefaultAllocator(); + + pool.batchStructCount(batchStructCount); + pool.batchGeomCount(batchStructCount * 8); + + tcu::Vec3 v0(0.0, 1.0, 0.0); + tcu::Vec3 v1(0.0, 0.0, 0.0); + tcu::Vec3 v2(1.0, 1.0, 0.0); + tcu::Vec3 v3(1.0, 0.0, 0.0); + + for (deUint32 z = 0; z < m_imageExtent.depth; ++z) + for (deUint32 y = 0; y < m_imageExtent.height; ++y) + for (deUint32 x = 0; x < m_imageExtent.width; ++x) + { + // let's build a 3D chessboard of geometries + if (((x + y + z) % 2) == 0) + continue; + tcu::Vec3 xyz((float)x, (float)y, (float)z); + std::vector geometryData; + + auto bottomLevelAccelerationStructure = pool.add(); + bottomLevelAccelerationStructure->setGeometryCount(1u); + + geometryData.push_back(xyz + v0); + geometryData.push_back(xyz + v1); + geometryData.push_back(xyz + v2); + geometryData.push_back(xyz + v2); + geometryData.push_back(xyz + v1); + geometryData.push_back(xyz + v3); + + bottomLevelAccelerationStructure->addGeometry(geometryData, true); + } + + pool.batchCreate(vkd, device, allocator); + pool.batchBuild(vkd, device, cmdBuffer); +} + +TestStatus TraceRaysIndirect2Instance::iterate (void) +{ + const InstanceInterface& vki = m_context.getInstanceInterface(); + const DeviceInterface& vkd = m_context.getDeviceInterface(); + const VkDevice device = m_context.getDevice(); + const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); + const auto queueAndFamilyIndex = getQueueFamilyIndexAtExact(vkd, vki, physicalDevice, device, m_params.submitQueue); + const VkQueue queue = std::get<1>(queueAndFamilyIndex); + const deUint32 queueFamilyIndex = std::get<2>(queueAndFamilyIndex); + Allocator& allocator = m_context.getDefaultAllocator(); + const deUint32 width = m_imageExtent.width; + const deUint32 height = m_imageExtent.height; + const deUint32 depth = m_imageExtent.depth; + const deUint32 pixelCount = width * height * depth; + const deUint32 shaderGroupHandleSize = getShaderGroupSize(vki, physicalDevice); + const deUint32 shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice); + + Move computeDescriptorSetLayout; + Move computeDescriptorPool; + Move computeDescriptorSet; + Move computePipelineLayout; + Move computeShader; + Move computePipeline; + + if (m_params.traceType == TraceType::INDIRECT_GPU) + { + computeDescriptorSetLayout = DescriptorSetLayoutBuilder() + .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) + .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) + .build(vkd, device); + computeDescriptorPool = DescriptorPoolBuilder() + .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) + .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) + .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); + const VkPushConstantRange full { VK_SHADER_STAGE_COMPUTE_BIT, 0, deUint32(sizeof(deUint32)) }; + computeDescriptorSet = makeDescriptorSet(vkd, device, *computeDescriptorPool, *computeDescriptorSetLayout); + computePipelineLayout = makePipelineLayout(vkd, device, 1, &computeDescriptorSetLayout.get(), 1, &full); + + computeShader = createShaderModule(vkd, device, m_context.getBinaryCollection().get("compute_indirect_command"), 0); + const VkPipelineShaderStageCreateInfo pipelineShaderStageParams = + { + VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + VkPipelineShaderStageCreateFlags(0u), // VkPipelineShaderStageCreateFlags flags; + VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage; + *computeShader, // VkShaderModule module; + "main", // const char* pName; + DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; + }; + const VkComputePipelineCreateInfo pipelineCreateInfo = + { + VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + VkPipelineCreateFlags(0u), // VkPipelineCreateFlags flags; + pipelineShaderStageParams, // VkPipelineShaderStageCreateInfo stage; + *computePipelineLayout, // VkPipelineLayout layout; + DE_NULL, // VkPipeline basePipelineHandle; + 0, // deInt32 basePipelineIndex; + }; + + computePipeline = vk::createComputePipeline(vkd, device, (VkPipelineCache)0u, &pipelineCreateInfo); + } + + const Move descriptorSetLayout = DescriptorSetLayoutBuilder() + .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES) + .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES) + .build(vkd, device); + const Move descriptorPool = DescriptorPoolBuilder() + .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) + .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR) + .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); + const Move descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout); + const Move pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get()); + + de::MovePtr rayTracingPipeline = de::newMovePtr(); + rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("rgen"), 0), 0); + rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("chit"), 0), 1); + rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("miss"), 0), 2); + Move pipeline = rayTracingPipeline->createPipeline(vkd, device, *pipelineLayout); + + const de::MovePtr rgenSbt = rayTracingPipeline->createShaderBindingTable(vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1 ); + const de::MovePtr hitSbt = rayTracingPipeline->createShaderBindingTable(vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1 ); + const de::MovePtr missSbt = rayTracingPipeline->createShaderBindingTable(vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1 ); + + const VkFormat imageFormat = VK_FORMAT_R32_UINT; + const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(width, height, depth, imageFormat); + const VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0, 1u); + const de::MovePtr image = de::MovePtr(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any)); + const Move imageView = makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, imageFormat, imageSubresourceRange); + + const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(pixelCount*sizeof(deUint32), VK_BUFFER_USAGE_TRANSFER_DST_BIT); + const VkImageSubresourceLayers resultBufferImageSubresourceLayers = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u); + const VkBufferImageCopy resultBufferImageRegion = makeBufferImageCopy(m_params.traceDimensions, resultBufferImageSubresourceLayers); + de::MovePtr resultBuffer = de::MovePtr(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible)); + Allocation& resultBufferAllocation = resultBuffer->getAllocation(); + + const VkDescriptorImageInfo descriptorImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL); + + // create indirect command buffer and fill it with parameter values + const VkDeviceSize bufferSize = sizeof(VkTraceRaysIndirectCommand2KHR); + de::MovePtr indirectBuffer; + de::MovePtr uniformBuffer; + + const bool indirectGpu = (m_params.traceType == TraceType::INDIRECT_GPU); + VkBufferUsageFlags indirectBufferUsageFlags = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | ( indirectGpu ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : VK_BUFFER_USAGE_TRANSFER_DST_BIT ); + const VkBufferCreateInfo indirectBufferCreateInfo = makeBufferCreateInfo(bufferSize, indirectBufferUsageFlags); + vk::MemoryRequirement indirectBufferMemoryRequirement = MemoryRequirement::DeviceAddress | MemoryRequirement::HostVisible; + indirectBuffer = de::MovePtr(new BufferWithMemory(vkd, device, allocator, indirectBufferCreateInfo, indirectBufferMemoryRequirement)); + + if (m_params.traceType == TraceType::INDIRECT_GPU) + { + const VkBufferCreateInfo uniformBufferCreateInfo = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT); + uniformBuffer = de::MovePtr(new BufferWithMemory(vkd, device, allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible)); + makeIndirectStructAndFlush(*uniformBuffer, true, *rgenSbt, *hitSbt, *missSbt, *missSbt); + makeIndirectStructAndFlush(*indirectBuffer, false, *rgenSbt, *hitSbt, *missSbt, *missSbt); + } + else if (m_params.traceType == TraceType::INDIRECT_CPU) + { + makeIndirectStructAndFlush(*indirectBuffer, true, *rgenSbt, *hitSbt, *missSbt, *missSbt); + } + else + { + TCU_THROW(NotSupportedError, "Invalid test parameters"); + } + + de::MovePtr topLevelAccelerationStructure; + BottomLevelAccelerationStructurePool blasPool; + const Move cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex); + const Move cmdBuffer = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); + + beginCommandBuffer(vkd, *cmdBuffer, 0u); + { + const VkImageMemoryBarrier preImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + **image, imageSubresourceRange); + cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier); + + const VkClearValue clearValue = makeClearValueColorU32(kClearColorValue, 0u, 0u, 0u); + vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange); + + const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, + **image, imageSubresourceRange); + cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier); + + + initBottomAccellStructures(*cmdBuffer, blasPool, 4); + topLevelAccelerationStructure = initTopAccelerationStructure(*cmdBuffer, blasPool.structures(), m_context, m_imageExtent); + + if (m_params.traceType == TraceType::INDIRECT_GPU) + { + const deUint32 fullCopyStyle = m_params.partialCopy ? 0 : 1; + const VkDescriptorBufferInfo uniformBufferDescriptorInfo = makeDescriptorBufferInfo(**uniformBuffer, 0ull, bufferSize); + const VkDescriptorBufferInfo indirectBufferDescriptorInfo = makeDescriptorBufferInfo(**indirectBuffer, 0ull, bufferSize); + DescriptorSetUpdateBuilder() + .writeSingle(*computeDescriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &uniformBufferDescriptorInfo) + .writeSingle(*computeDescriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &indirectBufferDescriptorInfo) + .update(vkd, device); + + vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline); + vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipelineLayout, 0u, 1u, &computeDescriptorSet.get(), 0u, DE_NULL); + vkd.cmdPushConstants(*cmdBuffer, *computePipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, deUint32(sizeof(deUint32)), &fullCopyStyle); + vkd.cmdDispatch(*cmdBuffer, 1, 1, 1); + + const VkBufferMemoryBarrier fillIndirectBufferMemoryBarrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_INDIRECT_COMMAND_READ_BIT, + **indirectBuffer, 0ull, bufferSize); + cmdPipelineBufferMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, &fillIndirectBufferMemoryBarrier); + } + + const TopLevelAccelerationStructure* topLevelAccelerationStructurePtr = topLevelAccelerationStructure.get(); + VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = + { + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType; + DE_NULL, // const void* pNext; + 1u, // deUint32 accelerationStructureCount; + topLevelAccelerationStructurePtr->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures; + }; + + DescriptorSetUpdateBuilder() + .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo) + .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet) + .update(vkd, device); + + vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL); + + vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipeline); + + cmdTraceRaysIndirect2(vkd, *cmdBuffer, getBufferDeviceAddress(vkd, device, **indirectBuffer, 0)); + + const VkMemoryBarrier postTraceMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT); + const VkMemoryBarrier postCopyMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT); + cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier); + + vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion); + + cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier); + } + endCommandBuffer(vkd, *cmdBuffer); + + submitCommandsAndWait(vkd, device, queue, cmdBuffer.get()); + + invalidateMappedMemoryRange(vkd, device, resultBufferAllocation.getMemory(), resultBufferAllocation.getOffset(), VK_WHOLE_SIZE); + + // run test using arrays of pointers + const deUint32* bufferPtr = (deUint32*)resultBufferAllocation.getHostPtr(); + const bool noWrites = isNullExtent(m_params.traceDimensions); + + const auto allocationCount = blasPool.getAllocationCount(); + deUint32 failures = 0; + deUint32 pos = 0; + deUint32 all = 0; + + // verify results + for (deUint32 z = 0; z < depth; ++z) + for (deUint32 y = 0; y < height; ++y) + for (deUint32 x = 0; x < width; ++x) + { + const deUint32 expectedResult = (noWrites ? kClearColorValue : (((x + y + z) % 2) ? kHitColorValue : kMissColorValue)); + if (bufferPtr[pos] != expectedResult) + failures++; + ++pos; + ++all; + } + + if (failures == 0) + return tcu::TestStatus::pass(std::to_string(allocationCount) +" allocations"); + else + { + const auto msg = std::to_string(allocationCount) +" allocations, " + std::to_string(failures) + " failures from " + std::to_string(all); + return tcu::TestStatus::fail(msg); + } +} + +std::string makeDimensionsName (const VkTraceRaysIndirectCommandKHR& cmd) +{ + std::ostringstream name; + name << cmd.width << "_" << cmd.height << "_" << cmd.depth; + return name.str(); +} + +std::string makeDimensionsName (const VkExtent3D& extent) +{ + std::ostringstream name; + name << extent.width << "x" << extent.height << "x" << extent.depth; + return name.str(); +} + } // anonymous tcu::TestCaseGroup* createTraceRaysTests(tcu::TestContext& testCtx) @@ -806,6 +1430,70 @@ tcu::TestCaseGroup* createTraceRaysMaintenance1Tests(tcu::TestContext& testCtx) return group.release(); } +tcu::TestCaseGroup* createTraceRays2Tests(tcu::TestContext& testCtx) +{ + auto group = new tcu::TestCaseGroup(testCtx, "trace_rays_indirect2", "Tests veryfying vkCmdTraceRaysIndirect2KHR command"); + + std::pair const bufferSources[] + { + { TraceType::INDIRECT_CPU, "indirect_cpu" }, + { TraceType::INDIRECT_GPU, "indirect_gpu" }, + }; + + std::pair const copyStyles[] + { + { true, "full_copy" }, + { false, "partial_copy" } + }; + + std::pair submitQueues[] + { + { VK_QUEUE_GRAPHICS_BIT, "submit_graphics" }, + { VK_QUEUE_COMPUTE_BIT, "submit_compute" } + }; + + const VkExtent3D traceDimensions[] = + { + { 11, 17, 1 }, + { 19, 11, 2 }, + { 23, 47, 3 }, + { 47, 19, 4 } + }; + + for (const auto& bufferSource : bufferSources) + { + auto bufferSourceGroup = new TestCaseGroup(testCtx, bufferSource.second, ""); + + for (const auto& copyStyle : copyStyles) + { + auto copyStyleGroup = new TestCaseGroup(testCtx, copyStyle.second, ""); + + for (const auto& submitQueue : submitQueues) + { + auto submitQueueGroup = new TestCaseGroup(testCtx, submitQueue.second, ""); + + for (const auto& traceDimension : traceDimensions) + { + TestParams2 testParams + { + bufferSource.first, + traceDimension, + copyStyle.first, + submitQueue.first + }; + const auto testName = makeDimensionsName(traceDimension); + submitQueueGroup->addChild(new TraceRaysIndirect2Case(testCtx, testName.c_str(), testParams)); + } + copyStyleGroup->addChild(submitQueueGroup); + } + bufferSourceGroup->addChild(copyStyleGroup); + } + group->addChild(bufferSourceGroup); + } + + return group; +} + } // RayTracing } // vkt diff --git a/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingTraceRaysTests.hpp b/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingTraceRaysTests.hpp index d8609a0..6b829d1 100644 --- a/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingTraceRaysTests.hpp +++ b/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingTraceRaysTests.hpp @@ -4,7 +4,7 @@ * Vulkan Conformance Tests * ------------------------ * - * Copyright (c) 2020 The Khronos Group Inc. + * Copyright (c) 2022 The Khronos Group Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,6 +33,7 @@ namespace RayTracing tcu::TestCaseGroup* createTraceRaysTests(tcu::TestContext& testCtx); tcu::TestCaseGroup* createTraceRaysMaintenance1Tests(tcu::TestContext& testCtx); +tcu::TestCaseGroup* createTraceRays2Tests(tcu::TestContext& testCtx); } // RayTracing } // vkt diff --git a/external/vulkancts/mustpass/main/vk-default/ray-tracing-pipeline.txt b/external/vulkancts/mustpass/main/vk-default/ray-tracing-pipeline.txt index 3bdd354..66ee6e6 100644 --- a/external/vulkancts/mustpass/main/vk-default/ray-tracing-pipeline.txt +++ b/external/vulkancts/mustpass/main/vk-default/ray-tracing-pipeline.txt @@ -9817,3 +9817,35 @@ dEQP-VK.ray_tracing_pipeline.pipeline_no_null_shaders_flag.cpu.tri_and_box.strid dEQP-VK.ray_tracing_pipeline.pipeline_no_null_shaders_flag.cpu.tri_and_box.stride_5.offset_7.no_libs.any_or_chit_or_isect dEQP-VK.ray_tracing_pipeline.pipeline_no_null_shaders_flag.cpu.tri_and_box.stride_5.offset_7.no_libs.any_or_chit dEQP-VK.ray_tracing_pipeline.pipeline_no_null_shaders_flag.cpu.tri_and_box.stride_5.offset_7.no_libs.any_or_chit_or_miss +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_graphics.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_graphics.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_graphics.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_graphics.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_compute.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_compute.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_compute.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.full_copy.submit_compute.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_graphics.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_graphics.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_graphics.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_graphics.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_compute.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_compute.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_compute.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_cpu.partial_copy.submit_compute.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_graphics.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_graphics.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_graphics.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_graphics.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_compute.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_compute.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_compute.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.full_copy.submit_compute.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_graphics.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_graphics.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_graphics.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_graphics.47x19x4 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_compute.11x17x1 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_compute.19x11x2 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_compute.23x47x3 +dEQP-VK.ray_tracing_pipeline.trace_rays_indirect2.indirect_gpu.partial_copy.submit_compute.47x19x4 -- 2.7.4