Add missing tests for NO_DUPLICATE_ANY_HIT flag used against AABBs and triangles.
authorDominik Witczak <dominik.witczak@amd.com>
Tue, 28 Jul 2020 15:44:10 +0000 (17:44 +0200)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Thu, 6 Aug 2020 08:17:38 +0000 (04:17 -0400)
New tests:
dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_*

Components: Vulkan

VK-GL-CTS issue: 2472

Change-Id: I2e1d0860e0c0132c23012dd6853f39da2f6e95d2

AndroidGen.mk
android/cts/master/vk-master-2020-03-01.txt
android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/ray_tracing/CMakeLists.txt
external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingMiscTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingMiscTests.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingTests.cpp
external/vulkancts/mustpass/master/vk-default.txt

index 5bb71bf..6df6668 100644 (file)
@@ -277,6 +277,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingCallableShadersTests.cpp \
        external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingCaptureReplayTests.cpp \
        external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingMemGuaranteeTests.cpp \
+       external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingMiscTests.cpp \
        external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingNullASTests.cpp \
        external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingPipelineLibraryTests.cpp \
        external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingShaderBindingTableTests.cpp \
index d0cf802..6fe7b38 100644 (file)
@@ -292115,6 +292115,14 @@ dEQP-VK.ray_tracing_pipeline.capture_replay.acceleration_structures.serializatio
 dEQP-VK.ray_tracing_pipeline.capture_replay.acceleration_structures.serialization.gpu_built.top_acceleration_structure.aabbs
 dEQP-VK.ray_tracing_pipeline.capture_replay.acceleration_structures.serialization.gpu_built.bottom_acceleration_structure.triangles
 dEQP-VK.ray_tracing_pipeline.capture_replay.acceleration_structures.serialization.gpu_built.bottom_acceleration_structure.aabbs
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TL1BL1G_AABB
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TL1BLnG_AABB
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TLnBL1G_AABB
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TLnBLnG_AABB
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TL1BL1G_tri
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TL1BLnG_tri
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TLnBL1G_tri
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TLnBLnG_tri
 dEQP-VK.ray_query.builtin.flow.vert.triangles
 dEQP-VK.ray_query.builtin.flow.vert.aabbs
 dEQP-VK.ray_query.builtin.flow.tesc.triangles
index d026da4..3f3aece 100644 (file)
@@ -702308,6 +702308,14 @@ dEQP-VK.ray_tracing_pipeline.capture_replay.acceleration_structures.serializatio
 dEQP-VK.ray_tracing_pipeline.capture_replay.acceleration_structures.serialization.gpu_built.top_acceleration_structure.aabbs
 dEQP-VK.ray_tracing_pipeline.capture_replay.acceleration_structures.serialization.gpu_built.bottom_acceleration_structure.triangles
 dEQP-VK.ray_tracing_pipeline.capture_replay.acceleration_structures.serialization.gpu_built.bottom_acceleration_structure.aabbs
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TL1BL1G_AABB
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TL1BLnG_AABB
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TLnBL1G_AABB
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TLnBLnG_AABB
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TL1BL1G_tri
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TL1BLnG_tri
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TLnBL1G_tri
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TLnBLnG_tri
 dEQP-VK.ray_query.builtin.flow.vert.triangles
 dEQP-VK.ray_query.builtin.flow.vert.aabbs
 dEQP-VK.ray_query.builtin.flow.tesc.triangles
