Watertightness tests for VK_KHR_ray_query
authorBoris Zanin <boris.zanin@mobica.com>
Wed, 27 May 2020 12:54:20 +0000 (14:54 +0200)
committerPiers Daniell <pdaniell@nvidia.com>
Fri, 26 Jun 2020 20:28:53 +0000 (14:28 -0600)
Performs watertightness tests for VK_KHR_ray_query.

Add tests:
 * dEQP-VK.ray_query.watertightness.*

Components: Vulkan

VK-GL-CTS issue: 2380

Change-Id: I48ff5360d3fa348057175e6811f4281fb80f73b7

AndroidGen.mk
android/cts/master/vk-master-2020-03-01.txt
android/cts/master/vk-master.txt
external/vulkancts/framework/vulkan/vkRayTracingUtil.cpp
external/vulkancts/modules/vulkan/ray_query/CMakeLists.txt
external/vulkancts/modules/vulkan/ray_query/vktRayQueryTests.cpp
external/vulkancts/modules/vulkan/ray_query/vktRayQueryWatertightnessTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/ray_query/vktRayQueryWatertightnessTests.hpp [new file with mode: 0644]
external/vulkancts/mustpass/master/vk-default.txt

index 16dc260..a8716af 100644 (file)
@@ -267,6 +267,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/ray_query/vktRayQueryBuiltinTests.cpp \
        external/vulkancts/modules/vulkan/ray_query/vktRayQueryTests.cpp \
        external/vulkancts/modules/vulkan/ray_query/vktRayQueryTraversalControlTests.cpp \
+       external/vulkancts/modules/vulkan/ray_query/vktRayQueryWatertightnessTests.cpp \
        external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingAccelerationStructuresTests.cpp \
        external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingBuildIndirectTests.cpp \
        external/vulkancts/modules/vulkan/ray_tracing/vktRayTracingBuildLargeTests.cpp \
index c74d419..542a96e 100644 (file)
@@ -243725,3 +243725,39 @@ dEQP-VK.ray_query.advanced.null_as.sect.triangles
 dEQP-VK.ray_query.advanced.null_as.sect.aabbs
 dEQP-VK.ray_query.advanced.null_as.call.triangles
 dEQP-VK.ray_query.advanced.null_as.call.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.vert.triangles
+dEQP-VK.ray_query.watertightness.nomiss.vert.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.tesc.triangles
+dEQP-VK.ray_query.watertightness.nomiss.tesc.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.tese.triangles
+dEQP-VK.ray_query.watertightness.nomiss.tese.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.geom.triangles
+dEQP-VK.ray_query.watertightness.nomiss.geom.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.frag.triangles
+dEQP-VK.ray_query.watertightness.nomiss.frag.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.comp.triangles
+dEQP-VK.ray_query.watertightness.nomiss.comp.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.rgen.triangles
+dEQP-VK.ray_query.watertightness.nomiss.rgen.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.ahit.triangles
+dEQP-VK.ray_query.watertightness.nomiss.ahit.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.chit.triangles
+dEQP-VK.ray_query.watertightness.nomiss.chit.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.miss.triangles
+dEQP-VK.ray_query.watertightness.nomiss.miss.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.sect.triangles
+dEQP-VK.ray_query.watertightness.nomiss.sect.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.call.triangles
+dEQP-VK.ray_query.watertightness.nomiss.call.aabbs
+dEQP-VK.ray_query.watertightness.singlehit.vert.triangles
+dEQP-VK.ray_query.watertightness.singlehit.tesc.triangles
+dEQP-VK.ray_query.watertightness.singlehit.tese.triangles
+dEQP-VK.ray_query.watertightness.singlehit.geom.triangles
+dEQP-VK.ray_query.watertightness.singlehit.frag.triangles
+dEQP-VK.ray_query.watertightness.singlehit.comp.triangles
+dEQP-VK.ray_query.watertightness.singlehit.rgen.triangles
+dEQP-VK.ray_query.watertightness.singlehit.ahit.triangles
+dEQP-VK.ray_query.watertightness.singlehit.chit.triangles
+dEQP-VK.ray_query.watertightness.singlehit.miss.triangles
+dEQP-VK.ray_query.watertightness.singlehit.sect.triangles
+dEQP-VK.ray_query.watertightness.singlehit.call.triangles
index 6e0bf45..6b2e62c 100644 (file)
@@ -639881,3 +639881,39 @@ dEQP-VK.ray_query.advanced.null_as.sect.triangles
 dEQP-VK.ray_query.advanced.null_as.sect.aabbs
 dEQP-VK.ray_query.advanced.null_as.call.triangles
 dEQP-VK.ray_query.advanced.null_as.call.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.vert.triangles