index 5b49d50..36d8dcd 100644 (file)
@@ -15,6 +15,8 @@ set(DEQP_VK_RAY_TRACING_SRCS
        vktRayTracingTraceRaysIndirectTests.hpp
        vktRayTracingMemGuaranteeTests.cpp
        vktRayTracingMemGuaranteeTests.hpp
+       vktRayTracingMiscTests.cpp
+       vktRayTracingMiscTests.hpp
        vktRayTracingNullASTests.cpp
        vktRayTracingNullASTests.hpp
        vktRayTracingShaderBindingTableTests.cpp
diff --git a/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingMiscTests.cpp b/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingMiscTests.cpp
new file mode 100644 (file)
index 0000000..957b52a
--- /dev/null
@@ -0,0 +1,1145 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2020 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.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Ray Tracing Misc tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktRayTracingMiscTests.hpp"
+
+#include "vkDefs.hpp"
+
+#include "vktTestCase.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkObjUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkBarrierUtil.hpp"
+#include "vkBufferWithMemory.hpp"
+#include "vkImageWithMemory.hpp"
+#include "vkTypeUtil.hpp"
+
+#include "vkRayTracingUtil.hpp"
+
+#include "deRandom.hpp"
+
+namespace vkt
+{
+namespace RayTracing
+{
+namespace
+{
+using namespace vk;
+using namespace std;
+
+enum class GeometryType
+{
+       FIRST = 0,
+
+       AABB            = FIRST,
+       TRIANGLES,
+
+       COUNT
+};
+
+enum class ShaderGroups
+{
+       FIRST_GROUP             = 0,
+       RAYGEN_GROUP    = FIRST_GROUP,
+       MISS_GROUP,
+       HIT_GROUP,
+       GROUP_COUNT
+};
+
+enum class TestType
+{
+       NO_DUPLICATE_ANY_HIT
+};
+
+enum class AccelerationStructureLayout
+{
+       FIRST = 0,
+
+       ONE_TL_ONE_BL_ONE_GEOMETRY    = FIRST,
+       ONE_TL_ONE_BL_MANY_GEOMETRIES,
+       ONE_TL_MANY_BLS_ONE_GEOMETRY,
+       ONE_TL_MANY_BLS_MANY_GEOMETRIES,
+
+       COUNT
+};
+
+static const VkFlags   ALL_RAY_TRACING_STAGES  = VK_SHADER_STAGE_RAYGEN_BIT_KHR
+                                                                                               | VK_SHADER_STAGE_ANY_HIT_BIT_KHR
+                                                                                               | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
+                                                                                               | VK_SHADER_STAGE_MISS_BIT_KHR
+                                                                                               | VK_SHADER_STAGE_INTERSECTION_BIT_KHR
+                                                                                               | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
+
+struct CaseDef
+{
+       TestType                                        type;
+       GeometryType                            geometryType;
+       AccelerationStructureLayout     asLayout;
+
+       deUint32 nRaysToTrace;
+};
+
+/* Helper global functions */
+static const char* getSuffixForASLayout(const AccelerationStructureLayout& layout)
+{
+       const char* result = "?!";
+
+       switch (layout)
+       {
+               case AccelerationStructureLayout::ONE_TL_ONE_BL_ONE_GEOMETRY:           result = "1TL1BL1G"; break;
+               case AccelerationStructureLayout::ONE_TL_ONE_BL_MANY_GEOMETRIES:        result = "1TL1BLnG"; break;
+               case AccelerationStructureLayout::ONE_TL_MANY_BLS_ONE_GEOMETRY:         result = "1TLnBL1G"; break;
+               case AccelerationStructureLayout::ONE_TL_MANY_BLS_MANY_GEOMETRIES:      result = "1TLnBLnG"; break;
+
+               default:
+               {
+                       deAssertFail("This should never happen", __FILE__, __LINE__);
+               }
+       }
+
+       return result;
+}
+
+static const char* getSuffixForGeometryType(const GeometryType& type)
+{
+       const char* result = "?!";
+
+       switch (type)
+       {
+               case GeometryType::AABB:                result = "AABB"; break;
+               case GeometryType::TRIANGLES:   result = "tri";  break;
+
+               default:
+               {
+                       deAssertFail("This should never happen", __FILE__, __LINE__);
+               }
+       }
+
+       return result;
+}
+
+/* Acceleration structure data providers.
+ *
+ * These are expected to be reused across different test cases.
+ **/
+class ASProviderBase
+{
+public:
+       virtual ~ASProviderBase()
+       {
+               /* Stub */
+       }
+
+       virtual std::unique_ptr<TopLevelAccelerationStructure>  createTLAS(             Context&                                                        context,
+                                                                                                                                                       const AccelerationStructureLayout&      asLayout,
+                                                                                                                                                       VkCommandBuffer                                         cmdBuffer,
+                                                                                                                                                       const VkGeometryFlagsKHR&                       bottomLevelGeometryFlags)       const = 0;
+       virtual deUint32                                                                                getNPrimitives()                                                                                                                                const = 0;
+
+};
+
+/* A 3D grid built of primitives. Size and distribution of the geometry can be configured at creation time. */
+class GridASProvider : public ASProviderBase
+{
+public:
+       GridASProvider( const tcu::Vec3&                        gridStartXYZ,
+                                       const tcu::Vec3&                        gridCellSizeXYZ,
+                                       const tcu::UVec3&                       gridSizeXYZ,
+                                       const tcu::Vec3&                        gridInterCellDeltaXYZ,
+                                       const GeometryType&                     geometryType)
+               :m_geometryType                 (geometryType),
+                m_gridCellSizeXYZ              (gridCellSizeXYZ),
+                m_gridInterCellDeltaXYZ(gridInterCellDeltaXYZ),
+                m_gridSizeXYZ                  (gridSizeXYZ),
+                m_gridStartXYZ                 (gridStartXYZ)
+       {
+               const auto nCellsNeeded = gridSizeXYZ.x() * gridSizeXYZ.y() * gridSizeXYZ.z();
+
+               for (auto       nCell = 0u;
+                                       nCell < nCellsNeeded;
+                                       nCell++)
+               {
+                       const auto cellX = (((nCell)                                                                            % m_gridSizeXYZ.x() ));
+                       const auto cellY = (((nCell / gridSizeXYZ.x() )                                         % m_gridSizeXYZ.y() ));
+                       const auto cellZ = (((nCell / gridSizeXYZ.x() ) / gridSizeXYZ.y() ) % m_gridSizeXYZ.z() );
+
+                       const auto cellX1Y1Z1 = tcu::Vec3(      m_gridStartXYZ.x() + static_cast<float>(cellX) * m_gridInterCellDeltaXYZ.x(),
+                                                                                               m_gridStartXYZ.y() + static_cast<float>(cellY) * m_gridInterCellDeltaXYZ.y(),
+                                                                                               m_gridStartXYZ.z() + static_cast<float>(cellZ) * m_gridInterCellDeltaXYZ.z() );
+                       const auto cellX2Y2Z2 = tcu::Vec3(      m_gridStartXYZ.x() + static_cast<float>(cellX) * m_gridInterCellDeltaXYZ.x() + m_gridCellSizeXYZ.x(),
+                                                                                               m_gridStartXYZ.y() + static_cast<float>(cellY) * m_gridInterCellDeltaXYZ.y() + m_gridCellSizeXYZ.y(),
+                                                                                               m_gridStartXYZ.z() + static_cast<float>(cellZ) * m_gridInterCellDeltaXYZ.z() + m_gridCellSizeXYZ.z() );
+
+                       if (m_geometryType == GeometryType::AABB)
+                       {
+                               /* Cell = AABB of the cell */
+                               m_vertexVec.push_back(cellX1Y1Z1);
+                               m_vertexVec.push_back(cellX2Y2Z2);
+                       }
+                       else
+                       {
+                               /* Cell == Plane that spans from top-left-front corner to bottom-right-back corner of the cell */
+                               const auto A = tcu::Vec3(       cellX1Y1Z1.x(),
+                                                                                       cellX1Y1Z1.y(),
+                                                                                       cellX1Y1Z1.z() );
+                               const auto B = tcu::Vec3(       cellX2Y2Z2.x(),
+                                                                                       cellX2Y2Z2.y(),
+                                                                                       cellX2Y2Z2.z() );
+                               const auto C = tcu::Vec3(       cellX1Y1Z1.x(),
+                                                                                       cellX2Y2Z2.y(),
+                                                                                       cellX1Y1Z1.z() );
+                               const auto D = tcu::Vec3(       cellX2Y2Z2.x(),
+                                                                                       cellX1Y1Z1.y(),
+                                                                                       cellX2Y2Z2.z() );
+
+                               m_vertexVec.push_back(A);
+                               m_vertexVec.push_back(C);
+                               m_vertexVec.push_back(B);
+
+                               m_vertexVec.push_back(A);
+                               m_vertexVec.push_back(B);
+                               m_vertexVec.push_back(D);
+                       }
+               }
+       }
+
+       std::unique_ptr<TopLevelAccelerationStructure> createTLAS(      Context&                                                        context,
+                                                                                                                               const AccelerationStructureLayout&      asLayout,
+                                                                                                                               VkCommandBuffer                                         cmdBuffer,
+                                                                                                                               const VkGeometryFlagsKHR&                       bottomLevelGeometryFlags) const
+       {
+               Allocator&                                                                              allocator                               = context.getDefaultAllocator           ();
+               const DeviceInterface&                                                  deviceInterface                 = context.getDeviceInterface            ();
+               const VkDevice                                                                  deviceVk                                = context.getDevice                                     ();
+               std::unique_ptr<TopLevelAccelerationStructure>  resultPtr;
+               de::MovePtr<TopLevelAccelerationStructure>              tlPtr                                   = makeTopLevelAccelerationStructure ();
+
+               const auto      nVerticesPerPrimitive   = (m_geometryType == GeometryType::AABB)        ? 2u
+                                                                                                                                                                               : 3u;
+
+               switch (asLayout)
+               {
+                       case AccelerationStructureLayout::ONE_TL_ONE_BL_ONE_GEOMETRY:
+                       {
+                               tlPtr->setInstanceCount(1);
+
+                               {
+                                       de::MovePtr<BottomLevelAccelerationStructure> blPtr = makeBottomLevelAccelerationStructure();
+
+                                       blPtr->setGeometryCount (1u);
+                                       blPtr->addGeometry              (m_vertexVec,
+                                                                                        (m_geometryType == GeometryType::TRIANGLES),
+                                                                                        bottomLevelGeometryFlags);
+
+                                       blPtr->createAndBuild(  deviceInterface,
+                                                                                       deviceVk,
+                                                                                       cmdBuffer,
+                                                                                       allocator);
+
+                                       tlPtr->addInstance(de::SharedPtr<BottomLevelAccelerationStructure>(blPtr.release() ) );
+                               }
+
+                               break;
+                       }
+
+                       case AccelerationStructureLayout::ONE_TL_ONE_BL_MANY_GEOMETRIES:
+                       {
+                               DE_ASSERT( (m_vertexVec.size() % nVerticesPerPrimitive) == 0);
+
+                               tlPtr->setInstanceCount(1);
+
+                               {
+                                       de::MovePtr<BottomLevelAccelerationStructure>   blPtr           = makeBottomLevelAccelerationStructure();
+                                       const auto                                                                              nGeometries = m_vertexVec.size() / nVerticesPerPrimitive;
+
+                                       blPtr->setGeometryCount (nGeometries);
+
+                                       for (deUint32 nGeometry = 0; nGeometry < nGeometries; ++nGeometry)
+                                       {
+                                               std::vector<tcu::Vec3> currentGeometry(nVerticesPerPrimitive);
+
+                                               for (deUint32 nVertex = 0; nVertex < nVerticesPerPrimitive; ++nVertex)
+                                               {
+                                                       currentGeometry.at(nVertex) = m_vertexVec.at(nGeometry * nVerticesPerPrimitive + nVertex);
+                                               }
+
+                                               blPtr->addGeometry      (currentGeometry,
+                                                                                        (m_geometryType == GeometryType::TRIANGLES),
+                                                                                        bottomLevelGeometryFlags);
+                                       }
+
+                                       blPtr->createAndBuild(  deviceInterface,
+                                                                                       deviceVk,
+                                                                                       cmdBuffer,
+                                                                                       allocator);
+
+                                       tlPtr->addInstance(de::SharedPtr<BottomLevelAccelerationStructure>(blPtr.release() ) );
+                               }
+
+                               break;
+                       }
+
+                       case AccelerationStructureLayout::ONE_TL_MANY_BLS_ONE_GEOMETRY:
+                       {
+                               DE_ASSERT( (m_vertexVec.size() % nVerticesPerPrimitive) == 0);
+
+                               const auto nInstances = m_vertexVec.size() / nVerticesPerPrimitive;
+
+                               tlPtr->setInstanceCount(nInstances);
+
+                               for (deUint32 nInstance = 0; nInstance < nInstances; nInstance++)
+                               {
+                                       de::MovePtr<BottomLevelAccelerationStructure>   blPtr                                           = makeBottomLevelAccelerationStructure();
+                                       std::vector<tcu::Vec3>                                                  currentInstanceVertexVec;
+
+                                       for (deUint32 nVertex = 0; nVertex < nVerticesPerPrimitive; ++nVertex)
+                                       {
+                                               currentInstanceVertexVec.push_back(m_vertexVec.at(nInstance * nVerticesPerPrimitive + nVertex) );
+                                       }
+
+                                       blPtr->setGeometryCount (1u);
+                                       blPtr->addGeometry              (currentInstanceVertexVec,
+                                                                                        (m_geometryType == GeometryType::TRIANGLES),
+                                                                                        bottomLevelGeometryFlags);
+
+                                       blPtr->createAndBuild(  deviceInterface,
+                                                                                       deviceVk,
+                                                                                       cmdBuffer,
+                                                                                       allocator);
+
+                                       tlPtr->addInstance(de::SharedPtr<BottomLevelAccelerationStructure>(blPtr.release() ) );
+                               }
+
+                               break;
+                       }
+
+                       case AccelerationStructureLayout::ONE_TL_MANY_BLS_MANY_GEOMETRIES:
+                       {
+                               const auto nPrimitivesDefined   = static_cast<deUint32>(m_vertexVec.size() / nVerticesPerPrimitive);
+                               const auto nPrimitivesPerBLAS   = 4;
+                               const auto nBottomLevelASes             = nPrimitivesDefined / nPrimitivesPerBLAS;
+
+                               DE_ASSERT( (m_vertexVec.size() % nVerticesPerPrimitive)                                                 == 0);
+                               DE_ASSERT( (nPrimitivesDefined % (nPrimitivesPerBLAS * nVerticesPerPrimitive))  == 0);
+
+                               tlPtr->setInstanceCount(nBottomLevelASes);
+
+                               for (deUint32 nBottomLevelAS = 0; nBottomLevelAS < nBottomLevelASes; nBottomLevelAS++)
+                               {
+                                       de::MovePtr<BottomLevelAccelerationStructure> blPtr = makeBottomLevelAccelerationStructure();
+
+                                       blPtr->setGeometryCount(nPrimitivesPerBLAS);
+
+                                       for (deUint32 nGeometry = 0; nGeometry < nPrimitivesPerBLAS; nGeometry++)
+                                       {
+                                               std::vector<tcu::Vec3> currentVertexVec;
+
+                                               for (deUint32 nVertex = 0; nVertex < nVerticesPerPrimitive; ++nVertex)
+                                               {
+                                                       currentVertexVec.push_back(m_vertexVec.at((nBottomLevelAS * nPrimitivesPerBLAS + nGeometry) * nVerticesPerPrimitive + nVertex) );
+                                               }
+
+                                               blPtr->addGeometry(     currentVertexVec,
+                                                                                       (m_geometryType == GeometryType::TRIANGLES),
+                                                                                       bottomLevelGeometryFlags);
+                                       }
+
+                                       blPtr->createAndBuild(  deviceInterface,
+                                                                                       deviceVk,
+                                                                                       cmdBuffer,
+                                                                                       allocator);
+                                       tlPtr->addInstance(             de::SharedPtr<BottomLevelAccelerationStructure>(blPtr.release() ) );
+                               }
+
+                               break;
+                       }
+
+                       default:
+                       {
+                               deAssertFail("This should never happen", __FILE__, __LINE__);
+                       }
+               }
+
+               tlPtr->createAndBuild(  deviceInterface,
+                                                               deviceVk,
+                                                               cmdBuffer,
+                                                               allocator);
+
+               resultPtr = decltype(resultPtr)(tlPtr.release() );
+               return resultPtr;
+       }
+
+       deUint32 getNPrimitives() const final
+       {
+               return m_gridSizeXYZ[0] * m_gridSizeXYZ[1] * m_gridSizeXYZ[2];
+       }
+
+private:
+       std::vector<tcu::Vec3> m_vertexVec;
+
+       const GeometryType      m_geometryType;
+       const tcu::Vec3         m_gridCellSizeXYZ;
+       const tcu::Vec3         m_gridInterCellDeltaXYZ;
+       const tcu::UVec3        m_gridSizeXYZ;
+       const tcu::Vec3         m_gridStartXYZ;
+};
+
+
+/* Test logic providers ==> */
+class TestBase
+{
+public:
+       virtual ~TestBase()
+       {
+               /* Stub */
+       }
+
+       virtual VkGeometryFlagBitsKHR   getBottomLevelGeometryFlags     ()                                                                              const = 0;
+       virtual tcu::UVec3                              getDispatchSize                         ()                                                                              const = 0;
+       virtual deUint32                                getResultBufferSize                     ()                                                                              const = 0;
+       virtual void                                    initPrograms                            (SourceCollections& programCollection)  const = 0;
+       virtual bool                                    verifyResultBuffer                      (const void*            inBufferPtr)            const = 0;
+};
+
+class NoDuplicateAnyHitTest : public TestBase
+{
+public:
+       NoDuplicateAnyHitTest(  const deUint32& nRaysToTrace,
+                                                       const deUint32& nTotalPrimitives)
+               :m_nRaysToTrace         (nRaysToTrace),
+                m_nTotalPrimitives     (nTotalPrimitives)
+       {
+               DE_ASSERT(nRaysToTrace          != 0);
+               DE_ASSERT(nTotalPrimitives      != 0);
+       }
+
+       ~NoDuplicateAnyHitTest()
+       {
+               /* Stub */
+       }
+
+       VkGeometryFlagBitsKHR getBottomLevelGeometryFlags() const final
+       {
+               return VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR;
+       }
+
+       tcu::UVec3 getDispatchSize() const final
+       {
+               return tcu::UVec3(4, 4, m_nRaysToTrace / (4 * 4) + 1);
+       }
+
+       deUint32 getResultBufferSize() const final
+       {
+               return static_cast<deUint32>((1 + 1 + 3 * m_nTotalPrimitives) * sizeof(deUint32) * m_nRaysToTrace);
+       }
+
+       void initPrograms(SourceCollections& programCollection) const final
+       {
+               const vk::ShaderBuildOptions    buildOptions(   programCollection.usedVulkanVersion,
+                                                                                                               vk::SPIRV_VERSION_1_4,
+                                                                                                               0u,             /* flags        */
+                                                                                                               true);  /* allowSpirv14 */
+
+               const auto hitPropertiesDefinition =    "struct HitProperties\n"
+                                                                                               "{\n"
+                                                                                               "    uint nHitsRegistered;\n"
+                                                                                               "        uint nMissRegistered;\n"
+                                                                                               "    uint instancePrimitiveIDPairsUsed[3 * " + de::toString(m_nTotalPrimitives) + "];\n"
+                                                                                               "};\n";
+
+               {
+                       std::stringstream css;
+
+                       css <<
+                               "#version 460 core\n"
+                               "\n"
+                               "#extension GL_EXT_ray_tracing : require\n"
+                               "\n"
+                               "hitAttributeEXT vec3 dummyAttribute;\n"
+                               "\n"
+                               + hitPropertiesDefinition +
+                               "\n"
+                               "layout(location = 0) rayPayloadInEXT      dummy { vec4 dummyVec;};\n"
+                               "layout(set      = 0, binding = 0, std430) buffer result\n"
+                               "{\n"
+                               "    HitProperties rayToHitProps[" << de::toString(m_nRaysToTrace) << "];\n"
+                               "};\n"
+                               "\n"
+                               "void main()\n"
+                               "{\n"
+                               "    uint nRay            = gl_LaunchIDEXT.z * gl_LaunchSizeEXT.x * gl_LaunchSizeEXT.y + gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x;\n"
+                               "    uint nHitsRegistered = atomicAdd(rayToHitProps[nRay].nHitsRegistered, 1);\n"
+                               "\n"
+                               "    rayToHitProps[nRay].instancePrimitiveIDPairsUsed[3 * nHitsRegistered + 0] = 1 + gl_InstanceID;\n"
+                               "    rayToHitProps[nRay].instancePrimitiveIDPairsUsed[3 * nHitsRegistered + 1] = 1 + gl_PrimitiveID;\n"
+                               "    rayToHitProps[nRay].instancePrimitiveIDPairsUsed[3 * nHitsRegistered + 2] = 1 + gl_GeometryIndexEXT;\n"
+                               "}\n";
+
+                       programCollection.glslSources.add("ahit") << glu::AnyHitSource(css.str() ) << buildOptions;
+               }
+
+               {
+                       std::stringstream css;
+
+                       css <<
+                               "#version 460 core\n"
+                               "\n"
+                               "#extension GL_EXT_ray_tracing : require\n"
+                               "\n"
+                               "hitAttributeEXT vec3 hitAttribute;\n"
+                               "\n"
+                               "void main()\n"
+                               "{\n"
+                               "    reportIntersectionEXT(0.95f, 0);\n"
+                               "}\n";
+
+                       programCollection.glslSources.add("intersection") << glu::IntersectionSource(css.str() ) << buildOptions;
+               }
+
+               {
+                       std::stringstream css;
+
+                       css <<
+                               "#version 460 core\n"
+                               "\n"
+                               "#extension GL_EXT_ray_tracing : require\n"
+                               "\n"
+                               + hitPropertiesDefinition +
+                               "layout(location = 0) rayPayloadInEXT      vec3   dummy;\n"
+                               "layout(set      = 0, binding = 0, std430) buffer result\n"
+                               "{\n"
+                               "    HitProperties rayToHitProps[" << de::toString(m_nRaysToTrace) << "];\n"
+                               "};\n"
+                               "\n"
+                               "void main()\n"
+                               "{\n"
+                               "    uint nRay = gl_LaunchIDEXT.z * gl_LaunchSizeEXT.x * gl_LaunchSizeEXT.y + gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x;\n"
+                               "\n"
+                               "    atomicAdd(rayToHitProps[nRay].nMissRegistered, 1);\n"
+                               "}\n";
+
+                       programCollection.glslSources.add("miss") << glu::MissSource(css.str() ) << buildOptions;
+               }
+
+               {
+                       std::stringstream css;
+
+                       css <<
+                               "#version 460 core\n"
+                               "\n"
+                               "#extension GL_EXT_ray_tracing : require\n"
+                               "\n"
+                               + hitPropertiesDefinition +
+                               "layout(location = 0)              rayPayloadEXT vec3                     dummy;\n"
+                               "layout(set      = 0, binding = 1) uniform       accelerationStructureEXT topLevelAS;\n"
+                               "\n"
+                               "void main()\n"
+                               "{\n"
+                               "    uint  nInvocation = gl_LaunchIDEXT.z * gl_LaunchSizeEXT.x * gl_LaunchSizeEXT.y + gl_LaunchIDEXT.y * gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x;\n"
+                               "    uint  rayFlags    = 0;\n"
+                               "    uint  cullMask    = 0xFF;\n"
+                               "    float tmin        = 0.001;\n"
+                               "    float tmax        = 9.0;\n"
+                               "    vec3  origin      = vec3(4,                                  4,                                  4);\n"
+                               "    vec3  target      = vec3(float(gl_LaunchIDEXT.x * 2) + 1.0f, float(gl_LaunchIDEXT.y * 2) + 1.0f, float(gl_LaunchIDEXT.z * 2) + 1.0f);\n"
+                               "    vec3  direct      = normalize(target - origin);\n"
+                               "\n"
+                               "    if (nInvocation >= " << m_nRaysToTrace << ")\n"
+                               "    {\n"
+                               "        return;\n"
+                               "    }\n"
+                               "\n"
+                               "    traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
+                               "}\n";
+
+                       programCollection.glslSources.add("rgen") << glu::RaygenSource(css.str() ) << buildOptions;
+               }
+       }
+
+       bool verifyResultBuffer (const void* resultDataPtr) const final
+       {
+               bool result = true;
+
+               for (deUint32 nRay = 0; nRay < m_nRaysToTrace; ++nRay)
+               {
+                       std::vector<std::tuple<deUint32, deUint32, deUint32> >  tupleVec;
+                       const auto                                                                                              rayProps        = reinterpret_cast<const deUint32*>(resultDataPtr) + (2 + 3 * m_nTotalPrimitives) * nRay;
+
+                       // 1. At least one ahit invocation must have been made.
+                       if (rayProps[0] == 0)
+                       {
+                               result = false;
+
+                               goto end;
+                       }
+
+                       // 2. It's OK for each ray to intersect many AABBs, but no AABB should have had >1 ahit invocation fired.
+                       for (deUint32 nPrimitive = 0; nPrimitive < m_nTotalPrimitives; nPrimitive++)
+                       {
+                               const auto instanceID    = rayProps[2 + 3 * nPrimitive + 0];
+                               const auto primitiveID   = rayProps[2 + 3 * nPrimitive + 1];
+                               const auto geometryIndex = rayProps[2 + 3 * nPrimitive + 2];
+
+                               const auto currentTuple = std::tuple<deUint32, deUint32, deUint32>(instanceID, primitiveID, geometryIndex);
+
+                               if (instanceID          != 0 ||
+                                       primitiveID             != 0 ||
+                                       geometryIndex   != 0)
+                               {
+                                       if (std::find(  tupleVec.begin(),
+                                                                       tupleVec.end  (),
+                                                                       currentTuple) != tupleVec.end() )
+                                       {
+                                               result = false;
+
+                                               goto end;
+                                       }
+
+                                       tupleVec.push_back(currentTuple);
+                               }
+                       }
+
+                       // 3. None of the traced rays should have triggered the miss shader invocation.
+                       if (rayProps[1] != 0)
+                       {
+                               result = false;
+
+                               goto end;
+                       }
+               }
+
+               end:
+                       return result;
+       }
+
+private:
+       const deUint32 m_nRaysToTrace;
+       const deUint32 m_nTotalPrimitives;
+};
+
+
+/* Generic misc test instance */
+class RayTracingMiscTestInstance : public TestInstance
+{
+public:
+        RayTracingMiscTestInstance (   Context&                                context,
+                                                                       const CaseDef&                  data,
+                                                                       const ASProviderBase*   asProviderPtr,
+                                                                       const TestBase*                 testPtr);
+       ~RayTracingMiscTestInstance (   void);
+
+       bool                    init    (void);
+       tcu::TestStatus iterate (void);
+
+protected:
+       void                                                    checkSupport(void) const;
+       de::MovePtr<BufferWithMemory>   runTest         (void);
+
+private:
+       CaseDef m_data;
+
+       const ASProviderBase*                           m_asProviderPtr;
+       de::MovePtr<RayTracingProperties>       m_rayTracingPropsPtr;
+       const TestBase*                                         m_testPtr;
+};
+
+RayTracingMiscTestInstance::RayTracingMiscTestInstance (Context&                                       context,
+                                                                                                               const CaseDef&                          data,
+                                                                                                               const ASProviderBase*           asProviderPtr,
+                                                                                                               const TestBase*                         testPtr)
+       : vkt::TestInstance     (context)
+       , m_data                        (data)
+       , m_asProviderPtr       (asProviderPtr)
+       , m_testPtr                     (testPtr)
+{
+       DE_ASSERT(m_asProviderPtr != nullptr);
+}
+
+RayTracingMiscTestInstance::~RayTracingMiscTestInstance(void)
+{
+       /* Stub */
+}
+
+bool RayTracingMiscTestInstance::init()
+{
+       const auto& instanceInterface = m_context.getInstanceInterface();
+       const auto& physicalDeviceVk  = m_context.getPhysicalDevice   ();
+
+       m_rayTracingPropsPtr = makeRayTracingProperties(instanceInterface,
+                                                                                                       physicalDeviceVk);
+
+       return true;
+}
+
+de::MovePtr<BufferWithMemory> RayTracingMiscTestInstance::runTest(void)
+{
+       const DeviceInterface&          deviceInterface         = m_context.getDeviceInterface  ();
+       const VkDevice                          deviceVk                        = m_context.getDevice                   ();
+
+       const deUint32                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
+       const VkQueue                   queueVk                         = m_context.getUniversalQueue                   ();
+       Allocator&                              allocator                       = m_context.getDefaultAllocator                 ();
+
+       de::MovePtr<BufferWithMemory>                                   resultBufferPtr;
+       const auto                                                                              resultBufferSize        = m_testPtr->getResultBufferSize();
+       std::unique_ptr<TopLevelAccelerationStructure>  tlPtr;
+
+       const Move<VkDescriptorSetLayout>       descriptorSetLayoutPtr  = DescriptorSetLayoutBuilder()
+                                                                                                                                       .addSingleBinding(      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+                                                                                                                                                                               ALL_RAY_TRACING_STAGES)
+                                                                                                                                       .addSingleBinding(      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
+                                                                                                                                                                               ALL_RAY_TRACING_STAGES)
+                                                                                                                                       .build                  (       deviceInterface,
+                                                                                                                                                                               deviceVk);
+
+       const Move<VkDescriptorPool>            descriptorPoolPtr               = DescriptorPoolBuilder()
+                                                                                                                                       .addType(       VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
+                                                                                                                                       .addType(       VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
+                                                                                                                                       .build  (       deviceInterface,
+                                                                                                                                                               deviceVk,
+                                                                                                                                                               VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
+                                                                                                                                                               1u); /* maxSets */
+
+       const Move<VkDescriptorSet>                     descriptorSetPtr                = makeDescriptorSet(deviceInterface,
+                                                                                                                                                                       deviceVk,
+                                                                                                                                                                       *descriptorPoolPtr,
+                                                                                                                                                                       *descriptorSetLayoutPtr);
+
+       const Move<VkPipelineLayout>            pipelineLayoutPtr               = makePipelineLayout(   deviceInterface,
+                                                                                                                                                                               deviceVk,
+                                                                                                                                                                               descriptorSetLayoutPtr.get() );
+
+       const Move<VkCommandPool>                       cmdPoolPtr                              = createCommandPool(deviceInterface,
+                                                                                                                                                                       deviceVk,
+                                                                                                                                                                       0, /* pCreateInfo */
+                                                                                                                                                                       queueFamilyIndex);
+
+       const Move<VkCommandBuffer>                     cmdBufferPtr                    = allocateCommandBuffer(deviceInterface,
+                                                                                                                                                                               deviceVk,
+                                                                                                                                                                               *cmdPoolPtr,
+                                                                                                                                                                               VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+
+       Move<VkPipeline>                                        pipelineVkPtr;
+       de::MovePtr<RayTracingPipeline>         rayTracingPipelinePtr   = de::newMovePtr<RayTracingPipeline>();
+
+       {
+               auto& collection = m_context.getBinaryCollection();
+
+               Move<VkShaderModule>    raygenShader            = createShaderModule(   deviceInterface,
+                                                                                                                                                       deviceVk,
+                                                                                                                                                       collection.get("rgen"),
+                                                                                                                                                       0); /* flags */
+               Move<VkShaderModule>    hitShader                       = createShaderModule(   deviceInterface,
+                                                                                                                                                       deviceVk,
+                                                                                                                                                       collection.get("ahit"),
+                                                                                                                                                       0); /* flags */
+               Move<VkShaderModule>    intersectionShader      = createShaderModule(   deviceInterface,
+                                                                                                                                                       deviceVk,
+                                                                                                                                                       collection.get("intersection"),
+                                                                                                                                                       0); /* flags */
+               Move<VkShaderModule>    missShader                      = createShaderModule(   deviceInterface,
+                                                                                                                                                       deviceVk,
+                                                                                                                                                       collection.get("miss"),
+                                                                                                                                                       0); /* flags */
+
+               rayTracingPipelinePtr->addShader(       VK_SHADER_STAGE_RAYGEN_BIT_KHR,
+                                                                                       raygenShader,
+                                                                                       static_cast<deUint32>(ShaderGroups::RAYGEN_GROUP) );
+               rayTracingPipelinePtr->addShader(       VK_SHADER_STAGE_ANY_HIT_BIT_KHR,
+                                                                                       hitShader,
+                                                                                       static_cast<deUint32>(ShaderGroups::HIT_GROUP) );
+               rayTracingPipelinePtr->addShader(       VK_SHADER_STAGE_MISS_BIT_KHR,
+                                                                                       missShader,
+                                                                                       static_cast<deUint32>(ShaderGroups::MISS_GROUP) );
+
+               if (m_data.geometryType == GeometryType::AABB)
+               {
+                       rayTracingPipelinePtr->addShader(       VK_SHADER_STAGE_INTERSECTION_BIT_KHR,
+                                                                                               intersectionShader,
+                                                                                               static_cast<deUint32>(ShaderGroups::HIT_GROUP) );
+               }
+
+               pipelineVkPtr = rayTracingPipelinePtr->createPipeline(  deviceInterface,
+                                                                                                                               deviceVk,
+                                                                                                                               *pipelineLayoutPtr);
+       }
+
+       const auto raygenShaderBindingTablePtr  = rayTracingPipelinePtr->createShaderBindingTable(      deviceInterface,
+                                                                                                                                                                                               deviceVk,
+                                                                                                                                                                                               *pipelineVkPtr,
+                                                                                                                                                                                               allocator,
+                                                                                                                                                                                               m_rayTracingPropsPtr->getShaderGroupHandleSize          (),
+                                                                                                                                                                                               m_rayTracingPropsPtr->getShaderGroupBaseAlignment       (),
+                                                                                                                                                                                               static_cast<deUint32>                                                           (ShaderGroups::RAYGEN_GROUP),
+                                                                                                                                                                                               1u); /* groupCount */
+       const auto      missShaderBindingTablePtr       = rayTracingPipelinePtr->createShaderBindingTable(      deviceInterface,
+                                                                                                                                                                                               deviceVk,
+                                                                                                                                                                                               *pipelineVkPtr,
+                                                                                                                                                                                               allocator,
+                                                                                                                                                                                               m_rayTracingPropsPtr->getShaderGroupHandleSize          (),
+                                                                                                                                                                                               m_rayTracingPropsPtr->getShaderGroupBaseAlignment       (),
+                                                                                                                                                                                               static_cast<deUint32>                                                           (ShaderGroups::MISS_GROUP),
+                                                                                                                                                                                               1u); /* groupCount */
+       const auto      hitShaderBindingTablePtr        = rayTracingPipelinePtr->createShaderBindingTable(      deviceInterface,
+                                                                                                                                                                                               deviceVk,
+                                                                                                                                                                                               *pipelineVkPtr,
+                                                                                                                                                                                               allocator,
+                                                                                                                                                                                               m_rayTracingPropsPtr->getShaderGroupHandleSize          (),
+                                                                                                                                                                                               m_rayTracingPropsPtr->getShaderGroupBaseAlignment       (),
+                                                                                                                                                                                               static_cast<deUint32>                                                           (ShaderGroups::HIT_GROUP),
+                                                                                                                                                                                               1u); /* groupCount */
+
+       {
+               const auto resultBufferCreateInfo       = makeBufferCreateInfo( resultBufferSize,
+                                                                                                                                       VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
+
+               resultBufferPtr = de::MovePtr<BufferWithMemory>(
+                       new BufferWithMemory(   deviceInterface,
+                                                                       deviceVk,
+                                                                       allocator,
+                                                                       resultBufferCreateInfo,
+                                                                       MemoryRequirement::HostVisible));
+       }
+
+       beginCommandBuffer(     deviceInterface,
+                                               *cmdBufferPtr,
+                                               0u /* flags */);
+       {
+               tlPtr = m_asProviderPtr->createTLAS(m_context,
+                                                                                       m_data.asLayout,
+                                                                                       *cmdBufferPtr,
+                                                                                       m_testPtr->getBottomLevelGeometryFlags() );
+
+               deviceInterface.cmdFillBuffer(  *cmdBufferPtr,
+                                                                               **resultBufferPtr,
+                                                                               0,                                      /* dstOffset */
+                                                                               VK_WHOLE_SIZE,
+                                                                               0);                                     /* data */
+
+               {
+                       const auto postFillBarrier = makeBufferMemoryBarrier(   VK_ACCESS_TRANSFER_WRITE_BIT,   /* srcAccessMask */
+                                                                                                                                       VK_ACCESS_SHADER_WRITE_BIT,             /* dstAccessMask */
+                                                                                                                                       **resultBufferPtr,
+                                                                                                                                       0, /* offset */
+                                                                                                                                       VK_WHOLE_SIZE);
+
+                       cmdPipelineBufferMemoryBarrier( deviceInterface,
+                                                                                       *cmdBufferPtr,
+                                                                                       VK_PIPELINE_STAGE_TRANSFER_BIT,                                 /* srcStageMask */
+                                                                                       VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,   /* dstStageMask */
+                                                                                       &postFillBarrier);
+               }
+
+               {
+                       VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
+                       {
+                               VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,      //  VkStructureType                                             sType;
+                               DE_NULL,                                                                                                                        //  const void*                                                 pNext;
+                               1u,                                                                                                                                     //  deUint32                                                    accelerationStructureCount;
+                               tlPtr->getPtr(),                                                                                                        //  const VkAccelerationStructureKHR*   pAccelerationStructures;
+                       };
+
+                       const auto descriptorResultBufferInfo = makeDescriptorBufferInfo(       **resultBufferPtr,
+                                                                                                                                                               0, /* offset */
+                                                                                                                                                               resultBufferSize);
+
+                       DescriptorSetUpdateBuilder()
+                               .writeSingle(   *descriptorSetPtr,
+                                                               DescriptorSetUpdateBuilder::Location::binding(0u),
+                                                               VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
+                                                               &descriptorResultBufferInfo)
+                               .writeSingle(   *descriptorSetPtr,
+                                                               DescriptorSetUpdateBuilder::Location::binding(1u),
+                                                               VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,
+                                                               &accelerationStructureWriteDescriptorSet)
+                               .update         (       deviceInterface,
+                                                               deviceVk);
+               }
+
+               deviceInterface.cmdBindDescriptorSets(  *cmdBufferPtr,
+                                                                                               VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR,
+                                                                                               *pipelineLayoutPtr,
+                                                                                               0, /* firstSet           */
+                                                                                               1, /* descriptorSetCount */
+                                                                                               &descriptorSetPtr.get(),
+                                                                                               0,        /* dynamicOffsetCount */
+                                                                                               DE_NULL); /* pDynamicOffsets    */
+
+               deviceInterface.cmdBindPipeline(*cmdBufferPtr,
+                                                                               VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR,
+                                                                               *pipelineVkPtr);
+
+               {
+                       const auto preTraceMemoryBarrier        = makeMemoryBarrier(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,     /* srcAccessMask */
+                                                                                                                                       VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR); /* dstAccessMask */
+
+                       cmdPipelineMemoryBarrier(       deviceInterface,
+                                                                               *cmdBufferPtr,
+                                                                               VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, /* srcStageMask */
+                                                                               VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,                   /* dstStageMask */
+                                                                               &preTraceMemoryBarrier);
+               }
+
+               {
+                       const auto      raygenShaderBindingTableRegion          = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(     deviceInterface,
+                                                                                                                                                                                                                                               deviceVk,
+                                                                                                                                                                                                                                               raygenShaderBindingTablePtr->get(),
+                                                                                                                                                                                                                                               0 /* offset */),
+                                                                                                                                                                                               0, /* stride */
+                                                                                                                                                                                               m_rayTracingPropsPtr->getShaderGroupHandleSize() );
+                       const auto      missShaderBindingTableRegion            = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(     deviceInterface,
+                                                                                                                                                                                                                                               deviceVk,
+                                                                                                                                                                                                                                               missShaderBindingTablePtr->get(),
+                                                                                                                                                                                                                                               0 /* offset */),
+                                                                                                                                                                                               0, /* stride */
+                                                                                                                                                                                               m_rayTracingPropsPtr->getShaderGroupHandleSize() );
+                       const auto      hitShaderBindingTableRegion                     = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(     deviceInterface,
+                                                                                                                                                                                                                                               deviceVk,
+                                                                                                                                                                                                                                               hitShaderBindingTablePtr->get(),
+                                                                                                                                                                                                                                               0 /* offset */),
+                                                                                                                                                                                               0, /* stride */
+                                                                                                                                                                                               m_rayTracingPropsPtr->getShaderGroupHandleSize() );
+                       const auto      callableShaderBindingTableRegion        = makeStridedDeviceAddressRegionKHR(DE_NULL,
+                                                                                                                                                                                               0, /* stride */
+                                                                                                                                                                                               0  /* size   */);
+
+                       cmdTraceRays(   deviceInterface,
+                                                       *cmdBufferPtr,
+                                                       &raygenShaderBindingTableRegion,
+                                                       &missShaderBindingTableRegion,
+                                                       &hitShaderBindingTableRegion,
+                                                       &callableShaderBindingTableRegion,
+                                                       m_testPtr->getDispatchSize()[0],
+                                                       m_testPtr->getDispatchSize()[1],
+                                                       m_testPtr->getDispatchSize()[2]);
+               }
+
+               {
+                       const auto postTraceMemoryBarrier       = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, /* srcAccessMask */
+                                                                                                                                       VK_ACCESS_HOST_READ_BIT);       /* dstAccessMask */
+
+                       cmdPipelineMemoryBarrier(       deviceInterface,
+                                                                               *cmdBufferPtr,
+                                                                               VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,   /* srcStageMask */
+                                                                               VK_PIPELINE_STAGE_HOST_BIT,                                             /* dstStageMask */
+                                                                               &postTraceMemoryBarrier);
+               }
+       }
+       endCommandBuffer(deviceInterface,
+                                       *cmdBufferPtr);
+
+       submitCommandsAndWait(  deviceInterface,
+                                                       deviceVk,
+                                                       queueVk,
+                                                       cmdBufferPtr.get() );
+
+       invalidateMappedMemoryRange(deviceInterface,
+                                                               deviceVk,
+                                                               resultBufferPtr->getAllocation().getMemory(),
+                                                               resultBufferPtr->getAllocation().getOffset(),
+                                                               resultBufferSize);
+
+       return resultBufferPtr;
+}
+
+tcu::TestStatus RayTracingMiscTestInstance::iterate (void)
+{
+       const de::MovePtr<BufferWithMemory>     bufferGPUPtr            = runTest();
+       const deUint32*                                         bufferGPUDataPtr        = (deUint32*) bufferGPUPtr->getAllocation().getHostPtr();
+       const bool                                                      result                          = m_testPtr->verifyResultBuffer(bufferGPUDataPtr);
+
+       if (result)
+               return tcu::TestStatus::pass("Pass");
+       else
+               return tcu::TestStatus::fail("Fail");
+}
+
+}      // anonymous
+
+
+class RayTracingTestCase : public TestCase
+{
+       public:
+                                                        RayTracingTestCase     (       tcu::TestContext&       context,
+                                                                                                       const char*                     name,
+                                                                                                       const char*                     desc,
+                                                                                                       const CaseDef           data);
+                                                       ~RayTracingTestCase     (       void);
+
+       virtual void                    checkSupport            (Context&                       context)                        const final;
+       virtual TestInstance*   createInstance          (Context&                       context)                        const final;
+       void                                    initPrograms            (SourceCollections& programCollection)  const final;
+
+private:
+       mutable std::unique_ptr<ASProviderBase> m_asProviderPtr;
+       CaseDef                                                                 m_data;
+       mutable std::unique_ptr<TestBase>               m_testPtr;
+};
+
+RayTracingTestCase::RayTracingTestCase (tcu::TestContext&      context,
+                                                                               const char*                     name,
+                                                                               const char*                     desc,
+                                                                               const CaseDef           data)
+       : vkt::TestCase (       context,
+                                               name,
+                                               desc)
+       , m_data                (       data)
+{
+       switch (m_data.type)
+       {
+               case TestType::NO_DUPLICATE_ANY_HIT:
+               {
+                       m_asProviderPtr.reset(
+                               new GridASProvider(     tcu::Vec3       (0,             0,              0),             /* gridStartXYZ          */
+                                                                       tcu::Vec3       (1,             1,              1),             /* gridCellSizeXYZ       */
+                                                                       tcu::UVec3      (4,             4,              4),             /* gridSizeXYZ           */
+                                                                       tcu::Vec3       (2.0f,  2.0f,   2.0f),  /* gridInterCellDeltaXYZ */
+                                                                       data.geometryType)
+                       );
+
+                       break;
+               }
+
+               default:
+               {
+                       deAssertFail(   "This location should never be reached",
+                                                       __FILE__,
+                                                       __LINE__);
+               }
+       }
+}
+
+RayTracingTestCase::~RayTracingTestCase        (void)
+{
+}
+
+void RayTracingTestCase::checkSupport(Context& context) const
+{
+       context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
+       context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
+
+       const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR        = context.getAccelerationStructureFeatures      ();
+       const VkPhysicalDeviceRayTracingPipelineFeaturesKHR&    rayTracingPipelineFeaturesKHR           = context.getRayTracingPipelineFeatures         ();
+
+       if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE)
+       {
+               TCU_THROW(NotSupportedError, "VkPhysicalDeviceRayTracingPipelineFeaturesKHR::rayTracingPipeline is false");
+       }
+
+       if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
+       {
+               TCU_THROW(NotSupportedError, "VkPhysicalDeviceAccelerationStructureFeaturesKHR::accelerationStructure is false");
+       }
+}
+
+void RayTracingTestCase::initPrograms(SourceCollections& programCollection)    const
+{
+       switch (m_data.type)
+       {
+               case TestType::NO_DUPLICATE_ANY_HIT:
+               {
+                       DE_ASSERT(m_asProviderPtr != nullptr);
+
+                       m_testPtr.reset(
+                               new NoDuplicateAnyHitTest(      m_data.nRaysToTrace,
+                                                                                       m_asProviderPtr->getNPrimitives() )
+                       );
+
+                       m_testPtr->initPrograms(programCollection);
+
+                       break;
+               }
+
+               default:
+               {
+                       deAssertFail(   "This location should never be reached",
+                                                       __FILE__,
+                                                       __LINE__);
+               }
+       }
+}
+
+TestInstance* RayTracingTestCase::createInstance (Context& context) const
+{
+       switch (m_data.type)
+       {
+               case TestType::NO_DUPLICATE_ANY_HIT:
+               {
+                       if (m_testPtr == nullptr)
+                       {
+                               m_testPtr.reset(
+                                       new NoDuplicateAnyHitTest(      m_data.nRaysToTrace,
+                                                                                               m_asProviderPtr->getNPrimitives() )
+                               );
+                       }
+
+                       break;
+               }
+
+               default:
+               {
+                       deAssertFail(   "This location should never be reached",
+                                                       __FILE__,
+                                                       __LINE__);
+               }
+       }
+
+       auto newTestInstancePtr = new RayTracingMiscTestInstance(       context,
+                                                                                                                               m_data,
+                                                                                                                               m_asProviderPtr.get     (),
+                                                                                                                               m_testPtr.get           () );
+
+       newTestInstancePtr->init();
+
+       return newTestInstancePtr;
+}
+
+
+tcu::TestCaseGroup*    createMiscTests (tcu::TestContext& testCtx)
+{
+       de::MovePtr<tcu::TestCaseGroup> miscGroupPtr(
+               new tcu::TestCaseGroup(
+                       testCtx,
+                       "misc",
+                       "Miscellaneous ray-tracing tests"));
+
+       for (auto currentGeometryType = GeometryType::FIRST; currentGeometryType != GeometryType::COUNT; currentGeometryType = static_cast<GeometryType>(static_cast<deUint32>(currentGeometryType) + 1) )
+       {
+               for (auto currentASLayout = AccelerationStructureLayout::FIRST; currentASLayout != AccelerationStructureLayout::COUNT; currentASLayout = static_cast<AccelerationStructureLayout>(static_cast<deUint32>(currentASLayout) + 1) )
+               {
+                       const std::string newTestCaseName = "NO_DUPLICATE_ANY_HIT_" + de::toString(getSuffixForASLayout(currentASLayout) ) + "_" + de::toString(getSuffixForGeometryType(currentGeometryType) );
+
+                       auto newTestCasePtr = new RayTracingTestCase(   testCtx,
+                                                                                                                       newTestCaseName.data(),
+                                                                                                                       "Verifies the NO_DUPLICATE_ANY_HIT flag is adhered to when tracing rays",
+                                                                                                                       CaseDef{TestType::NO_DUPLICATE_ANY_HIT, GeometryType::AABB, currentASLayout, 32});
+
+                       miscGroupPtr->addChild(newTestCasePtr);
+               }
+       }
+
+       return miscGroupPtr.release();
+}
+
+}      // RayTracing
+}      // vkt
diff --git a/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingMiscTests.hpp b/external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingMiscTests.hpp
new file mode 100644 (file)
index 0000000..8a23243
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _VKTRAYTRACINGMISCTESTS_HPP
+#define _VKTRAYTRACINGMISCTESTS_HPP
+/*-------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2020 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Ray Tracing Watertightness tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace RayTracing
+{
+
+tcu::TestCaseGroup*    createMiscTests(tcu::TestContext& testCtx);
+
+} // RayTracing
+} // vkt
+
+#endif // _VKTRAYTRACINGMISCTESTS_HPP
index ce558e6..0d735c0 100644 (file)
@@ -36,6 +36,7 @@
 #include "vktRayTracingMemGuaranteeTests.hpp"
 #include "vktRayTracingNullASTests.hpp"
 #include "vktRayTracingCaptureReplayTests.hpp"
+#include "vktRayTracingMiscTests.hpp"
 
 #include "deUniquePtr.hpp"
 
@@ -64,6 +65,7 @@ tcu::TestCaseGroup*   createTests (tcu::TestContext& testCtx)
        group->addChild(createMemGuaranteeTests(testCtx));
        group->addChild(createNullAccelerationStructureTests(testCtx));
        group->addChild(createCaptureReplayTests(testCtx));
+       group->addChild(createMiscTests(testCtx));
 
        return group.release();
 }
index cac9c07..4a204e2 100644 (file)
@@ -704518,6 +704518,14 @@ dEQP-VK.ray_tracing_pipeline.capture_replay.acceleration_structures.serializatio
 dEQP-VK.ray_tracing_pipeline.capture_replay.acceleration_structures.serialization.gpu_built.top_acceleration_structure.aabbs
 dEQP-VK.ray_tracing_pipeline.capture_replay.acceleration_structures.serialization.gpu_built.bottom_acceleration_structure.triangles
 dEQP-VK.ray_tracing_pipeline.capture_replay.acceleration_structures.serialization.gpu_built.bottom_acceleration_structure.aabbs
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TL1BL1G_AABB
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TL1BLnG_AABB
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TLnBL1G_AABB
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TLnBLnG_AABB
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TL1BL1G_tri
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TL1BLnG_tri
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TLnBL1G_tri
+dEQP-VK.ray_tracing_pipeline.misc.NO_DUPLICATE_ANY_HIT_1TLnBLnG_tri
 dEQP-VK.ray_query.builtin.flow.vert.triangles
 dEQP-VK.ray_query.builtin.flow.vert.aabbs
 dEQP-VK.ray_query.builtin.flow.tesc.triangles