+dEQP-VK.ray_query.watertightness.nomiss.vert.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.tesc.triangles
+dEQP-VK.ray_query.watertightness.nomiss.tesc.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.tese.triangles
+dEQP-VK.ray_query.watertightness.nomiss.tese.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.geom.triangles
+dEQP-VK.ray_query.watertightness.nomiss.geom.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.frag.triangles
+dEQP-VK.ray_query.watertightness.nomiss.frag.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.comp.triangles
+dEQP-VK.ray_query.watertightness.nomiss.comp.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.rgen.triangles
+dEQP-VK.ray_query.watertightness.nomiss.rgen.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.ahit.triangles
+dEQP-VK.ray_query.watertightness.nomiss.ahit.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.chit.triangles
+dEQP-VK.ray_query.watertightness.nomiss.chit.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.miss.triangles
+dEQP-VK.ray_query.watertightness.nomiss.miss.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.sect.triangles
+dEQP-VK.ray_query.watertightness.nomiss.sect.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.call.triangles
+dEQP-VK.ray_query.watertightness.nomiss.call.aabbs
+dEQP-VK.ray_query.watertightness.singlehit.vert.triangles
+dEQP-VK.ray_query.watertightness.singlehit.tesc.triangles
+dEQP-VK.ray_query.watertightness.singlehit.tese.triangles
+dEQP-VK.ray_query.watertightness.singlehit.geom.triangles
+dEQP-VK.ray_query.watertightness.singlehit.frag.triangles
+dEQP-VK.ray_query.watertightness.singlehit.comp.triangles
+dEQP-VK.ray_query.watertightness.singlehit.rgen.triangles
+dEQP-VK.ray_query.watertightness.singlehit.ahit.triangles
+dEQP-VK.ray_query.watertightness.singlehit.chit.triangles
+dEQP-VK.ray_query.watertightness.singlehit.miss.triangles
+dEQP-VK.ray_query.watertightness.singlehit.sect.triangles
+dEQP-VK.ray_query.watertightness.singlehit.call.triangles
index 471ca65..89e2abf 100644 (file)
@@ -142,7 +142,9 @@ VkDeviceAddress getBufferDeviceAddress ( const DeviceInterface&     vk,
                                                                                 const VkBuffer                 buffer,
                                                                                 VkDeviceSize                   offset )
 {
-       DE_ASSERT(buffer != DE_NULL);
+
+       if (buffer == DE_NULL)
+               return 0;
 
        VkBufferDeviceAddressInfo deviceAddressInfo
        {
index a0ebfc3..f6cbf0f 100644 (file)
@@ -9,6 +9,8 @@ set(DEQP_VK_RAY_QUERY_SRCS
        vktRayQueryTraversalControlTests.hpp
        vktRayQueryAccelerationStructuresTests.cpp
        vktRayQueryAccelerationStructuresTests.hpp
+       vktRayQueryWatertightnessTests.cpp
+       vktRayQueryWatertightnessTests.hpp
        )
 
 set(DEQP_VK_RAY_QUERY_LIBS
index 75ccc8a..1bf98d6 100644 (file)
  *//*--------------------------------------------------------------------*/
 
 #include "vktRayQueryTests.hpp"
-
 #include "vktRayQueryBuiltinTests.hpp"
 #include "vktRayQueryTraversalControlTests.hpp"
 #include "vktRayQueryAccelerationStructuresTests.hpp"
+#include "vktRayQueryWatertightnessTests.hpp"
 
 #include "deUniquePtr.hpp"
 
@@ -44,6 +44,7 @@ tcu::TestCaseGroup*   createTests (tcu::TestContext& testCtx)
        group->addChild(createTraversalControlTests(testCtx));
        group->addChild(createAccelerationStructuresTests(testCtx));
        group->addChild(createAdvancedTests(testCtx));
+       group->addChild(createWatertightnessTests(testCtx));
 
        return group.release();
 }
diff --git a/external/vulkancts/modules/vulkan/ray_query/vktRayQueryWatertightnessTests.cpp b/external/vulkancts/modules/vulkan/ray_query/vktRayQueryWatertightnessTests.cpp
new file mode 100644 (file)
index 0000000..027213b
--- /dev/null
@@ -0,0 +1,2349 @@
+/*------------------------------------------------------------------------
+ * 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 Query Builtin tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktRayQueryWatertightnessTests.hpp"
+
+#include "vkDefs.hpp"
+
+#include "vktTestCase.hpp"
+#include "vktTestGroupUtil.hpp"
+#include "vkCmdUtil.hpp"
+#include "vkObjUtil.hpp"
+#include "vkBuilderUtil.hpp"
+#include "vkBarrierUtil.hpp"
+#include "vkBufferWithMemory.hpp"
+#include "vkImageWithMemory.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkImageUtil.hpp"
+#include "deRandom.hpp"
+#include "tcuTexture.hpp"
+#include "tcuTextureUtil.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuImageCompare.hpp"
+#include "tcuCommandLine.hpp"
+
+#include "vkRayTracingUtil.hpp"
+
+namespace vkt
+{
+namespace RayQuery
+{
+namespace
+{
+using namespace vk;
+using namespace vkt;
+
+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;
+
+enum TestType
+{
+       TEST_TYPE_NO_MISS               = 0,
+       TEST_TYPE_SINGLE_HIT,
+};
+
+enum GeomType
+{
+       GEOM_TYPE_TRIANGLES,
+       GEOM_TYPE_AABBS,
+       GEOM_TYPE_LAST,
+};
+
+const deUint32 TEST_WIDTH                                      = 256u;
+const deUint32 TEST_HEIGHT                                     = 256u;
+const float            MIN_AABB_SIDE_LENGTH            = 1e-6f;
+const float            MIN_TRIANGLE_EDGE_LENGTH        = 1.0f / float(10 * TEST_WIDTH * TEST_HEIGHT);
+const float            MIN_TRIANGLE_AREA_SIZE          = 1.0f / float(10 * TEST_WIDTH * TEST_HEIGHT);
+
+struct TestParams;
+
+typedef void (*CheckSupportFunc)(Context& context, const TestParams& testParams);
+typedef void (*InitProgramsFunc)(SourceCollections& programCollection, const TestParams& testParams);
+typedef const std::string (*ShaderBodyTextFunc)(const TestParams& testParams);
+
+class PipelineConfiguration
+{
+public:
+                                       PipelineConfiguration   ()      {};
+       virtual                 ~PipelineConfiguration  ()      {};
+
+       virtual void    initConfiguration       (Context&                                                       context,
+                                                                                TestParams&                                            testParams) = 0;
+       virtual void    fillCommandBuffer       (Context&                                                       context,
+                                                                                TestParams&                                            testParams,
+                                                                                VkCommandBuffer                                        commandBuffer,
+                                                                                const VkAccelerationStructureKHR*      rayQueryTopAccelerationStructurePtr,
+                                                                                const VkDescriptorImageInfo&           resultImageInfo) = 0;
+};
+
+class TestConfiguration
+{
+public:
+                                                                                                                                       TestConfiguration                               ()
+                                                                                                                                               : m_bottomAccelerationStructures        ()
+                                                                                                                                               , m_topAccelerationStructure            ()
+                                                                                                                                               , m_expected                                            ()
+                                                                                                                                       {
+                                                                                                                                       }
+       virtual                                                                                                                 ~TestConfiguration                              ()
+                                                                                                                                       {
+                                                                                                                                       }
+
+       virtual const VkAccelerationStructureKHR*                                               initAccelerationStructures              (Context&                                                       context,
+                                                                                                                                                                                                        TestParams&                                            testParams,
+                                                                                                                                                                                                        VkCommandBuffer                                        cmdBuffer) = 0;
+       virtual bool                                                                                                    verify                                                  (BufferWithMemory*                                      resultBuffer,
+                                                                                                                                                                                                        Context&                                                       context,
+                                                                                                                                                                                                        TestParams&                                            testParams) = 0;
+
+protected:
+       std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>    m_bottomAccelerationStructures;
+       de::SharedPtr<TopLevelAccelerationStructure>                                    m_topAccelerationStructure;
+       std::vector<deInt32>                                                                                    m_expected;
+};
+
+struct TestParams
+{
+       deUint32                                width;
+       deUint32                                height;
+       deUint32                                depth;
+       deUint32                                randomSeed;
+       TestType                                testType;
+       VkShaderStageFlagBits   stage;
+       GeomType                                geomType;
+       deUint32                                squaresGroupCount;
+       deUint32                                geometriesGroupCount;
+       deUint32                                instancesGroupCount;
+       VkFormat                                format;
+       CheckSupportFunc                pipelineCheckSupport;
+       InitProgramsFunc                pipelineInitPrograms;
+       ShaderBodyTextFunc              testConfigShaderBodyText;
+};
+
+deUint32 getShaderGroupHandleSize (const InstanceInterface&    vki,
+                                                                  const VkPhysicalDevice       physicalDevice)
+{
+       de::MovePtr<RayTracingProperties>       rayTracingPropertiesKHR;
+
+       rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
+
+       return rayTracingPropertiesKHR->getShaderGroupHandleSize();
+}
+
+deUint32 getShaderGroupBaseAlignment (const InstanceInterface& vki,
+                                                                         const VkPhysicalDevice        physicalDevice)
+{
+       de::MovePtr<RayTracingProperties>       rayTracingPropertiesKHR;
+
+       rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
+
+       return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
+}
+
+VkBuffer getVkBuffer (const de::MovePtr<BufferWithMemory>& buffer)
+{
+       VkBuffer result = (buffer.get() == DE_NULL) ? DE_NULL : buffer->get();
+
+       return result;
+}
+
+VkStridedDeviceAddressRegionKHR makeStridedDeviceAddressRegion (const DeviceInterface& vkd, const VkDevice device, VkBuffer buffer, VkDeviceSize size)
+{
+       const VkDeviceSize sizeFixed = ((buffer == DE_NULL) ? 0ull : size);
+
+       return makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, buffer, 0), 0, sizeFixed);
+}
+
+VkImageCreateInfo makeImageCreateInfo (VkFormat                                format,
+                                                                          deUint32                             width,
+                                                                          deUint32                             height,
+                                                                          deUint32                             depth,
+                                                                          VkImageType                  imageType       = VK_IMAGE_TYPE_3D,
+                                                                          VkImageUsageFlags    usageFlags      = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
+{
+       const VkImageCreateInfo imageCreateInfo =
+       {
+               VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType                      sType;
+               DE_NULL,                                                                // const void*                          pNext;
+               (VkImageCreateFlags)0u,                                 // VkImageCreateFlags           flags;
+               imageType,                                                              // VkImageType                          imageType;
+               format,                                                                 // VkFormat                                     format;
+               makeExtent3D(width, height, depth),             // VkExtent3D                           extent;
+               1u,                                                                             // deUint32                                     mipLevels;
+               1u,                                                                             // deUint32                                     arrayLayers;
+               VK_SAMPLE_COUNT_1_BIT,                                  // VkSampleCountFlagBits        samples;
+               VK_IMAGE_TILING_OPTIMAL,                                // VkImageTiling                        tiling;
+               usageFlags,                                                             // VkImageUsageFlags            usage;
+               VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                        sharingMode;
+               0u,                                                                             // deUint32                                     queueFamilyIndexCount;
+               DE_NULL,                                                                // const deUint32*                      pQueueFamilyIndices;
+               VK_IMAGE_LAYOUT_UNDEFINED                               // VkImageLayout                        initialLayout;
+       };
+
+       return imageCreateInfo;
+}
+
+Move<VkPipeline> makeComputePipeline (const DeviceInterface&           vk,
+                                                                         const VkDevice                                device,
+                                                                         const VkPipelineLayout                pipelineLayout,
+                                                                         const VkShaderModule                  shaderModule)
+{
+       const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
+               DE_NULL,                                                                                                // const void*                                                  pNext;
+               0u,                                                                                                             // VkPipelineShaderStageCreateFlags             flags;
+               VK_SHADER_STAGE_COMPUTE_BIT,                                                    // VkShaderStageFlagBits                                stage;
+               shaderModule,                                                                                   // 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;
+               0u,                                                                                                     // VkPipelineCreateFlags                        flags;
+               pipelineShaderStageParams,                                                      // VkPipelineShaderStageCreateInfo      stage;
+               pipelineLayout,                                                                         // VkPipelineLayout                                     layout;
+               DE_NULL,                                                                                        // VkPipeline                                           basePipelineHandle;
+               0,                                                                                                      // deInt32                                                      basePipelineIndex;
+       };
+
+       return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo);
+}
+
+static const std::string getMissPassthrough (void)
+{
+       const std::string missPassthrough =
+               "#version 460 core\n"
+               "#extension GL_EXT_ray_tracing : require\n"
+               "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
+               "\n"
+               "void main()\n"
+               "{\n"
+               "}\n";
+
+       return missPassthrough;
+}
+
+static const std::string getHitPassthrough (void)
+{
+       const std::string hitPassthrough =
+               "#version 460 core\n"
+               "#extension GL_EXT_ray_tracing : require\n"
+               "hitAttributeEXT vec3 attribs;\n"
+               "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
+               "\n"
+               "void main()\n"
+               "{\n"
+               "}\n";
+
+       return hitPassthrough;
+}
+
+static const std::string getGraphicsPassthrough (void)
+{
+       std::ostringstream src;
+
+       src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
+               << "\n"
+               << "void main(void)\n"
+               << "{\n"
+               << "}\n";
+
+       return src.str();
+}
+
+static const std::string getVertexPassthrough (void)
+{
+       std::ostringstream src;
+
+       src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
+               << "\n"
+               << "layout(location = 0) in vec4 in_position;\n"
+               << "\n"
+               << "void main(void)\n"
+               << "{\n"
+               << "  gl_Position = in_position;\n"
+               << "}\n";
+
+       return src.str();
+}
+
+static inline tcu::Vec2 mixVec2 (const tcu::Vec2& a, const tcu::Vec2& b, const float alpha)
+{
+       const tcu::Vec2 result = a * alpha + b * (1.0f - alpha);
+
+       return result;
+}
+
+static inline tcu::Vec2 mixCoordsVec2 (const tcu::Vec2& a, const tcu::Vec2& b, const float alpha, const float beta)
+{
+       const tcu::Vec2 result  = tcu::Vec2(deFloatMix(a.x(), b.x(), alpha), deFloatMix(a.y(), b.y(), beta));
+
+       return result;
+}
+
+inline float triangleEdgeLength (const tcu::Vec2& vertexA, const tcu::Vec2& vertexB)
+{
+       const float     abx     = vertexA.x() - vertexB.x();
+       const float     aby     = vertexA.y() - vertexB.y();
+       const float abq = abx * abx + aby * aby;
+       const float     ab      = deFloatSqrt(abq);
+
+       return ab;
+}
+
+inline float triangleArea (const float edgeALen, const float edgeBLen, const float edgeCLen)
+{
+       const float     s       = (edgeALen + edgeBLen + edgeCLen) / 2.0f;
+       const float     q       = s * (s - edgeALen) * (s - edgeBLen) * (s - edgeCLen);
+
+       if (q <= 0.0f)
+               return 0.0f;
+
+       return deFloatSqrt(q);
+}
+
+class GraphicsConfiguration : public PipelineConfiguration
+{
+public:
+       static void                                             checkSupport                    (Context&                                                       context,
+                                                                                                                        const TestParams&                                      testParams);
+       static void                                             initPrograms                    (SourceCollections&                                     programCollection,
+                                                                                                                        const TestParams&                                      testParams);
+
+                                                                       GraphicsConfiguration   ();
+       virtual                                                 ~GraphicsConfiguration  () {};
+
+       void                                                    initVertexBuffer                (Context&                                                       context,
+                                                                                                                        TestParams&                                            testParams);
+       Move<VkPipeline>                                makeGraphicsPipeline    (Context&                                                       context,
+                                                                                                                        TestParams&                                            testParams);
+       virtual void                                    initConfiguration               (Context&                                                       context,
+                                                                                                                        TestParams&                                            testParams) override;
+       virtual void                                    fillCommandBuffer               (Context&                                                       context,
+                                                                                                                        TestParams&                                            testParams,
+                                                                                                                        VkCommandBuffer                                        commandBuffer,
+                                                                                                                        const VkAccelerationStructureKHR*      rayQueryTopAccelerationStructurePtr,
+                                                                                                                        const VkDescriptorImageInfo&           resultImageInfo) override;
+
+private:
+       Move<VkDescriptorSetLayout>             m_descriptorSetLayout;
+       Move<VkDescriptorPool>                  m_descriptorPool;
+       Move<VkDescriptorSet>                   m_descriptorSet;
+
+       VkFormat                                                m_framebufferFormat;
+       Move<VkImage>                                   m_framebufferImage;
+       de::MovePtr<Allocation>                 m_framebufferImageAlloc;
+       Move<VkImageView>                               m_framebufferAttachment;
+
+       Move<VkShaderModule>                    m_vertShaderModule;
+       Move<VkShaderModule>                    m_geomShaderModule;
+       Move<VkShaderModule>                    m_tescShaderModule;
+       Move<VkShaderModule>                    m_teseShaderModule;
+       Move<VkShaderModule>                    m_fragShaderModule;
+
+       Move<VkRenderPass>                              m_renderPass;
+       Move<VkFramebuffer>                             m_framebuffer;
+       Move<VkPipelineLayout>                  m_pipelineLayout;
+       Move<VkPipeline>                                m_pipeline;
+
+       deUint32                                                m_vertexCount;
+       Move<VkBuffer>                                  m_vertexBuffer;
+       de::MovePtr<Allocation>                 m_vertexBufferAlloc;
+};
+
+GraphicsConfiguration::GraphicsConfiguration()
+       : PipelineConfiguration         ()
+       , m_descriptorSetLayout         ()
+       , m_descriptorPool                      ()
+       , m_descriptorSet                       ()
+       , m_framebufferFormat           (VK_FORMAT_R8G8B8A8_UNORM)
+       , m_framebufferImage            ()
+       , m_framebufferImageAlloc       ()
+       , m_framebufferAttachment       ()
+       , m_vertShaderModule            ()
+       , m_geomShaderModule            ()
+       , m_tescShaderModule            ()
+       , m_teseShaderModule            ()
+       , m_fragShaderModule            ()
+       , m_renderPass                          ()
+       , m_framebuffer                         ()
+       , m_pipelineLayout                      ()
+       , m_pipeline                            ()
+       , m_vertexCount                         (0)
+       , m_vertexBuffer                        ()
+       , m_vertexBufferAlloc           ()
+{
+}
+
+void GraphicsConfiguration::checkSupport (Context&                     context,
+                                                                                 const TestParams&     testParams)
+{
+       switch (testParams.stage)
+       {
+               case VK_SHADER_STAGE_VERTEX_BIT:
+                       break;
+
+               case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
+               case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
+               {
+                       context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_GEOMETRY_BIT:
+               {
+                       context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_FRAGMENT_BIT:
+                       break;
+
+               default:
+                       TCU_THROW(InternalError, "Unknown stage");
+       }
+}
+
+void GraphicsConfiguration::initPrograms (SourceCollections&   programCollection,
+                                                                                 const TestParams&             testParams)
+{
+       const std::string       testShaderBody  = testParams.testConfigShaderBodyText(testParams);
+
+       switch (testParams.stage)
+       {
+               case VK_SHADER_STAGE_VERTEX_BIT:
+               {
+                       {
+                               std::ostringstream src;
+                               src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
+                                       << "#extension GL_EXT_ray_query : require\n"
+                                       << "#extension GL_EXT_ray_tracing : require\n"
+                                       << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
+                                       << "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
+                                       << "\n"
+                                       << "void testFunc(ivec3 pos, ivec3 size)\n"
+                                       << "{\n"
+                                       << testShaderBody
+                                       << "}\n"
+                                       << "\n"
+                                       << "void main(void)\n"
+                                       << "{\n"
+                                       << "  const int   posId    = int(gl_VertexIndex / 3);\n"
+                                       << "  const int   vertId   = int(gl_VertexIndex % 3);\n"
+                                       << "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
+                                       << "  const ivec3 pos      = ivec3(posId % size.x, posId / size.x, 0);\n"
+                                       << "\n"
+                                       << "  if (vertId == 0)\n"
+                                       << "  {\n"
+                                       << "    testFunc(pos, size);\n"
+                                       << "  }\n"
+                                       << "}\n";
+
+                               programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
+                       }
+
+                       programCollection.glslSources.add("frag") << glu::FragmentSource(getGraphicsPassthrough());
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
+               {
+                       {
+                               std::ostringstream src;
+                               src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
+                                       << "\n"
+                                       << "layout(location = 0) in vec4 in_position;\n"
+                                       << "out gl_PerVertex\n"
+                                       << "{\n"
+                                       << "  vec4 gl_Position;\n"
+                                       << "};\n"
+                                       << "\n"
+                                       << "void main(void)\n"
+                                       << "{\n"
+                                       << "  gl_Position = in_position;\n"
+                                       << "}\n";
+
+                               programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
+                       }
+
+                       {
+                               std::ostringstream src;
+                               src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
+                                       << "#extension GL_EXT_tessellation_shader : require\n"
+                                       << "#extension GL_EXT_ray_query : require\n"
+                                       << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
+                                       << "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
+                                       << "in gl_PerVertex\n"
+                                       << "{\n"
+                                       << "  vec4 gl_Position;\n"
+                                       << "} gl_in[];\n"
+                                       << "layout(vertices = 4) out;\n"
+                                       << "out gl_PerVertex\n"
+                                       << "{\n"
+                                       << "  vec4 gl_Position;\n"
+                                       << "} gl_out[];\n"
+                                       << "\n"
+                                       << "void testFunc(ivec3 pos, ivec3 size)\n"
+                                       << "{\n"
+                                       << testShaderBody
+                                       << "}\n"
+                                       << "\n"
+                                       << "void main(void)\n"
+                                       << "{\n"
+                                       << "\n"
+                                       << "  if (gl_InvocationID == 0)\n"
+                                       << "  {\n"
+                                       << "    const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
+                                       << "    for (int y = 0; y < size.y; y++)\n"
+                                       << "    for (int x = 0; x < size.x; x++)\n"
+                                       << "    {\n"
+                                       << "      const ivec3 pos = ivec3(x, y, 0);\n"
+                                       << "      testFunc(pos, size);\n"
+                                       << "    }\n"
+                                       << "  }\n"
+                                       << "\n"
+                                       << "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+                                       << "  gl_TessLevelInner[0] = 1;\n"
+                                       << "  gl_TessLevelInner[1] = 1;\n"
+                                       << "  gl_TessLevelOuter[gl_InvocationID] = 1;\n"
+                                       << "}\n";
+
+                               programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str());
+                       }
+
+                       {
+                               std::ostringstream src;
+                               src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
+                                       << "#extension GL_EXT_tessellation_shader : require\n"
+                                       << "layout(quads, equal_spacing, ccw) in;\n"
+                                       << "in gl_PerVertex\n"
+                                       << "{\n"
+                                       << "  vec4 gl_Position;\n"
+                                       << "} gl_in[];\n"
+                                       << "\n"
+                                       << "void main(void)\n"
+                                       << "{\n"
+                                       << "  gl_Position = gl_in[0].gl_Position;\n"
+                                       << "}\n";
+
+                               programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str());
+                       }
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
+               {
+                       {
+                               std::ostringstream src;
+                               src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
+                                       << "\n"
+                                       << "layout(location = 0) in vec4 in_position;\n"
+                                       << "out gl_PerVertex"
+                                       << "{\n"
+                                       << "  vec4 gl_Position;\n"
+                                       << "};\n"
+                                       << "\n"
+                                       << "void main(void)\n"
+                                       << "{\n"
+                                       << "  gl_Position = in_position;\n"
+                                       << "}\n";
+
+                               programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
+                       }
+
+                       {
+                               std::ostringstream src;
+                               src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
+                                       << "#extension GL_EXT_tessellation_shader : require\n"
+                                       << "in gl_PerVertex\n"
+                                       << "{\n"
+                                       << "  vec4 gl_Position;\n"
+                                       << "} gl_in[];\n"
+                                       << "layout(vertices = 4) out;\n"
+                                       << "out gl_PerVertex\n"
+                                       << "{\n"
+                                       << "  vec4 gl_Position;\n"
+                                       << "} gl_out[];\n"
+                                       << "\n"
+                                       << "void main(void)\n"
+                                       << "{\n"
+                                       << "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+                                       << "  gl_TessLevelInner[0] = 1;\n"
+                                       << "  gl_TessLevelInner[1] = 1;\n"
+                                       << "  gl_TessLevelOuter[gl_InvocationID] = 1;\n"
+                                       << "}\n";
+
+                               programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str());
+                       }
+
+                       {
+                               std::ostringstream src;
+                               src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
+                                       << "#extension GL_EXT_tessellation_shader : require\n"
+                                       << "#extension GL_EXT_ray_query : require\n"
+                                       << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
+                                       << "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
+                                       << "layout(quads, equal_spacing, ccw) in;\n"
+                                       << "in gl_PerVertex\n"
+                                       << "{\n"
+                                       << "  vec4 gl_Position;\n"
+                                       << "} gl_in[];\n"
+                                       << "\n"
+                                       << "void testFunc(ivec3 pos, ivec3 size)\n"
+                                       << "{\n"
+                                       << testShaderBody
+                                       << "}\n"
+                                       << "\n"
+                                       << "void main(void)\n"
+                                       << "{\n"
+                                       << "  const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
+                                       << "\n"
+                                       << "  if (gl_PrimitiveID == 0)\n"
+                                       << "  {\n"
+                                       << "    const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
+                                       << "    for (int y = 0; y < size.y; y++)\n"
+                                       << "    for (int x = 0; x < size.x; x++)\n"
+                                       << "    {\n"
+                                       << "      const ivec3 pos = ivec3(x, y, 0);\n"
+                                       << "      testFunc(pos, size);\n"
+                                       << "    }\n"
+                                       << "  }\n"
+                                       << "\n"
+                                       << "  gl_Position = gl_in[0].gl_Position;\n"
+                                       << "}\n";
+
+                               programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str());
+                       }
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_GEOMETRY_BIT:
+               {
+                       programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough());
+
+                       {
+                               std::ostringstream src;
+                               src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
+                                       << "#extension GL_EXT_ray_query : require\n"
+                                       << "layout(triangles) in;\n"
+                                       << "layout(points, max_vertices = 1) out;\n"
+                                       << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
+                                       << "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
+                                       << "\n"
+                                       << "void testFunc(ivec3 pos, ivec3 size)\n"
+                                       << "{\n"
+                                       << testShaderBody
+                                       << "}\n"
+                                       << "\n"
+                                       << "void main(void)\n"
+                                       << "{\n"
+                                       << "  const int   posId    = int(gl_PrimitiveIDIn);\n"
+                                       << "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
+                                       << "  const ivec3 pos      = ivec3(posId % size.x, posId / size.x, 0);\n"
+                                       << "\n"
+                                       << "  testFunc(pos, size);\n"
+                                       << "}\n";
+
+                               programCollection.glslSources.add("geom") << glu::GeometrySource(src.str());
+                       }
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_FRAGMENT_BIT:
+               {
+                       programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough());
+
+                       {
+                               std::ostringstream src;
+                               src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
+                                       << "#extension GL_EXT_ray_query : require\n"
+                                       << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
+                                       << "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
+                                       << "\n"
+                                       << "void testFunc(ivec3 pos, ivec3 size)\n"
+                                       << "{\n"
+                                       << testShaderBody
+                                       << "}\n"
+                                       << "\n"
+                                       << "void main(void)\n"
+                                       << "{\n"
+                                       << "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
+                                       << "  const ivec3 pos      = ivec3(int(gl_FragCoord.x - 0.5f), int(gl_FragCoord.y - 0.5f), 0);\n"
+                                       << "\n"
+                                       << "  testFunc(pos, size);\n"
+                                       << "}\n";
+
+                               programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
+                       }
+
+                       break;
+               }
+
+               default:
+                       TCU_THROW(InternalError, "Unknown stage");
+       }
+}
+
+void GraphicsConfiguration::initVertexBuffer (Context&         context,
+                                                                                         TestParams&   testParams)
+{
+       const DeviceInterface&  vkd                     = context.getDeviceInterface();
+       const VkDevice                  device          = context.getDevice();
+       const deUint32                  width           = testParams.width;
+       const deUint32                  height          = testParams.height;
+       Allocator&                              allocator       = context.getDefaultAllocator();
+       std::vector<tcu::Vec4>  vertices;
+
+       switch (testParams.stage)
+       {
+               case VK_SHADER_STAGE_VERTEX_BIT:
+               {
+                       const float z = 0.0f;
+                       const float w = 1.0f;
+
+                       vertices.reserve(3 * height * width);
+
+                       for (deUint32 y = 0; y < height; ++y)
+                       for (deUint32 x = 0; x < width; ++x)
+                       {
+                               const float     x0      = float(x + 0) / float(width);
+                               const float     y0      = float(y + 0) / float(height);
+                               const float     x1      = float(x + 1) / float(width);
+                               const float     y1      = float(y + 1) / float(height);
+                               const float     xm      = (x0 + x1) / 2.0f;
+                               const float     ym      = (y0 + y1) / 2.0f;
+
+                               vertices.push_back(tcu::Vec4(x0, y0, z, w));
+                               vertices.push_back(tcu::Vec4(xm, y1, z, w));
+                               vertices.push_back(tcu::Vec4(x1, ym, z, w));
+                       }
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
+               {
+                       const float             z = 0.0f;
+                       const float             w = 1.0f;
+                       const tcu::Vec4 a = tcu::Vec4(-1.0f, -1.0f, z, w);
+                       const tcu::Vec4 b = tcu::Vec4(+1.0f, -1.0f, z, w);
+                       const tcu::Vec4 c = tcu::Vec4(+1.0f, +1.0f, z, w);
+                       const tcu::Vec4 d = tcu::Vec4(-1.0f, +1.0f, z, w);
+
+                       vertices.push_back(a);
+                       vertices.push_back(b);
+                       vertices.push_back(c);
+                       vertices.push_back(d);
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
+               {
+                       const float             z = 0.0f;
+                       const float             w = 1.0f;
+                       const tcu::Vec4 a = tcu::Vec4(-1.0f, -1.0f, z, w);
+                       const tcu::Vec4 b = tcu::Vec4(+1.0f, -1.0f, z, w);
+                       const tcu::Vec4 c = tcu::Vec4(+1.0f, +1.0f, z, w);
+                       const tcu::Vec4 d = tcu::Vec4(-1.0f, +1.0f, z, w);
+
+                       vertices.push_back(a);
+                       vertices.push_back(b);
+                       vertices.push_back(c);
+                       vertices.push_back(d);
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_GEOMETRY_BIT:
+               {
+                       const float z = 0.0f;
+                       const float w = 1.0f;
+
+                       vertices.reserve(3 * height * width);
+
+                       for (deUint32 y = 0; y < height; ++y)
+                       for (deUint32 x = 0; x < width; ++x)
+                       {
+                               const float     x0      = float(x + 0) / float(width);
+                               const float     y0      = float(y + 0) / float(height);
+                               const float     x1      = float(x + 1) / float(width);
+                               const float     y1      = float(y + 1) / float(height);
+                               const float     xm      = (x0 + x1) / 2.0f;
+                               const float     ym      = (y0 + y1) / 2.0f;
+
+                               vertices.push_back(tcu::Vec4(x0, y0, z, w));
+                               vertices.push_back(tcu::Vec4(xm, y1, z, w));
+                               vertices.push_back(tcu::Vec4(x1, ym, z, w));
+                       }
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_FRAGMENT_BIT:
+               {
+                       const float             z = 1.0f;
+                       const float             w = 1.0f;
+                       const tcu::Vec4 a = tcu::Vec4(-1.0f, -1.0f, z, w);
+                       const tcu::Vec4 b = tcu::Vec4(+1.0f, -1.0f, z, w);
+                       const tcu::Vec4 c = tcu::Vec4(-1.0f, +1.0f, z, w);
+                       const tcu::Vec4 d = tcu::Vec4(+1.0f, +1.0f, z, w);
+
+                       vertices.push_back(a);
+                       vertices.push_back(b);
+                       vertices.push_back(c);
+
+                       vertices.push_back(b);
+                       vertices.push_back(c);
+                       vertices.push_back(d);
+
+                       break;
+               }
+
+               default:
+                       TCU_THROW(InternalError, "Unknown stage");
+
+       }
+
+       // Initialize vertex buffer
+       {
+               const VkDeviceSize                      vertexBufferSize                = sizeof(vertices[0][0]) * vertices[0].SIZE * vertices.size();
+               const VkBufferCreateInfo        vertexBufferCreateInfo  = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
+
+               m_vertexCount           = static_cast<deUint32>(vertices.size());
+               m_vertexBuffer          = createBuffer(vkd, device, &vertexBufferCreateInfo);
+               m_vertexBufferAlloc     = bindBuffer(vkd, device, allocator, *m_vertexBuffer, vk::MemoryRequirement::HostVisible);
+
+               deMemcpy(m_vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexBufferSize);
+               flushAlloc(vkd, device, *m_vertexBufferAlloc);
+       }
+}
+
+Move<VkPipeline> GraphicsConfiguration::makeGraphicsPipeline (Context&         context,
+                                                                                                                         TestParams&   testParams)
+{
+       const DeviceInterface&                  vkd                                     = context.getDeviceInterface();
+       const VkDevice                                  device                          = context.getDevice();
+       const bool                                              tessStageTest           = (testParams.stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || testParams.stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
+       const VkPrimitiveTopology               topology                        = tessStageTest ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+       const deUint32                                  patchControlPoints      = tessStageTest ? 4 : 0;
+       const std::vector<VkViewport>   viewports                       (1, makeViewport(testParams.width, testParams.height));
+       const std::vector<VkRect2D>             scissors                        (1, makeRect2D(testParams.width, testParams.height));
+
+       return vk::makeGraphicsPipeline (vkd,
+                                                                        device,
+                                                                        *m_pipelineLayout,
+                                                                        *m_vertShaderModule,
+                                                                        *m_tescShaderModule,
+                                                                        *m_teseShaderModule,
+                                                                        *m_geomShaderModule,
+                                                                        *m_fragShaderModule,
+                                                                        *m_renderPass,
+                                                                        viewports,
+                                                                        scissors,
+                                                                        topology,
+                                                                        0,
+                                                                        patchControlPoints);
+}
+
+void GraphicsConfiguration::initConfiguration (Context&                context,
+                                                                                          TestParams&  testParams)
+{
+       const DeviceInterface&  vkd                     = context.getDeviceInterface();
+       const VkDevice                  device          = context.getDevice();
+       Allocator&                              allocator       = context.getDefaultAllocator();
+       vk::BinaryCollection&   collection      = context.getBinaryCollection();
+       VkShaderStageFlags              shaders         = static_cast<VkShaderStageFlags>(0);
+       deUint32                                shaderCount     = 0;
+
+       if (collection.contains("vert")) shaders |= VK_SHADER_STAGE_VERTEX_BIT;
+       if (collection.contains("geom")) shaders |= VK_SHADER_STAGE_GEOMETRY_BIT;
+       if (collection.contains("tesc")) shaders |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
+       if (collection.contains("tese")) shaders |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
+       if (collection.contains("frag")) shaders |= VK_SHADER_STAGE_FRAGMENT_BIT;
+
+       for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
+               shaderCount++;
+
+       if (shaderCount != (deUint32)dePop32(shaders))
+               TCU_THROW(InternalError, "Unused shaders detected in the collection");
+
+       if (0 != (shaders & VK_SHADER_STAGE_VERTEX_BIT))                                        m_vertShaderModule = createShaderModule(vkd, device, collection.get("vert"), 0);
+       if (0 != (shaders & VK_SHADER_STAGE_GEOMETRY_BIT))                                      m_geomShaderModule = createShaderModule(vkd, device, collection.get("geom"), 0);
+       if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT))          m_tescShaderModule = createShaderModule(vkd, device, collection.get("tesc"), 0);
+       if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))       m_teseShaderModule = createShaderModule(vkd, device, collection.get("tese"), 0);
+       if (0 != (shaders & VK_SHADER_STAGE_FRAGMENT_BIT))                                      m_fragShaderModule = createShaderModule(vkd, device, collection.get("frag"), 0);
+
+       m_descriptorSetLayout   = DescriptorSetLayoutBuilder()
+                                                               .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL_GRAPHICS)
+                                                               .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL_GRAPHICS)
+                                                               .build(vkd, device);
+       m_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);
+       m_descriptorSet                 = makeDescriptorSet             (vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
+       m_framebufferImage              = makeImage                             (vkd, device, makeImageCreateInfo(m_framebufferFormat, testParams.width, testParams.height, 1u, VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
+       m_framebufferImageAlloc = bindImage                             (vkd, device, allocator, *m_framebufferImage, MemoryRequirement::Any);
+       m_framebufferAttachment = makeImageView                 (vkd, device, *m_framebufferImage, VK_IMAGE_VIEW_TYPE_2D, m_framebufferFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
+       m_renderPass                    = makeRenderPass                (vkd, device, m_framebufferFormat);
+       m_framebuffer                   = makeFramebuffer               (vkd, device, *m_renderPass, *m_framebufferAttachment, testParams.width, testParams.height);
+       m_pipelineLayout                = makePipelineLayout    (vkd, device, m_descriptorSetLayout.get());
+       m_pipeline                              = makeGraphicsPipeline  (context, testParams);
+
+       initVertexBuffer(context, testParams);
+}
+
+void GraphicsConfiguration::fillCommandBuffer (Context&                                                                context,
+                                                                                          TestParams&                                                  testParams,
+                                                                                          VkCommandBuffer                                              cmdBuffer,
+                                                                                          const VkAccelerationStructureKHR*    rayQueryTopAccelerationStructurePtr,
+                                                                                          const VkDescriptorImageInfo&                 resultImageInfo)
+{
+       const DeviceInterface&                                                          vkd                                                                                             = context.getDeviceInterface();
+       const VkDevice                                                                          device                                                                                  = context.getDevice();
+       const VkDeviceSize                                                                      vertexBufferOffset                                                              = 0;
+       const VkWriteDescriptorSetAccelerationStructureKHR      rayQueryAccelerationStructureWriteDescriptorSet =
+       {
+               VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,      //  VkStructureType                                             sType;
+               DE_NULL,                                                                                                                        //  const void*                                                 pNext;
+               1u,                                                                                                                                     //  deUint32                                                    accelerationStructureCount;
+               rayQueryTopAccelerationStructurePtr,                                                            //  const VkAccelerationStructureKHR*   pAccelerationStructures;
+       };
+
+       DescriptorSetUpdateBuilder()
+               .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
+               .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
+               .update(vkd, device);
+
+       vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
+       vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
+       vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
+
+       beginRenderPass(vkd, cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, testParams.width, testParams.height), tcu::UVec4());
+
+       vkd.cmdDraw(cmdBuffer, m_vertexCount, 1u, 0u, 0u);
+
+       endRenderPass(vkd, cmdBuffer);
+}
+
+class ComputeConfiguration : public PipelineConfiguration
+{
+public:
+                                                               ComputeConfiguration    ();
+       virtual                                         ~ComputeConfiguration   () {};
+
+       static void                                     checkSupport                    (Context&                                                       context,
+                                                                                                                const TestParams&                                      testParams);
+       static void                                     initPrograms                    (SourceCollections&                                     programCollection,
+                                                                                                                const TestParams&                                      testParams);
+
+       virtual void                            initConfiguration               (Context&                                                       context,
+                                                                                                                TestParams&                                            testParams) override;
+       virtual void                            fillCommandBuffer               (Context&                                                       context,
+                                                                                                                TestParams&                                            testParams,
+                                                                                                                VkCommandBuffer                                        commandBuffer,
+                                                                                                                const VkAccelerationStructureKHR*      rayQueryTopAccelerationStructurePtr,
+                                                                                                                const VkDescriptorImageInfo&           resultImageInfo) override;
+
+protected:
+       Move<VkDescriptorSetLayout>     m_descriptorSetLayout;
+       Move<VkDescriptorPool>          m_descriptorPool;
+       Move<VkDescriptorSet>           m_descriptorSet;
+       Move<VkPipelineLayout>          m_pipelineLayout;
+
+       Move<VkShaderModule>            m_shaderModule;
+
+       Move<VkPipeline>                        m_pipeline;
+};
+
+ComputeConfiguration::ComputeConfiguration ()
+       : PipelineConfiguration ()
+       , m_descriptorSetLayout ()
+       , m_descriptorPool              ()
+       , m_descriptorSet               ()
+       , m_pipelineLayout              ()
+
+       , m_shaderModule                ()
+
+       , m_pipeline                    ()
+{
+}
+
+void ComputeConfiguration::checkSupport (Context&                      context,
+                                                                                const TestParams&      testParams)
+{
+       DE_UNREF(context);
+       DE_UNREF(testParams);
+}
+
+void ComputeConfiguration::initPrograms (SourceCollections&    programCollection,
+                                                                                const TestParams&      testParams)
+{
+       const std::string       testShaderBody          = testParams.testConfigShaderBodyText(testParams);
+       const std::string       testBody                        =
+               "  ivec3       pos      = ivec3(gl_WorkGroupID);\n"
+               "  ivec3       size     = ivec3(gl_NumWorkGroups);\n"
+               + testShaderBody;
+
+       switch (testParams.stage)
+       {
+               case VK_SHADER_STAGE_COMPUTE_BIT:
+               {
+                       std::stringstream css;
+                       css <<
+                               "#version 460 core\n"
+                               "#extension GL_EXT_ray_query : require\n"
+                               "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
+                               "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
+                               "\n"
+                               "void main()\n"
+                               "{\n"
+                               << testBody <<
+                               "}\n";
+
+                       programCollection.glslSources.add("comp") << glu::ComputeSource(updateRayTracingGLSL(css.str()));
+
+                       break;
+               }
+
+               default:
+                       TCU_THROW(InternalError, "Unknown stage");
+       }
+}
+
+void ComputeConfiguration::initConfiguration (Context&         context,
+                                                                                         TestParams&   testParams)
+{
+       DE_UNREF(testParams);
+
+       const DeviceInterface&  vkd                     = context.getDeviceInterface();
+       const VkDevice                  device          = context.getDevice();
+       vk::BinaryCollection&   collection      = context.getBinaryCollection();
+
+       m_descriptorSetLayout   = DescriptorSetLayoutBuilder()
+                                                               .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
+                                                               .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_COMPUTE_BIT)
+                                                               .build(vkd, device);
+       m_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);
+       m_descriptorSet                 = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
+       m_pipelineLayout                = makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
+       m_shaderModule                  = createShaderModule(vkd, device, collection.get("comp"), 0);
+       m_pipeline                              = makeComputePipeline(vkd, device, *m_pipelineLayout, *m_shaderModule);
+}
+
+void ComputeConfiguration::fillCommandBuffer (Context&                                                 context,
+                                                                                         TestParams&                                           testParams,
+                                                                                         VkCommandBuffer                                       cmdBuffer,
+                                                                                         const VkAccelerationStructureKHR*     rayQueryTopAccelerationStructurePtr,
+                                                                                         const VkDescriptorImageInfo&          resultImageInfo)
+{
+       const DeviceInterface&                                                          vkd                                                                                             = context.getDeviceInterface();
+       const VkDevice                                                                          device                                                                                  = context.getDevice();
+       const VkWriteDescriptorSetAccelerationStructureKHR      rayQueryAccelerationStructureWriteDescriptorSet =
+       {
+               VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,      //  VkStructureType                                             sType;
+               DE_NULL,                                                                                                                        //  const void*                                                 pNext;
+               1u,                                                                                                                                     //  deUint32                                                    accelerationStructureCount;
+               rayQueryTopAccelerationStructurePtr,                                                            //  const VkAccelerationStructureKHR*   pAccelerationStructures;
+       };
+
+       DescriptorSetUpdateBuilder()
+               .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
+               .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
+               .update(vkd, device);
+
+       vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
+
+       vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline.get());
+
+       vkd.cmdDispatch(cmdBuffer, testParams.width, testParams.height, 1);
+}
+
+class RayTracingConfiguration : public PipelineConfiguration
+{
+public:
+                                                                                                       RayTracingConfiguration                         ();
+       virtual                                                                                 ~RayTracingConfiguration                        () {};
+
+       static void                                                                             checkSupport                                            (Context&                                                       context,
+                                                                                                                                                                                const TestParams&                                      testParams);
+       static void                                                                             initPrograms                                            (SourceCollections&                                     programCollection,
+                                                                                                                                                                                const TestParams&                                      testParams);
+
+       virtual void                                                                    initConfiguration                                       (Context&                                                       context,
+                                                                                                                                                                                TestParams&                                            testParams) override;
+       virtual void                                                                    fillCommandBuffer                                       (Context&                                                       context,
+                                                                                                                                                                                TestParams&                                            testParams,
+                                                                                                                                                                                VkCommandBuffer                                        commandBuffer,
+                                                                                                                                                                                const VkAccelerationStructureKHR*      rayQueryTopAccelerationStructurePtr,
+                                                                                                                                                                                const VkDescriptorImageInfo&           resultImageInfo) override;
+
+protected:
+       de::MovePtr<BufferWithMemory>                                   createShaderBindingTable                        (const InstanceInterface&                       vki,
+                                                                                                                                                                                const DeviceInterface&                         vkd,
+                                                                                                                                                                                const VkDevice                                         device,
+                                                                                                                                                                                const VkPhysicalDevice                         physicalDevice,
+                                                                                                                                                                                const VkPipeline                                       pipeline,
+                                                                                                                                                                                Allocator&                                                     allocator,
+                                                                                                                                                                                de::MovePtr<RayTracingPipeline>&       rayTracingPipeline,
+                                                                                                                                                                                const deUint32                                         group);
+
+protected:
+       deUint32                                                                                m_shaders;
+       deUint32                                                                                m_raygenShaderGroup;
+       deUint32                                                                                m_missShaderGroup;
+       deUint32                                                                                m_hitShaderGroup;
+       deUint32                                                                                m_callableShaderGroup;
+       deUint32                                                                                m_shaderGroupCount;
+
+       Move<VkDescriptorSetLayout>                                             m_descriptorSetLayout;
+       Move<VkDescriptorPool>                                                  m_descriptorPool;
+       Move<VkDescriptorSet>                                                   m_descriptorSet;
+       Move<VkPipelineLayout>                                                  m_pipelineLayout;
+
+       de::MovePtr<RayTracingPipeline>                                 m_rayTracingPipeline;
+       Move<VkPipeline>                                                                m_pipeline;
+
+       de::MovePtr<BufferWithMemory>                                   m_raygenShaderBindingTable;
+       de::MovePtr<BufferWithMemory>                                   m_hitShaderBindingTable;
+       de::MovePtr<BufferWithMemory>                                   m_missShaderBindingTable;
+       de::MovePtr<BufferWithMemory>                                   m_callableShaderBindingTable;
+
+       VkStridedDeviceAddressRegionKHR                                 m_raygenShaderBindingTableRegion;
+       VkStridedDeviceAddressRegionKHR                                 m_missShaderBindingTableRegion;
+       VkStridedDeviceAddressRegionKHR                                 m_hitShaderBindingTableRegion;
+       VkStridedDeviceAddressRegionKHR                                 m_callableShaderBindingTableRegion;
+
+       de::SharedPtr<BottomLevelAccelerationStructure> m_bottomLevelAccelerationStructure;
+       de::SharedPtr<TopLevelAccelerationStructure>    m_topLevelAccelerationStructure;
+};
+
+RayTracingConfiguration::RayTracingConfiguration()
+       : m_shaders                                                             (0)
+       , m_raygenShaderGroup                                   (~0u)
+       , m_missShaderGroup                                             (~0u)
+       , m_hitShaderGroup                                              (~0u)
+       , m_callableShaderGroup                                 (~0u)
+       , m_shaderGroupCount                                    (0)
+
+       , m_descriptorSetLayout                                 ()
+       , m_descriptorPool                                              ()
+       , m_descriptorSet                                               ()
+       , m_pipelineLayout                                              ()
+
+       , m_rayTracingPipeline                                  ()
+       , m_pipeline                                                    ()
+
+       , m_raygenShaderBindingTable                    ()
+       , m_hitShaderBindingTable                               ()
+       , m_missShaderBindingTable                              ()
+       , m_callableShaderBindingTable                  ()
+
+       , m_raygenShaderBindingTableRegion              ()
+       , m_missShaderBindingTableRegion                ()
+       , m_hitShaderBindingTableRegion                 ()
+       , m_callableShaderBindingTableRegion    ()
+
+       , m_bottomLevelAccelerationStructure    ()
+       , m_topLevelAccelerationStructure               ()
+{
+}
+
+void RayTracingConfiguration::checkSupport (Context&                   context,
+                                                                                       const TestParams&       testParams)
+{
+       DE_UNREF(testParams);
+
+       const VkPhysicalDeviceRayTracingFeaturesKHR&    rayTracingFeaturesKHR = context.getRayTracingFeatures();
+
+       if (rayTracingFeaturesKHR.rayTracing == DE_FALSE)
+               TCU_THROW(NotSupportedError, "Requires rayTracingFeaturesKHR.rayTracing");
+}
+
+void RayTracingConfiguration::initPrograms (SourceCollections& programCollection,
+                                                                                       const TestParams&       testParams)
+{
+       const std::string       testShaderBody          = testParams.testConfigShaderBodyText(testParams);
+       const std::string       testBody                        =
+               "  ivec3       pos      = ivec3(gl_LaunchIDEXT);\n"
+               "  ivec3       size     = ivec3(gl_LaunchSizeEXT);\n"
+               + testShaderBody;
+
+       switch (testParams.stage)
+       {
+               case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
+               {
+                       std::stringstream css;
+                       css <<
+                               "#version 460 core\n"
+                               "#extension GL_EXT_ray_tracing : require\n"
+                               "#extension GL_EXT_ray_query : require\n"
+                               "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
+                               "layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
+                               "\n"
+                               "void main()\n"
+                               "{\n"
+                               << testBody <<
+                               "}\n";
+
+                       programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str()));
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
+               {
+                       programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader()));
+
+                       {
+                               std::stringstream css;
+                               css <<
+                                       "#version 460 core\n"
+                                       "#extension GL_EXT_ray_tracing : require\n"
+                                       "#extension GL_EXT_ray_query : require\n"
+                                       "hitAttributeEXT vec3 attribs;\n"
+                                       "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
+                                       "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
+                                       "layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
+                                       "\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       << testBody <<
+                                       "}\n";
+
+                               programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str()));
+                       }
+
+                       programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough()));
+                       programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough()));
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
+               {
+                       programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader()));
+
+                       {
+                               std::stringstream css;
+                               css <<
+                                       "#version 460 core\n"
+                                       "#extension GL_EXT_ray_tracing : require\n"
+                                       "#extension GL_EXT_ray_query : require\n"
+                                       "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
+                                       "hitAttributeEXT vec3 attribs;\n"
+                                       "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
+                                       "layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
+                                       "\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       << testBody <<
+                                       "}\n";
+
+                               programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str()));
+                       }
+
+                       programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough()));
+                       programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough()));
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
+               {
+                       programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader()));
+
+                       {
+                               std::stringstream css;
+                               css <<
+                                       "#version 460 core\n"
+                                       "#extension GL_EXT_ray_tracing : require\n"
+                                       "#extension GL_EXT_ray_query : require\n"
+                                       "hitAttributeEXT vec3 hitAttribute;\n"
+                                       "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
+                                       "layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
+                                       "\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       << testBody <<
+                                       "  hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n"
+                                       "  reportIntersectionEXT(1.0f, 0);\n"
+                                       "}\n";
+
+                               programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str()));
+                       }
+
+                       programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough()));
+                       programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough()));
+                       programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough()));
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_MISS_BIT_KHR:
+               {
+                       programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader()));
+
+                       {
+                               std::stringstream css;
+                               css <<
+                                       "#version 460 core\n"
+                                       "#extension GL_EXT_ray_tracing : require\n"
+                                       "#extension GL_EXT_ray_query : require\n"
+                                       "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
+                                       "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
+                                       "layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
+                                       "\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       << testBody <<
+                                       "}\n";
+
+                               programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str()));
+                       }
+
+                       programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough()));
+                       programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough()));
+
+                       break;
+               }
+
+               case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
+               {
+                       {
+                               std::stringstream css;
+                               css <<
+                                       "#version 460 core\n"
+                                       "#extension GL_EXT_ray_tracing : require\n"
+                                       "#extension GL_EXT_ray_query : require\n"
+                                       "layout(location = 0) callableDataEXT float dummy;"
+                                       "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
+                                       "\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       "  executeCallableEXT(0, 0);\n"
+                                       "}\n";
+
+                               programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str()));
+                       }
+
+                       {
+                               std::stringstream css;
+                               css <<
+                                       "#version 460 core\n"
+                                       "#extension GL_EXT_ray_tracing : require\n"
+                                       "#extension GL_EXT_ray_query : require\n"
+                                       "layout(location = 0) callableDataInEXT float dummy;"
+                                       "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
+                                       "layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
+                                       "\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       << testBody <<
+                                       "}\n";
+
+                               programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(css.str()));
+                       }
+
+                       programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough()));
+                       programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough()));
+                       programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough()));
+
+                       break;
+               }
+
+               default:
+                       TCU_THROW(InternalError, "Unknown stage");
+       }
+}
+
+de::MovePtr<BufferWithMemory> RayTracingConfiguration::createShaderBindingTable (const InstanceInterface&                      vki,
+                                                                                                                                                                const DeviceInterface&                         vkd,
+                                                                                                                                                                const VkDevice                                         device,
+                                                                                                                                                                const VkPhysicalDevice                         physicalDevice,
+                                                                                                                                                                const VkPipeline                                       pipeline,
+                                                                                                                                                                Allocator&                                                     allocator,
+                                                                                                                                                                de::MovePtr<RayTracingPipeline>&       rayTracingPipeline,
+                                                                                                                                                                const deUint32                                         group)
+{
+       de::MovePtr<BufferWithMemory>   shaderBindingTable;
+
+       if (group < m_shaderGroupCount)
+       {
+               const deUint32  shaderGroupHandleSize           = getShaderGroupHandleSize(vki, physicalDevice);
+               const deUint32  shaderGroupBaseAlignment        = getShaderGroupBaseAlignment(vki, physicalDevice);
+
+               shaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, group, 1u);
+       }
+
+       return shaderBindingTable;
+}
+
+void RayTracingConfiguration::initConfiguration (Context&              context,
+                                                                                                TestParams&    testParams)
+{
+       DE_UNREF(testParams);
+
+       const InstanceInterface&        vki                                             = context.getInstanceInterface();
+       const DeviceInterface&          vkd                                             = context.getDeviceInterface();
+       const VkDevice                          device                                  = context.getDevice();
+       const VkPhysicalDevice          physicalDevice                  = context.getPhysicalDevice();
+       vk::BinaryCollection&           collection                              = context.getBinaryCollection();
+       Allocator&                                      allocator                               = context.getDefaultAllocator();
+       const deUint32                          shaderGroupHandleSize   = getShaderGroupHandleSize(vki, physicalDevice);
+       const VkShaderStageFlags        hitStages                               = VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
+       deUint32                                        shaderCount                             = 0;
+
+       m_shaderGroupCount = 0;
+
+       if (collection.contains("rgen")) m_shaders |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
+       if (collection.contains("ahit")) m_shaders |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
+       if (collection.contains("chit")) m_shaders |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
+       if (collection.contains("miss")) m_shaders |= VK_SHADER_STAGE_MISS_BIT_KHR;
+       if (collection.contains("sect")) m_shaders |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
+       if (collection.contains("call")) m_shaders |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
+
+       for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
+               shaderCount++;
+
+       if (shaderCount != (deUint32)dePop32(m_shaders))
+               TCU_THROW(InternalError, "Unused shaders detected in the collection");
+
+       if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))
+               m_raygenShaderGroup             = m_shaderGroupCount++;
+
+       if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))
+               m_missShaderGroup               = m_shaderGroupCount++;
+
+       if (0 != (m_shaders & hitStages))
+               m_hitShaderGroup                = m_shaderGroupCount++;
+
+       if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))
+               m_callableShaderGroup   = m_shaderGroupCount++;
+
+       m_rayTracingPipeline                            = de::newMovePtr<RayTracingPipeline>();
+
+       m_descriptorSetLayout                           = DescriptorSetLayoutBuilder()
+                                                                                       .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
+                                                                                       .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
+                                                                                       .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
+                                                                                       .build(vkd, device);
+       m_descriptorPool                                        = DescriptorPoolBuilder()
+                                                                                       .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
+                                                                                       .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
+                                                                                       .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
+                                                                                       .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
+       m_descriptorSet                                         = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
+
+       if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))                  m_rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR                  , createShaderModule(vkd, device, collection.get("rgen"), 0), m_raygenShaderGroup);
+       if (0 != (m_shaders & VK_SHADER_STAGE_ANY_HIT_BIT_KHR))                 m_rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR                 , createShaderModule(vkd, device, collection.get("ahit"), 0), m_hitShaderGroup);
+       if (0 != (m_shaders & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR))             m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR             , createShaderModule(vkd, device, collection.get("chit"), 0), m_hitShaderGroup);
+       if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))                    m_rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR                    , createShaderModule(vkd, device, collection.get("miss"), 0), m_missShaderGroup);
+       if (0 != (m_shaders & VK_SHADER_STAGE_INTERSECTION_BIT_KHR))    m_rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR    , createShaderModule(vkd, device, collection.get("sect"), 0), m_hitShaderGroup);
+       if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))                m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR                , createShaderModule(vkd, device, collection.get("call"), 0), m_callableShaderGroup);
+
+       m_pipelineLayout                                        = makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
+       m_pipeline                                                      = m_rayTracingPipeline->createPipeline(vkd, device, *m_pipelineLayout);
+
+       m_raygenShaderBindingTable                      = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_raygenShaderGroup);
+       m_missShaderBindingTable                        = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_missShaderGroup);
+       m_hitShaderBindingTable                         = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_hitShaderGroup);
+       m_callableShaderBindingTable            = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_callableShaderGroup);
+
+       m_raygenShaderBindingTableRegion        = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_raygenShaderBindingTable),          shaderGroupHandleSize);
+       m_missShaderBindingTableRegion          = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_missShaderBindingTable),            shaderGroupHandleSize);
+       m_hitShaderBindingTableRegion           = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_hitShaderBindingTable),                     shaderGroupHandleSize);
+       m_callableShaderBindingTableRegion      = makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_callableShaderBindingTable),        shaderGroupHandleSize);
+}
+
+void RayTracingConfiguration::fillCommandBuffer (Context&                                                      context,
+                                                                                                TestParams&                                            testParams,
+                                                                                                VkCommandBuffer                                        commandBuffer,
+                                                                                                const VkAccelerationStructureKHR*      rayQueryTopAccelerationStructurePtr,
+                                                                                                const VkDescriptorImageInfo&           resultImageInfo)
+{
+       const DeviceInterface&                                                  vkd                                                                     = context.getDeviceInterface();
+       const VkDevice                                                                  device                                                          = context.getDevice();
+       Allocator&                                                                              allocator                                                       = context.getDefaultAllocator();
+       de::MovePtr<BottomLevelAccelerationStructure>   bottomLevelAccelerationStructure        = makeBottomLevelAccelerationStructure();
+       de::MovePtr<TopLevelAccelerationStructure>              topLevelAccelerationStructure           = makeTopLevelAccelerationStructure();
+
+       m_bottomLevelAccelerationStructure = de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release());
+       m_bottomLevelAccelerationStructure->setDefaultGeometryData(testParams.stage);
+       m_bottomLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
+
+       m_topLevelAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(topLevelAccelerationStructure.release());
+       m_topLevelAccelerationStructure->setInstanceCount(1);
+       m_topLevelAccelerationStructure->addInstance(m_bottomLevelAccelerationStructure);
+       m_topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
+
+       const TopLevelAccelerationStructure*                            topLevelAccelerationStructurePtr                                = m_topLevelAccelerationStructure.get();
+       const 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;
+       };
+       const VkWriteDescriptorSetAccelerationStructureKHR      rayQueryAccelerationStructureWriteDescriptorSet =
+       {
+               VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,      //  VkStructureType                                             sType;
+               DE_NULL,                                                                                                                        //  const void*                                                 pNext;
+               1u,                                                                                                                                     //  deUint32                                                    accelerationStructureCount;
+               rayQueryTopAccelerationStructurePtr,                                                            //  const VkAccelerationStructureKHR*   pAccelerationStructures;
+       };
+
+       DescriptorSetUpdateBuilder()
+               .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
+               .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
+               .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
+               .update(vkd, device);
+
+       vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
+
+       vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, m_pipeline.get());
+
+       cmdTraceRays(vkd,
+               commandBuffer,
+               &m_raygenShaderBindingTableRegion,
+               &m_missShaderBindingTableRegion,
+               &m_hitShaderBindingTableRegion,
+               &m_callableShaderBindingTableRegion,
+               testParams.width, testParams.height, 1);
+}
+
+
+const std::string getShaderBodyText (const TestParams& testParams)
+{
+       if (testParams.geomType == GEOM_TYPE_AABBS)
+       {
+               const std::string result =
+                       "  uint        rayFlags = 0;\n"
+                       "  uint        cullMask = 0xFF;\n"
+                       "  float       tmin     = 0.0;\n"
+                       "  float       tmax     = 9.0;\n"
+                       "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
+                       "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
+                       "  uint        count    = 0;\n"
+                       "  rayQueryEXT rayQuery;\n"
+                       "\n"
+                       "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
+                       "\n"
+                       "  while(rayQueryProceedEXT(rayQuery))\n"
+                       "  {\n"
+                       "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
+                       "    {\n"
+                       "      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n"
+                       "      count++;\n"
+                       "    }\n"
+                       "  }\n"
+                       "  imageStore(result, pos, ivec4(count, 0, 0, 0));\n"
+                       "\n";
+
+               return result;
+       }
+       else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
+       {
+               const std::string result =
+                       "  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
+                       "  uint        cullMask = 0xFF;\n"
+                       "  float       tmin     = 0.0;\n"
+                       "  float       tmax     = 9.0;\n"
+                       "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
+                       "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
+                       "  uint        count    = 0;\n"
+                       "  rayQueryEXT rayQuery;\n"
+                       "\n"
+                       "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
+                       "\n"
+                       "  while(rayQueryProceedEXT(rayQuery))\n"
+                       "  {\n"
+                       "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
+                       "    {\n"
+                       "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
+                       "      count++;\n"
+                       "    }\n"
+                       "  }\n"
+                       "  imageStore(result, pos, ivec4(count, 0, 0, 0));\n"
+                       "\n";
+
+               return result;
+       }
+       else
+       {
+               TCU_THROW(InternalError, "Unknown geometry type");
+       }
+}
+
+
+class TestConfigurationNoMiss : public TestConfiguration
+{
+public:
+       virtual const VkAccelerationStructureKHR*       initAccelerationStructures      (Context&                                                       context,
+                                                                                                                                                        TestParams&                                            testParams,
+                                                                                                                                                        VkCommandBuffer                                        cmdBuffer) override;
+
+       virtual bool                                                            verify                                          (BufferWithMemory*                                      resultBuffer,
+                                                                                                                                                        Context&                                                       context,
+                                                                                                                                                        TestParams&                                            testParams) override;
+private:
+       deUint32                                                                        chooseAABB                                      (de::Random&                                            rng,
+                                                                                                                                                        const std::vector<tcu::Vec2>&          vertices,
+                                                                                                                                                        const std::vector<tcu::UVec2>&         aabbs);
+       deUint32                                                                        chooseTriangle                          (de::Random&                                            rng,
+                                                                                                                                                        const std::vector<tcu::Vec2>&          vertices,
+                                                                                                                                                        const std::vector<tcu::UVec3>&         triangles);
+};
+
+deUint32 TestConfigurationNoMiss::chooseAABB (de::Random&                                              rng,
+                                                                                         const std::vector<tcu::Vec2>&         vertices,
+                                                                                         const std::vector<tcu::UVec2>&        aabbs)
+{
+       while (true)
+       {
+               const deUint32          n       = (deUint32)rng.getInt(0, (deUint32)aabbs.size() - 1);
+               const tcu::UVec2&       t       = aabbs[n];
+               const tcu::Vec2&        a       = vertices[t.x()];
+               const tcu::Vec2&        b       = vertices[t.y()];
+
+               if (deFloatAbs(a.x() - b.x()) < MIN_AABB_SIDE_LENGTH || deFloatAbs(a.y() - b.y()) < MIN_AABB_SIDE_LENGTH)
+                       continue;
+
+               return n;
+       }
+}
+
+deUint32 TestConfigurationNoMiss::chooseTriangle (de::Random&                                          rng,
+                                                                                                 const std::vector<tcu::Vec2>&         vertices,
+                                                                                                 const std::vector<tcu::UVec3>&        triangles)
+{
+       while (true)
+       {
+               const deUint32          n       = (deUint32)rng.getInt(0, (deUint32)triangles.size() - 1);
+               const tcu::UVec3&       t       = triangles[n];
+               const tcu::Vec2&        a       = vertices[t.x()];
+               const tcu::Vec2&        b       = vertices[t.y()];
+               const tcu::Vec2&        c       = vertices[t.z()];
+               const float                     ab      = triangleEdgeLength(a, b);
+               const float                     bc      = triangleEdgeLength(b, c);
+               const float                     ca      = triangleEdgeLength(c, a);
+
+               if (ab < MIN_TRIANGLE_EDGE_LENGTH || bc < MIN_TRIANGLE_EDGE_LENGTH || ca < MIN_TRIANGLE_EDGE_LENGTH || triangleArea(ab, bc, ca) < MIN_TRIANGLE_AREA_SIZE)
+                       continue;
+
+               return n;
+       }
+}
+
+const VkAccelerationStructureKHR* TestConfigurationNoMiss::initAccelerationStructures (Context&                        context,
+                                                                                                                                                                          TestParams&          testParams,
+                                                                                                                                                                          VkCommandBuffer      cmdBuffer)
+{
+       const DeviceInterface&                                                  vkd                                                                                     = context.getDeviceInterface();
+       const VkDevice                                                                  device                                                                          = context.getDevice();
+       Allocator&                                                                              allocator                                                                       = context.getDefaultAllocator();
+       const tcu::Vec2                                                                 centerPixelCenter                                                       = tcu::Vec2(0.5f - 0.5f / float(testParams.width), 0.5f - 0.5f / float(testParams.height));
+       de::MovePtr<BottomLevelAccelerationStructure>   rayQueryBottomLevelAccelerationStructure        = makeBottomLevelAccelerationStructure();
+       de::MovePtr<TopLevelAccelerationStructure>              rayQueryTopLevelAccelerationStructure           = makeTopLevelAccelerationStructure();
+       de::Random                                                                              rng                                                                                     (testParams.randomSeed);
+       std::vector<tcu::Vec3>                                                  geometryData;
+
+       if (testParams.geomType == GEOM_TYPE_AABBS)
+       {
+               std::vector<tcu::UVec2> aabbs;
+               std::vector<tcu::Vec2>  vertices;
+
+               vertices.reserve(2u * testParams.squaresGroupCount);
+               aabbs.reserve(testParams.squaresGroupCount);
+
+               {
+                       // a---g---+
+                       // |   |   |
+                       // e---d---h
+                       // |   |   |
+                       // +---f---b
+                       //
+                       // a-d, d-b, e-f, g-h
+
+                       const tcu::Vec2         d       = centerPixelCenter;
+                       const tcu::Vec2         a       = tcu::Vec2(0.0f, 0.0f);
+                       const tcu::Vec2         b       = tcu::Vec2(1.0f, 1.0f);
+                       const tcu::Vec2         e       = tcu::Vec2(a.x(), d.y());
+                       const tcu::Vec2         f       = tcu::Vec2(d.x(), b.y());
+                       const tcu::Vec2         g       = tcu::Vec2(d.x(), a.y());
+                       const tcu::Vec2         h       = tcu::Vec2(b.x(), d.y());
+                       const deUint32          A       = 0;
+                       const deUint32          B       = 1;
+                       const deUint32          D       = 2;
+                       const deUint32          E       = 3;
+                       const deUint32          F       = 4;
+                       const deUint32          G       = 5;
+                       const deUint32          H       = 6;
+
+                       vertices.push_back(a);
+                       vertices.push_back(b);
+                       vertices.push_back(d);
+                       vertices.push_back(e);
+                       vertices.push_back(f);
+                       vertices.push_back(g);
+                       vertices.push_back(h);
+
+                       aabbs.push_back(tcu::UVec2(A, D));
+                       aabbs.push_back(tcu::UVec2(D, B));
+                       aabbs.push_back(tcu::UVec2(E, F));
+                       aabbs.push_back(tcu::UVec2(G, H));
+               }
+
+               while (aabbs.size() < testParams.squaresGroupCount)
+               {
+                       // a-------+      a---g---+
+                       // |       |      |   |   |
+                       // |       |  ->  e---d---h
+                       // |       |      |   |   |
+                       // +-------b      +---f---b
+                       //
+                       // a-b        ->  a-d, d-b, e-f, g-h
+
+                       const deUint32          n               = chooseAABB(rng, vertices, aabbs);
+                       tcu::UVec2&                     t               = aabbs[n];
+                       const tcu::Vec2&        a               = vertices[t.x()];
+                       const tcu::Vec2&        b               = vertices[t.y()];
+                       const float                     alfa    = rng.getFloat(0.2f, 0.8f);
+                       const float                     beta    = rng.getFloat(0.2f, 0.8f);
+                       const tcu::Vec2         d               = mixCoordsVec2(a, b, alfa, beta);
+                       const tcu::Vec2         e               = tcu::Vec2(a.x(), d.y());
+                       const tcu::Vec2         f               = tcu::Vec2(d.x(), b.y());
+                       const tcu::Vec2         g               = tcu::Vec2(d.x(), a.y());
+                       const tcu::Vec2         h               = tcu::Vec2(b.x(), d.y());
+                       const deUint32          B               = t.y();
+                       const deUint32          D               = (deUint32)vertices.size();
+                       const deUint32          E               = D + 1;
+                       const deUint32          F               = D + 2;
+                       const deUint32          G               = D + 3;
+                       const deUint32          H               = D + 4;
+
+                       if (d.x() <= a.x() || d.x() >= b.x() || d.y() <= a.y() || d.y() >= b.y())
+                               continue;
+
+                       vertices.push_back(d);
+                       vertices.push_back(e);
+                       vertices.push_back(f);
+                       vertices.push_back(g);
+                       vertices.push_back(h);
+
+                       t.y() = D;
+                       aabbs.push_back(tcu::UVec2(D, B));
+                       aabbs.push_back(tcu::UVec2(E, F));
+                       aabbs.push_back(tcu::UVec2(G, H));
+               }
+
+               geometryData.reserve(2u * aabbs.size());
+
+               for (size_t i = 0; i < aabbs.size(); ++i)
+               {
+                       const tcu::Vec2&        a       = vertices[aabbs[i].x()];
+                       const tcu::Vec2&        b       = vertices[aabbs[i].y()];
+                       const float                     az      = -rng.getFloat(0.1f, 0.5f);
+                       const float                     bz      = az + 0.01f;
+                       const tcu::Vec3         A       = tcu::Vec3(a.x(), a.y(), az);
+                       const tcu::Vec3         B       = tcu::Vec3(b.x(), b.y(), bz);
+
+                       geometryData.push_back(A);
+                       geometryData.push_back(B);
+               }
+       }
+       else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
+       {
+               std::vector<tcu::UVec3> triangles;
+               std::vector<tcu::Vec2>  vertices;
+               std::vector<float>              verticesZ;
+
+               vertices.reserve(3u * testParams.squaresGroupCount);
+               triangles.reserve(testParams.squaresGroupCount);
+
+               {
+                       // Initial triangle set: aeb, bec, cef, fei, ieh, heg, ged, dea
+                       // e - is not math middle, but centrum of one of the pixels
+                       // a---b---c
+                       // | \ | / |
+                       // d---e---f
+                       // | / | \ |
+                       // g---h---i
+
+                       const tcu::Vec2         e       = centerPixelCenter;
+                       const tcu::Vec2         a       = tcu::Vec2( 0.0f,  0.0f);
+                       const tcu::Vec2         i       = tcu::Vec2( 1.0f,  1.0f);
+                       const tcu::Vec2         c       = tcu::Vec2(i.x(), a.y());
+                       const tcu::Vec2         g       = tcu::Vec2(a.x(), i.y());
+                       const tcu::Vec2         b       = tcu::Vec2(e.x(), a.y());
+                       const tcu::Vec2         d       = tcu::Vec2(a.x(), e.y());
+                       const tcu::Vec2         f       = tcu::Vec2(i.x(), e.y());
+                       const tcu::Vec2         h       = tcu::Vec2(e.x(), i.y());
+                       const deUint32          A       = 0;
+                       const deUint32          B       = 1;
+                       const deUint32          C       = 2;
+                       const deUint32          D       = 3;
+                       const deUint32          E       = 4;
+                       const deUint32          F       = 5;
+                       const deUint32          G       = 6;
+                       const deUint32          H       = 7;
+                       const deUint32          I       = 8;
+
+                       vertices.push_back(a);
+                       vertices.push_back(b);
+                       vertices.push_back(c);
+                       vertices.push_back(d);
+                       vertices.push_back(e);
+                       vertices.push_back(f);
+                       vertices.push_back(g);
+                       vertices.push_back(h);
+                       vertices.push_back(i);
+
+                       triangles.push_back(tcu::UVec3(A, E, B));
+                       triangles.push_back(tcu::UVec3(B, E, C));
+                       triangles.push_back(tcu::UVec3(C, E, F));
+                       triangles.push_back(tcu::UVec3(F, E, I));
+                       triangles.push_back(tcu::UVec3(I, E, H));
+                       triangles.push_back(tcu::UVec3(H, E, G));
+                       triangles.push_back(tcu::UVec3(G, E, D));
+                       triangles.push_back(tcu::UVec3(D, E, A));
+               }
+
+               while (triangles.size() < testParams.squaresGroupCount)
+               {
+                       const deUint32          n               = chooseTriangle(rng, vertices, triangles);
+                       tcu::UVec3&                     t               = triangles[n];
+                       const tcu::Vec2&        a               = vertices[t.x()];
+                       const tcu::Vec2&        b               = vertices[t.y()];
+                       const tcu::Vec2&        c               = vertices[t.z()];
+                       const float                     alfa    = rng.getFloat(0.2f, 0.8f);
+                       const float                     beta    = rng.getFloat(0.2f, 0.8f);
+                       const tcu::Vec2         d               = mixVec2(mixVec2(a, b, alfa), c, beta);
+                       const deUint32&         p               = t.x();
+                       const deUint32&         q               = t.y();
+                       deUint32&                       r               = t.z();
+                       const deUint32          R               = (deUint32)vertices.size();
+
+                       vertices.push_back(d);
+
+                       triangles.push_back(tcu::UVec3(q, r, R));
+                       triangles.push_back(tcu::UVec3(p, r, R));
+                       r = R;
+               }
+
+               verticesZ.reserve(vertices.size());
+               for (size_t i = 0; i < vertices.size(); ++i)
+                       verticesZ.push_back(-rng.getFloat(0.01f, 0.99f));
+
+               geometryData.reserve(3u * triangles.size());
+
+               for (size_t i = 0; i < triangles.size(); ++i)
+               {
+                       const deUint32  a = triangles[i].x();
+                       const deUint32  b = triangles[i].y();
+                       const deUint32  c = triangles[i].z();
+
+                       geometryData.push_back(tcu::Vec3(vertices[a].x(), vertices[a].y(), verticesZ[a]));
+                       geometryData.push_back(tcu::Vec3(vertices[b].x(), vertices[b].y(), verticesZ[b]));
+                       geometryData.push_back(tcu::Vec3(vertices[c].x(), vertices[c].y(), verticesZ[c]));
+               }
+       }
+       else
+       {
+               TCU_THROW(InternalError, "Unknown geometry type");
+       }
+
+       rayQueryBottomLevelAccelerationStructure->setGeometryCount(1u);
+       rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, testParams.geomType == GEOM_TYPE_TRIANGLES);
+       rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
+       m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
+       m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
+       m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back());
+       m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
+
+       return m_topAccelerationStructure.get()->getPtr();
+}
+
+bool TestConfigurationNoMiss::verify (BufferWithMemory*                                        resultBuffer,
+                                                                         Context&                                                      context,
+                                                                         TestParams&                                           testParams)
+{
+       tcu::TestLog&   log                     = context.getTestContext().getLog();
+       const deUint32  width           = testParams.width;
+       const deUint32  height          = testParams.height;
+       const deInt32*  resultPtr       = (deInt32*)resultBuffer->getAllocation().getHostPtr();
+       deUint32                failures        = 0;
+       deUint32                pos                     = 0;
+
+       for (deUint32 y = 0; y < height; ++y)
+       for (deUint32 x = 0; x < width; ++x)
+       {
+               if (resultPtr[pos] <= 0)
+                       failures++;
+
+               pos++;
+       }
+
+       if (failures != 0)
+       {
+               std::stringstream       css;
+
+               pos = 0;
+
+               for (deUint32 y = 0; y < height; ++y)
+               {
+                       for (deUint32 x = 0; x < width; ++x)
+                       {
+                               if (resultPtr[pos] <= 0)
+                                       css << std::setw(3) << resultPtr[pos] << ",";
+                               else
+                                       css << "___,";
+
+                               pos++;
+                       }
+
+                       css << std::endl;
+               }
+
+               log << tcu::TestLog::Message << "Retrieved:" << tcu::TestLog::EndMessage;
+               log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
+       }
+
+       return (failures == 0);
+}
+
+
+class TestConfigurationSingleHit : public TestConfigurationNoMiss
+{
+public:
+       virtual bool                                                            verify                                          (BufferWithMemory*                                      resultBuffer,
+                                                                                                                                                        Context&                                                       context,
+                                                                                                                                                        TestParams&                                            testParams) override;
+};
+
+bool TestConfigurationSingleHit::verify (BufferWithMemory*                                     resultBuffer,
+                                                                                Context&                                                       context,
+                                                                                TestParams&                                            testParams)
+{
+       tcu::TestLog&   log                             = context.getTestContext().getLog();
+       const deUint32  width                   = testParams.width;
+       const deUint32  height                  = testParams.height;
+       const deInt32*  resultPtr               = (deInt32*)resultBuffer->getAllocation().getHostPtr();
+       const deInt32   expectedValue   = 1;
+       deUint32                failures                = 0;
+       deUint32                pos                             = 0;
+
+       for (deUint32 y = 0; y < height; ++y)
+       for (deUint32 x = 0; x < width; ++x)
+       {
+               if (resultPtr[pos] != expectedValue)
+                       failures++;
+
+               pos++;
+       }
+
+       if (failures != 0)
+       {
+               std::stringstream       css;
+
+               pos = 0;
+
+               for (deUint32 y = 0; y < height; ++y)
+               {
+                       for (deUint32 x = 0; x < width; ++x)
+                       {
+                               if (resultPtr[pos] != expectedValue)
+                                       css << std::setw(3) << resultPtr[pos] << ",";
+                               else
+                                       css << "___,";
+
+                               pos++;
+                       }
+
+                       css << std::endl;
+               }
+
+               log << tcu::TestLog::Message << "Retrieved:" << tcu::TestLog::EndMessage;
+               log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
+       }
+
+       return (failures == 0);
+}
+
+
+class RayQueryBuiltinTestInstance : public TestInstance
+{
+public:
+                                                                               RayQueryBuiltinTestInstance             (Context& context, const TestParams& data);
+       virtual                                                         ~RayQueryBuiltinTestInstance    (void);
+       tcu::TestStatus                                         iterate                                                 (void);
+
+private:
+       TestParams                                                      m_data;
+       de::MovePtr<TestConfiguration>          m_testConfig;
+       de::MovePtr<PipelineConfiguration>      m_pipelineConfig;
+};
+
+RayQueryBuiltinTestInstance::RayQueryBuiltinTestInstance (Context& context, const TestParams& data)
+       : vkt::TestInstance             (context)
+       , m_data                                (data)
+{
+       switch (m_data.testType)
+       {
+               case TEST_TYPE_NO_MISS:         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationNoMiss());           break;
+               case TEST_TYPE_SINGLE_HIT:      m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationSingleHit());        break;
+               default: TCU_THROW(InternalError, "Unknown test type");
+       }
+
+       switch (m_data.stage)
+       {
+               case VK_SHADER_STAGE_VERTEX_BIT:
+               case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
+               case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
+               case VK_SHADER_STAGE_GEOMETRY_BIT:
+               case VK_SHADER_STAGE_FRAGMENT_BIT:
+               {
+                       m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new GraphicsConfiguration());
+                       break;
+               }
+
+               case VK_SHADER_STAGE_COMPUTE_BIT:
+               {
+                       m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new ComputeConfiguration());
+                       break;
+               }
+
+               case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
+               case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
+               case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
+               case VK_SHADER_STAGE_MISS_BIT_KHR:
+               case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
+               case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
+               {
+                       m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new RayTracingConfiguration());
+                       break;
+               }
+
+               default:
+                       TCU_THROW(InternalError, "Unknown shader stage");
+       }
+}
+
+RayQueryBuiltinTestInstance::~RayQueryBuiltinTestInstance (void)
+{
+}
+
+tcu::TestStatus RayQueryBuiltinTestInstance::iterate (void)
+{
+       const DeviceInterface&                          vkd                                                                     = m_context.getDeviceInterface();
+       const VkDevice                                          device                                                          = m_context.getDevice();
+       const VkQueue                                           queue                                                           = m_context.getUniversalQueue();
+       Allocator&                                                      allocator                                                       = m_context.getDefaultAllocator();
+       const deUint32                                          queueFamilyIndex                                        = m_context.getUniversalQueueFamilyIndex();
+
+       const deUint32                                          width                                                           = m_data.width;
+       const deUint32                                          height                                                          = m_data.height;
+       const deUint32                                          depth                                                           = m_data.depth;
+       const VkPipelineStageFlags                      pipelineStageFlags                                      = ALL_RAY_TRACING_STAGES;
+       const VkImageCreateInfo                         imageCreateInfo                                         = makeImageCreateInfo(m_data.format, width, height, depth);
+       const VkImageSubresourceRange           imageSubresourceRange                           = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
+       const de::MovePtr<ImageWithMemory>      image                                                           = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
+       const Move<VkImageView>                         imageView                                                       = makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, m_data.format, imageSubresourceRange);
+
+       const deUint32                                          pixelSize                                                       = mapVkFormat(m_data.format).getPixelSize();
+       const VkBufferCreateInfo                        resultBufferCreateInfo                          = makeBufferCreateInfo(width * height * depth * pixelSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
+       const VkImageSubresourceLayers          resultBufferImageSubresourceLayers      = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
+       const VkBufferImageCopy                         resultBufferImageRegion                         = makeBufferImageCopy(makeExtent3D(width, height, depth), resultBufferImageSubresourceLayers);
+       de::MovePtr<BufferWithMemory>           resultBuffer                                            = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
+
+       const VkDescriptorImageInfo                     resultImageInfo                                         = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
+
+       const Move<VkCommandPool>                       cmdPool                                                         = createCommandPool(vkd, device, 0, queueFamilyIndex);
+       const Move<VkCommandBuffer>                     cmdBuffer                                                       = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+       const VkAccelerationStructureKHR*       topAccelerationStructurePtr                     = DE_NULL;
+
+       m_pipelineConfig->initConfiguration(m_context, m_data);
+
+       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);
+               const VkClearValue                      clearValue                              = makeClearValueColorU32(0u, 0u, 0u, 0u);
+               const VkImageMemoryBarrier      postImageBarrier                = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, **image, imageSubresourceRange);
+               const VkMemoryBarrier           postTestMemoryBarrier   = makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
+
+               cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
+               vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
+               cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, pipelineStageFlags, &postImageBarrier);
+
+               topAccelerationStructurePtr = m_testConfig->initAccelerationStructures(m_context, m_data, *cmdBuffer);
+
+               m_pipelineConfig->fillCommandBuffer(m_context, m_data, *cmdBuffer, topAccelerationStructurePtr, resultImageInfo);
+
+               cmdPipelineMemoryBarrier(vkd, *cmdBuffer, pipelineStageFlags, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTestMemoryBarrier);
+
+               vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
+       }
+       endCommandBuffer(vkd, *cmdBuffer);
+
+       submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
+
+       invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
+
+       if (m_testConfig->verify(resultBuffer.get(), m_context, m_data))
+               return tcu::TestStatus::pass("Pass");
+       else
+               return tcu::TestStatus::fail("Fail");
+}
+
+class RayQueryBuiltinTestCase : public TestCase
+{
+       public:
+                                                       RayQueryBuiltinTestCase         (tcu::TestContext& context, const char* name, const char* desc, const TestParams data);
+                                                       ~RayQueryBuiltinTestCase        (void);
+
+       virtual void                    checkSupport                            (Context& context) const;
+       virtual void                    initPrograms                            (SourceCollections& programCollection) const;
+       virtual TestInstance*   createInstance                          (Context& context) const;
+
+private:
+       TestParams                              m_data;
+};
+
+RayQueryBuiltinTestCase::RayQueryBuiltinTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams data)
+       : vkt::TestCase (context, name, desc)
+       , m_data                (data)
+{
+}
+
+RayQueryBuiltinTestCase::~RayQueryBuiltinTestCase (void)
+{
+}
+
+void RayQueryBuiltinTestCase::checkSupport (Context& context) const
+{
+       context.requireDeviceFunctionality(getRayTracingExtensionUsed());
+
+       const VkPhysicalDeviceRayTracingFeaturesKHR&    rayTracingFeaturesKHR = context.getRayTracingFeatures();
+
+       if (rayTracingFeaturesKHR.rayQuery == DE_FALSE)
+               TCU_THROW(NotSupportedError, "Requires rayTracingFeaturesKHR.rayQuery");
+
+       m_data.pipelineCheckSupport(context, m_data);
+}
+
+TestInstance* RayQueryBuiltinTestCase::createInstance (Context& context) const
+{
+       return new RayQueryBuiltinTestInstance(context, m_data);
+}
+
+void RayQueryBuiltinTestCase::initPrograms (SourceCollections& programCollection) const
+{
+       m_data.pipelineInitPrograms(programCollection, m_data);
+}
+
+static inline CheckSupportFunc getPipelineCheckSupport (const VkShaderStageFlagBits stage)
+{
+       switch (stage)
+       {
+               case VK_SHADER_STAGE_VERTEX_BIT:
+               case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
+               case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
+               case VK_SHADER_STAGE_GEOMETRY_BIT:
+               case VK_SHADER_STAGE_FRAGMENT_BIT:
+                       return GraphicsConfiguration::checkSupport;
+
+               case VK_SHADER_STAGE_COMPUTE_BIT:
+                       return ComputeConfiguration::checkSupport;
+
+               case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
+               case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
+               case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
+               case VK_SHADER_STAGE_MISS_BIT_KHR:
+               case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
+               case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
+                       return RayTracingConfiguration::checkSupport;
+
+               default:
+                       TCU_THROW(InternalError, "Unknown shader stage");
+       }
+}
+
+static inline InitProgramsFunc getPipelineInitPrograms (const VkShaderStageFlagBits stage)
+{
+       switch (stage)
+       {
+               case VK_SHADER_STAGE_VERTEX_BIT:
+               case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
+               case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
+               case VK_SHADER_STAGE_GEOMETRY_BIT:
+               case VK_SHADER_STAGE_FRAGMENT_BIT:
+                       return GraphicsConfiguration::initPrograms;
+
+               case VK_SHADER_STAGE_COMPUTE_BIT:
+                       return ComputeConfiguration::initPrograms;
+
+               case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
+               case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
+               case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
+               case VK_SHADER_STAGE_MISS_BIT_KHR:
+               case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
+               case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
+                       return RayTracingConfiguration::initPrograms;
+
+               default:
+                       TCU_THROW(InternalError, "Unknown shader stage");
+       }
+}
+
+static inline ShaderBodyTextFunc getShaderBodyTextFunc (const TestType testType)
+{
+       switch (testType)
+       {
+               case TEST_TYPE_NO_MISS:         return getShaderBodyText;       break;
+               case TEST_TYPE_SINGLE_HIT:      return getShaderBodyText;       break;
+               default:                                        TCU_THROW(InternalError, "Unknown test type");
+       }
+}
+
+}      // anonymous
+
+tcu::TestCaseGroup*    createWatertightnessTests       (tcu::TestContext& testCtx)
+{
+       const deUint32                                  seed    = (deUint32)(testCtx.getCommandLine().getBaseSeed());
+       de::MovePtr<tcu::TestCaseGroup> group   (new tcu::TestCaseGroup(testCtx, "watertightness", "Tests watertightness of ray query"));
+
+       const struct PipelineStages
+       {
+               VkShaderStageFlagBits   stage;
+               const char*                             name;
+       }
+       pipelineStages[] =
+       {
+               { VK_SHADER_STAGE_VERTEX_BIT,                                   "vert"                  },
+               { VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,             "tesc"                  },
+               { VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,  "tese"                  },
+               { VK_SHADER_STAGE_GEOMETRY_BIT,                                 "geom"                  },
+               { VK_SHADER_STAGE_FRAGMENT_BIT,                                 "frag"                  },
+               { VK_SHADER_STAGE_COMPUTE_BIT,                                  "comp"                  },
+               { VK_SHADER_STAGE_RAYGEN_BIT_KHR,                               "rgen"                  },
+               { VK_SHADER_STAGE_ANY_HIT_BIT_KHR,                              "ahit"                  },
+               { VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,                  "chit"                  },
+               { VK_SHADER_STAGE_MISS_BIT_KHR,                                 "miss"                  },
+               { VK_SHADER_STAGE_INTERSECTION_BIT_KHR,                 "sect"                  },
+               { VK_SHADER_STAGE_CALLABLE_BIT_KHR,                             "call"                  },
+       };
+       const struct TestTypes
+       {
+               TestType        testType;
+               const char*     name;
+       }
+       testTypes[] =
+       {
+               { TEST_TYPE_NO_MISS,                                                    "nomiss"                },
+               { TEST_TYPE_SINGLE_HIT,                                                 "singlehit"             },
+       };
+       const struct GeomTypes
+       {
+               GeomType        geomType;
+               const char*     name;
+       }
+       geomTypes[] =
+       {
+               { GEOM_TYPE_TRIANGLES,                                                  "triangles"             },
+               { GEOM_TYPE_AABBS,                                                              "aabbs"                 },
+       };
+
+       for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
+       {
+               de::MovePtr<tcu::TestCaseGroup> testTypeGroup           (new tcu::TestCaseGroup(group->getTestContext(), testTypes[testTypeNdx].name, ""));
+               const TestType                                  testType                        = testTypes[testTypeNdx].testType;
+               const ShaderBodyTextFunc                shaderBodyTextFunc      = getShaderBodyTextFunc(testType);
+               const deUint32                                  imageDepth                      = 1;
+
+               for (size_t pipelineStageNdx = 0; pipelineStageNdx < DE_LENGTH_OF_ARRAY(pipelineStages); ++pipelineStageNdx)
+               {
+                       de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup                 (new tcu::TestCaseGroup(group->getTestContext(), pipelineStages[pipelineStageNdx].name, ""));
+                       const VkShaderStageFlagBits             stage                                   = pipelineStages[pipelineStageNdx].stage;
+                       const CheckSupportFunc                  pipelineCheckSupport    = getPipelineCheckSupport(stage);
+                       const InitProgramsFunc                  pipelineInitPrograms    = getPipelineInitPrograms(stage);
+                       const deUint32                                  instancesGroupCount             = 1;
+                       const deUint32                                  geometriesGroupCount    = 1;
+                       const deUint32                                  squaresGroupCount               = (TEST_WIDTH * TEST_HEIGHT) / geometriesGroupCount / instancesGroupCount;
+
+                       DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == TEST_WIDTH * TEST_HEIGHT);
+
+                       for (size_t geomTypeNdx = 0; geomTypeNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypeNdx)
+                       {
+                               const GeomType          geomType        = geomTypes[geomTypeNdx].geomType;
+                               const TestParams        testParams      =
+                               {
+                                       TEST_WIDTH,                             //  deUint32                            width;
+                                       TEST_HEIGHT,                    //  deUint32                            height;
+                                       imageDepth,                             //  deUint32                            depth;
+                                       seed,                                   //  deUint32                            randomSeed;
+                                       testType,                               //  TestType                            testType;
+                                       stage,                                  //  VkShaderStageFlagBits       stage;
+                                       geomType,                               //  GeomType                            geomType;
+                                       squaresGroupCount,              //  deUint32                            squaresGroupCount;
+                                       geometriesGroupCount,   //  deUint32                            geometriesGroupCount;
+                                       instancesGroupCount,    //  deUint32                            instancesGroupCount;
+                                       VK_FORMAT_R32_SINT,             //  VkFormat                            format;
+                                       pipelineCheckSupport,   //  CheckSupportFunc            pipelineCheckSupport;
+                                       pipelineInitPrograms,   //  InitProgramsFunc            pipelineInitPrograms;
+                                       shaderBodyTextFunc,             //  ShaderTestTextFunc          testConfigShaderBodyText;
+                               };
+
+                               if (testType == TEST_TYPE_SINGLE_HIT && geomType == GEOM_TYPE_AABBS)
+                                       continue;
+
+                               sourceTypeGroup->addChild(new RayQueryBuiltinTestCase(group->getTestContext(), geomTypes[geomTypeNdx].name, "", testParams));
+                       }
+
+                       testTypeGroup->addChild(sourceTypeGroup.release());
+               }
+
+               group->addChild(testTypeGroup.release());
+       }
+
+       return group.release();
+}
+
+}      // RayQuery
+}      // vkt
diff --git a/external/vulkancts/modules/vulkan/ray_query/vktRayQueryWatertightnessTests.hpp b/external/vulkancts/modules/vulkan/ray_query/vktRayQueryWatertightnessTests.hpp
new file mode 100644 (file)
index 0000000..c7af644
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _VKTRAYQUERYWATERTIGHTNESSTESTS_HPP
+#define _VKTRAYQUERYWATERTIGHTNESSTESTS_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 Query Watertightness tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tcuTestCase.hpp"
+
+namespace vkt
+{
+namespace RayQuery
+{
+
+tcu::TestCaseGroup*    createWatertightnessTests       (tcu::TestContext& testCtx);
+
+} // RayQuery
+} // vkt
+
+#endif // _VKTRAYQUERYWATERTIGHTNESSTESTS_HPP
index 84f4281..2bbef80 100644 (file)
@@ -642061,3 +642061,39 @@ dEQP-VK.ray_query.advanced.null_as.sect.triangles
 dEQP-VK.ray_query.advanced.null_as.sect.aabbs
 dEQP-VK.ray_query.advanced.null_as.call.triangles
 dEQP-VK.ray_query.advanced.null_as.call.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.vert.triangles
+dEQP-VK.ray_query.watertightness.nomiss.vert.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.tesc.triangles
+dEQP-VK.ray_query.watertightness.nomiss.tesc.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.tese.triangles
+dEQP-VK.ray_query.watertightness.nomiss.tese.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.geom.triangles
+dEQP-VK.ray_query.watertightness.nomiss.geom.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.frag.triangles
+dEQP-VK.ray_query.watertightness.nomiss.frag.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.comp.triangles
+dEQP-VK.ray_query.watertightness.nomiss.comp.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.rgen.triangles
+dEQP-VK.ray_query.watertightness.nomiss.rgen.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.ahit.triangles
+dEQP-VK.ray_query.watertightness.nomiss.ahit.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.chit.triangles
+dEQP-VK.ray_query.watertightness.nomiss.chit.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.miss.triangles
+dEQP-VK.ray_query.watertightness.nomiss.miss.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.sect.triangles
+dEQP-VK.ray_query.watertightness.nomiss.sect.aabbs
+dEQP-VK.ray_query.watertightness.nomiss.call.triangles
+dEQP-VK.ray_query.watertightness.nomiss.call.aabbs
+dEQP-VK.ray_query.watertightness.singlehit.vert.triangles
+dEQP-VK.ray_query.watertightness.singlehit.tesc.triangles
+dEQP-VK.ray_query.watertightness.singlehit.tese.triangles
+dEQP-VK.ray_query.watertightness.singlehit.geom.triangles
+dEQP-VK.ray_query.watertightness.singlehit.frag.triangles
+dEQP-VK.ray_query.watertightness.singlehit.comp.triangles
+dEQP-VK.ray_query.watertightness.singlehit.rgen.triangles
+dEQP-VK.ray_query.watertightness.singlehit.ahit.triangles
+dEQP-VK.ray_query.watertightness.singlehit.chit.triangles
+dEQP-VK.ray_query.watertightness.singlehit.miss.triangles
+dEQP-VK.ray_query.watertightness.singlehit.sect.triangles
+dEQP-VK.ray_query.watertightness.singlehit.call.triangles