Ray query helper invocations
authormichal_jakubek <michal.jakubek@mobica.com>
Wed, 9 Feb 2022 00:01:03 +0000 (01:01 +0100)
committerMatthew Netsch <quic_mnetsch@quicinc.com>
Thu, 14 Apr 2022 19:03:09 +0000 (19:03 +0000)
New tests:
dEQP-VK.ray_query.helper_invocations.*

Components: Vulkan

VK-GL-CTS issue: 3254

Change-Id: I2f62c4eb2dea21184587c086768297322a3f45d8

android/cts/main/vk-master-2022-03-01/ray-query.txt
android/cts/main/vk-master/ray-query.txt
external/vulkancts/modules/vulkan/ray_query/vktRayQueryMiscTests.cpp
external/vulkancts/modules/vulkan/ray_query/vktRayQueryMiscTests.hpp
external/vulkancts/modules/vulkan/ray_query/vktRayQueryTests.cpp
external/vulkancts/mustpass/main/vk-default/ray-query.txt

index ea7aa01..86f8f47 100644 (file)
@@ -125,3 +125,75 @@ dEQP-VK.ray_query.non_uniform_args.miss_cause_3
 dEQP-VK.ray_query.non_uniform_args.miss_cause_4
 dEQP-VK.ray_query.non_uniform_args.miss_cause_5
 dEQP-VK.ray_query.non_uniform_args.miss_cause_6
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.cubic_quadratic.32x64.64x32
index 2bb070f..97237ad 100644 (file)
@@ -23426,3 +23426,75 @@ dEQP-VK.ray_query.non_uniform_args.miss_cause_3
 dEQP-VK.ray_query.non_uniform_args.miss_cause_4
 dEQP-VK.ray_query.non_uniform_args.miss_cause_5
 dEQP-VK.ray_query.non_uniform_args.miss_cause_6
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.cubic_quadratic.32x64.64x32
index d0a1f5e..5251f1a 100644 (file)
 #include "vkTypeUtil.hpp"
 #include "vkCmdUtil.hpp"
 #include "vkBarrierUtil.hpp"
+#include "vkImageWithMemory.hpp"
+#include "vkImageUtil.hpp"
 
 #include "tcuVector.hpp"
+#include "tcuStringTemplate.hpp"
+#include "tcuTextureUtil.hpp"
 
 #include "deUniquePtr.hpp"
 #include "deRandom.hpp"
@@ -41,6 +45,7 @@
 #include <sstream>
 #include <limits>
 #include <vector>
+#include <map>
 
 namespace vkt
 {
@@ -344,8 +349,738 @@ tcu::TestStatus DynamicIndexingInstance::iterate (void)
        return tcu::TestStatus::pass("Pass");
 }
 
+using namespace tcu;
+
+struct HelperInvocationsParamDefs
+{
+       enum DfStyle
+       {
+               Regular,
+               Coarse,
+               Fine
+       };
+
+       enum FuncType
+       {
+               LINEAR,
+               QUADRATIC,
+               CUBIC
+       };
+
+       typedef float (*F1D)(float);
+       struct func2D_t {
+               F1D                     first;
+               F1D                     second;
+       };
+       struct func2D_mask {
+               FuncType        first;
+               FuncType        second;
+       };
+       struct test_mode_t {
+               func2D_t        funcs;
+               func2D_mask     types;
+       };
+
+       static float linear(float x)    { return x; }
+       static float quadratic(float x) { return (x * x); }
+       static float cubic(float x)             { return (x * x * x * 0.5f); }
+
+       static float combine(const func2D_t& f2D, float x, float y)
+       {
+               DE_ASSERT( (f2D.first) && (f2D.second) );
+               const float z = ((*f2D.first)(x) + (*f2D.second)(y)) / 2.0f;
+               return z;
+       }
+
+       static constexpr func2D_t FUNC_LINEAR_QUADRATIC                 = { linear,             quadratic       };
+       static constexpr func2D_t FUNC_LINEAR_CUBIC                             = { linear,             cubic           };
+       static constexpr func2D_t FUNC_CUBIC_QUADRATIC                  = { cubic,              quadratic       };
+       #ifdef ENABLE_ALL_HELPER_COMBINATIONS
+       static constexpr func2D_t FUNC_LINEAR_LINEAR                    = { linear,             linear          };
+       static constexpr func2D_t FUNC_QUADRATIC_LINEAR                 = { quadratic,  linear          };
+       static constexpr func2D_t FUNC_QUADRATIC_QUADRATIC              = { quadratic,  quadratic       };
+       static constexpr func2D_t FUNC_QUADRATIC_CUBIC                  = { quadratic,  cubic           };
+       static constexpr func2D_t FUNC_CUBIC_LINEAR                             = { cubic,              linear          };
+       static constexpr func2D_t FUNC_CUBIC_CUBIC                              = { cubic,              cubic           };
+       #endif
+
+       static constexpr func2D_mask MASK_LINEAR_QUADRATIC              = { LINEAR,             QUADRATIC       };
+       static constexpr func2D_mask MASK_LINEAR_CUBIC                  = { LINEAR,             CUBIC           };
+       static constexpr func2D_mask MASK_CUBIC_QUADRATIC               = { CUBIC,              QUADRATIC       };
+       #ifdef ENABLE_ALL_HELPER_COMBINATIONS
+       static constexpr func2D_mask MASK_LINEAR_LINEAR                 = { LINEAR,             LINEAR          };
+       static constexpr func2D_mask MASK_QUADRATIC_LINEAR              = { QUADRATIC,  LINEAR          };
+       static constexpr func2D_mask MASK_QUADRATIC_QUADRATIC   = { QUADRATIC,  QUADRATIC       };
+       static constexpr func2D_mask MASK_QUADRATIC_CUBIC               = { QUADRATIC,  CUBIC           };
+       static constexpr func2D_mask MASK_CUBIC_LINEAR                  = { CUBIC,              LINEAR          };
+       static constexpr func2D_mask MASK_CUBIC_CUBIC                   = { CUBIC,              CUBIC           };
+       #endif
+
+       static constexpr test_mode_t MODE_LINEAR_QUADRATIC              = { FUNC_LINEAR_QUADRATIC,              MASK_LINEAR_QUADRATIC   };
+       static constexpr test_mode_t MODE_LINEAR_CUBIC                  = { FUNC_LINEAR_CUBIC,                  MASK_LINEAR_CUBIC               };
+       static constexpr test_mode_t MODE_CUBIC_QUADRATIC               = { FUNC_CUBIC_QUADRATIC,               MASK_CUBIC_QUADRATIC    };
+       #ifdef ENABLE_ALL_HELPER_COMBINATIONS
+       static constexpr test_mode_t MODE_LINEAR_LINEAR                 = { FUNC_LINEAR_LINEAR,                 MASK_LINEAR_LINEAR              };
+       static constexpr test_mode_t MODE_QUADRATIC_LINEAR              = { FUNC_QUADRATIC_LINEAR,              MASK_QUADRATIC_LINEAR   };
+       static constexpr test_mode_t MODE_QUADRATIC_QUADRATIC   = { FUNC_QUADRATIC_QUADRATIC,   MASK_QUADRATIC_QUADRATIC};
+       static constexpr test_mode_t MODE_QUADRATIC_CUBIC               = { FUNC_QUADRATIC_CUBIC,               MASK_QUADRATIC_CUBIC    };
+       static constexpr test_mode_t MODE_CUBIC_LINEAR                  = { FUNC_CUBIC_LINEAR,                  MASK_CUBIC_LINEAR               };
+       static constexpr test_mode_t MODE_CUBIC_CUBIC                   = { FUNC_CUBIC_CUBIC,                   MASK_CUBIC_CUBIC                };
+       #endif
+};
+
+constexpr HelperInvocationsParamDefs::test_mode_t HelperInvocationsParamDefs::MODE_LINEAR_QUADRATIC;
+constexpr HelperInvocationsParamDefs::test_mode_t HelperInvocationsParamDefs::MODE_LINEAR_CUBIC;
+constexpr HelperInvocationsParamDefs::test_mode_t HelperInvocationsParamDefs::MODE_CUBIC_QUADRATIC;
+#ifdef ENABLE_ALL_HELPER_COMBINATIONS
+constexpr HelperInvocationsParamDefs::test_mode_t HelperInvocationsParamDefs::MODE_LINEAR_LINEAR;
+constexpr HelperInvocationsParamDefs::test_mode_t HelperInvocationsParamDefs::MODE_QUADRATIC_LINEAR;
+constexpr HelperInvocationsParamDefs::test_mode_t HelperInvocationsParamDefs::MODE_QUADRATIC_QUADRATIC;
+constexpr HelperInvocationsParamDefs::test_mode_t HelperInvocationsParamDefs::MODE_QUADRATIC_CUBIC;
+constexpr HelperInvocationsParamDefs::test_mode_t HelperInvocationsParamDefs::MODE_CUBIC_LINEAR;
+constexpr HelperInvocationsParamDefs::test_mode_t HelperInvocationsParamDefs::MODE_CUBIC_CUBIC;
+#endif
+
+struct HelperInvocationsParams : HelperInvocationsParamDefs
+{
+       test_mode_t                                             mode;
+       std::pair<deUint32, deUint32>   screen;
+       std::pair<deUint32, deUint32>   model;
+       DfStyle                                                 style;
+       bool                                                    buildGPU;
+};
+
+class HelperInvocationsCase : public TestCase
+{
+public:
+       HelperInvocationsCase                                   (TestContext&                                   testCtx,
+                                                                                        const HelperInvocationsParams& params,
+                                                                                        const std::string&                             name);
+       virtual void                    initPrograms    (SourceCollections&                             programs) const override;
+       virtual TestInstance*   createInstance  (Context&                                               context) const override;
+       virtual void                    checkSupport    (Context&                                               context) const override;
+
+private:
+       HelperInvocationsParams m_params;
+};
+
+class HelperInvocationsInstance : public TestInstance
+{
+public:
+       typedef de::MovePtr<TopLevelAccelerationStructure> TopLevelAccelerationStructurePtr;
+       enum Points {
+               Vertices,
+               Coords,
+               Centers
+       };
+
+       HelperInvocationsInstance                               (Context&                                                                       context,
+                                                                                        const HelperInvocationsParams&                         params);
+       virtual TestStatus              iterate                 (void) override;
+       static  auto                    createSurface   (const Points                                                           points,
+                                                                                        const deUint32                                                         divX,
+                                                                                        const deUint32                                                         divY,
+                                                                                        const HelperInvocationsParams::func2D_t&       f2D,
+                                                                                        bool                                                                           clockWise = false) -> std::vector<Vec3>;
+       VkImageCreateInfo               makeImgInfo             (deUint32                                                                       queueFamilyIndexCount,
+                                                                                        const deUint32*                                                        pQueueFamilyIndices) const;
+       Move<VkPipeline>                makePipeline    (const DeviceInterface&                                         vk,
+                                                                                        const VkDevice                                                         device,
+                                                                                        const VkPipelineLayout                                         pipelineLayout,
+                                                                                        const VkShaderModule                                           vertexShader,
+                                                                                        const VkShaderModule                                           fragmentShader,
+                                                                                        const VkRenderPass                                                     renderPass) const;
+       auto                                    makeResultBuff  (const DeviceInterface&                                         vk,
+                                                                                        const VkDevice                                                         device,
+                                                                                        Allocator&                                                                     allocator) const -> de::MovePtr<BufferWithMemory>;
+       auto                                    makeAttribBuff  (const DeviceInterface&                                         vk,
+                                                                                        const VkDevice                                                         device,
+                                                                                        Allocator&                                                                     allocator,
+                                                                                        const std::vector<Vec3>&                                       vertices,
+                                                                                        const std::vector<Vec3>&                                       coords,
+                                                                                        const std::vector<Vec3>&                                       centers) const -> de::MovePtr<BufferWithMemory>;
+       auto                                    createAccStructs(const DeviceInterface&                                         vk,
+                                                                                        const VkDevice                                                         device,
+                                                                                        Allocator&                                                                     allocator,
+                                                                                        const VkCommandBuffer                                          cmdBuffer,
+                                                                                        const std::vector<Vec3>                                        coords) const -> TopLevelAccelerationStructurePtr;
+protected:
+       bool                                    verifyResult    (const DeviceInterface&                                         vk,
+                                                                                        const VkDevice                                                         device,
+                                                                                        const BufferWithMemory&                                        buffer) const;
+       bool onlyPipeline();
+private:
+       VkFormat                                m_format;
+       HelperInvocationsParams m_params;
+};
+
+HelperInvocationsCase::HelperInvocationsCase (TestContext&                                             testCtx,
+                                                                                         const HelperInvocationsParams&        params,
+                                                                                         const std::string&                            name)
+       : TestCase      (testCtx, name, std::string())
+       , m_params      (params)
+{
+}
+
+TestInstance* HelperInvocationsCase::createInstance (Context& context) const
+{
+       return new HelperInvocationsInstance(context, m_params);
+}
+
+void HelperInvocationsCase::checkSupport (Context& context) const
+{
+       context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
+       context.requireDeviceFunctionality("VK_KHR_ray_query");
+
+       const auto& rayQueryFeaturesKHR                                 = context.getRayQueryFeatures();
+       const auto& accelerationStructureFeaturesKHR    = context.getAccelerationStructureFeatures();
+
+       if (!rayQueryFeaturesKHR.rayQuery)
+               TCU_THROW(NotSupportedError, "Ray queries not supported");
+
+       if (!accelerationStructureFeaturesKHR.accelerationStructure)
+               TCU_THROW(NotSupportedError, "Acceleration structures not supported but ray queries supported");
+
+       if (m_params.buildGPU == false && accelerationStructureFeaturesKHR.accelerationStructureHostCommands == DE_FALSE)
+               TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceAccelerationStructureFeaturesKHR::accelerationStructureHostCommands");
+}
+
+void HelperInvocationsCase::initPrograms (SourceCollections& programs) const
+{
+       const ShaderBuildOptions buildOptions(programs.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
+
+       std::string vertexCode (
+       R"(
+       #version 460
+       #extension GL_EXT_ray_query : require
+       #extension GL_EXT_ray_tracing : require
+
+       layout(location = 0) in vec3 pos;
+       layout(location = 1) in vec3 inCoord;
+       layout(location = 2) in vec3 inCenter;
+       layout(location = 0) out vec3 outCoord;
+       layout(location = 1) out vec3 outCenter;
+
+       void main()
+       {
+               gl_PointSize = 1.0;
+               gl_Position = vec4(pos.xyz, 1.0);
+               outCoord = inCoord;
+               outCenter = inCenter;
+       }
+       )");
+       programs.glslSources.add("vert") << glu::VertexSource(vertexCode) << buildOptions;
+
+       StringTemplate fragmentCode(
+       R"(
+       #version 460
+       #extension GL_EXT_ray_query : require
+       #extension GL_EXT_ray_tracing : require
+
+       #define LINEAR    0
+       #define QUADRATIC 1
+       #define CUBIC     2
+
+       layout(push_constant) uniform PC {
+               int fun_x;
+               int fun_y;
+               float width;
+               float height;
+       } params;
+       layout(location = 0) in vec3 coord;
+       layout(location = 1) in vec3 center;
+       layout(location = 0) out vec4 color;
+       layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;
+
+       float d_linear   (in float t) { return 0.5; }                   // (x/2)'
+       float d_quadratic(in float t) { return t; }                             // (x^2/2)'
+       float d_cubic    (in float t) { return 0.75 * t * t; }  // (x^3/4)'
+
+       float derivate(in int fun, in float u)
+       {
+               switch (fun)
+               {
+                       case LINEAR:    return d_linear(u);
+                       case QUADRATIC: return d_quadratic(u);
+                       case CUBIC:             return d_cubic(u);
+               }
+               return -1.0;
+       }
+       void main()
+       {
+               const uint rayFlags     = 0u;
+               const uint cullMask     = 0xFFu;
+               const float tmin        = 0.0;
+               const float tmax        = 10.0;
+               const vec3 direct       = vec3(0.0, 0.0, 1.0);
+               const vec3 origin       = vec3(center.x, center.y, -1.0);
+
+               rayQueryEXT query;
+               rayQueryInitializeEXT(query, topLevelAS, rayFlags, cullMask, origin, tmin, direct, tmax);
+
+               color = vec4(-1.0, -1.0, -1.0, -1.0);
+
+               while (rayQueryProceedEXT(query)) {
+                       if (rayQueryGetIntersectionTypeEXT(query, false)
+                               == gl_RayQueryCandidateIntersectionTriangleEXT)
+                       {
+                               float vx = derivate(params.fun_x, coord.x);
+                               float vy = derivate(params.fun_y, coord.y);
+                               float dx = ${DFDX}(coord.x);
+                               float dy = ${DFDY}(coord.y);
+                               float dzx = ${DFDX}(coord.z);
+                               float dzy = ${DFDY}(coord.z);
+                               float dfx = dzx / dx;
+                               float dfy = dzy / dy;
+                               float cx = dfx - vx;
+                               float cy = dfy - vy;
+
+                               color = vec4(cx, cy, sign(dx-abs(cx)), sign(dy-abs(cy)));
+                       }
+                       else
+                       {
+                               color = vec4(0.0, 0.0, -1.0, -1.0);
+                       }
+                       rayQueryConfirmIntersectionEXT(query);
+               }
+       })");
+
+       std::map<std::string, std::string> m;
+       switch (m_params.style)
+       {
+       case HelperInvocationsParams::DfStyle::Regular:
+               m["DFDX"] = "dFdx";
+               m["DFDY"] = "dFdy";
+               break;
+       case HelperInvocationsParams::DfStyle::Coarse:
+               m["DFDX"] = "dFdxCoarse";
+               m["DFDY"] = "dFdyCoarse";
+               break;
+       case HelperInvocationsParams::DfStyle::Fine:
+               m["DFDX"] = "dFdxFine";
+               m["DFDY"] = "dFdyFine";
+               break;
+       }
+
+       programs.glslSources.add("frag") << glu::FragmentSource(fragmentCode.specialize(m)) << buildOptions;
+}
+
+HelperInvocationsInstance::HelperInvocationsInstance (Context& context, const HelperInvocationsParams& params)
+       : TestInstance  (context)
+       , m_format              (VK_FORMAT_R32G32B32A32_SFLOAT)
+       , m_params              (params)
+{
+}
+
+std::vector<Vec3> HelperInvocationsInstance::createSurface (const Points points, const deUint32 divX, const deUint32 divY, const HelperInvocationsParams::func2D_t& f2D, bool clockWise)
+{
+       std::vector<Vec3> s;
+       const float dx = (points == Points::Vertices ? 2.0f : 1.0f) / float(divX);
+       const float dy = (points == Points::Vertices ? 2.0f : 1.0f) / float(divY);
+       // Z is always scaled to range (0,1)
+       auto z = [&](const deUint32 n, const deUint32 m) -> float
+       {
+               const float x = float(n) / float(divX);
+               const float y = float(m) / float(divY);
+               return HelperInvocationsParams::combine(f2D, x,y);
+       };
+       float y = (points == Points::Vertices) ? -1.0f : 0.0f;
+       for (deUint32 j = 0; j < divY; ++j)
+       {
+               const float ny = ((j + 1) < divY) ? (y + dy) : 1.f;
+               float x = (points == Points::Vertices) ? -1.0f : 0.0f;
+
+               for (deUint32 i = 0; i < divX; ++i)
+               {
+                       const float nx = ((i + 1) < divX) ? (x + dx) : 1.f;
+
+                       const Vec3      p0( x,  y, z( i,   j   ));
+                       const Vec3      p1(nx,  y, z( i+1 ,j   ));
+                       const Vec3      p2(nx, ny, z( i+1, j+1 ));
+                       const Vec3      p3( x, ny, z( i,   j+1 ));
+
+                       if (points == Points::Centers)
+                       {
+                               const float cx1 = (p0.x() + p1.x() + p2.x()) / 3.0f;
+                               const float cy1 = (p0.y() + p1.y() + p2.y()) / 3.0f;
+                               const float cz1 = (p0.z() + p1.z() + p2.z()) / 3.0f;
+                               const float cx2 = (p0.x() + p2.x() + p3.x()) / 3.0f;
+                               const float cy2 = (p0.y() + p2.y() + p3.y()) / 3.0f;
+                               const float cz2 = (p0.z() + p2.z() + p3.z()) / 3.0f;
+
+                               s.emplace_back(cx1, cy1, cz1); s.emplace_back(cx1, cy1, cz1); s.emplace_back(cx1, cy1, cz1);
+                               s.emplace_back(cx2, cy2, cz2); s.emplace_back(cx2, cy2, cz2); s.emplace_back(cx2, cy2, cz2);
+                       }
+                       else if (clockWise)
+                       {
+                               s.push_back(p0); s.push_back(p3); s.push_back(p2);
+                               s.push_back(p0); s.push_back(p2); s.push_back(p1);
+                       }
+                       else
+                       {
+                               s.push_back(p0); s.push_back(p1); s.push_back(p2);
+                               s.push_back(p2); s.push_back(p3); s.push_back(p0);
+                       }
+
+                       x = nx;
+               }
+               y = ny;
+       }
+       return s;
+}
+
+VkImageCreateInfo HelperInvocationsInstance::makeImgInfo (deUint32                     queueFamilyIndexCount,
+                                                                                                                 const deUint32*       pQueueFamilyIndices) const
+{
+       const VkImageUsageFlags usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+       return
+       {
+               VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // sType;
+               nullptr,                                                                // pNext;
+               VkImageCreateFlags(0),                                  // flags;
+               VK_IMAGE_TYPE_2D,                                               // imageType;
+               m_format,                                                               // format;
+               {
+                       m_params.screen.first,
+                       m_params.screen.second,
+                       1u
+               },                                                                              // extent;
+               1u,                                                                             // mipLevels;
+               1u,                                                                             // arrayLayers;
+               VK_SAMPLE_COUNT_1_BIT,                                  // samples;
+               VK_IMAGE_TILING_OPTIMAL,                                // tiling;
+               usage,                                                                  // usage;
+               VK_SHARING_MODE_EXCLUSIVE,                              // sharingMode;
+               queueFamilyIndexCount,                                  // queueFamilyIndexCount;
+               pQueueFamilyIndices,                                    // pQueueFamilyIndices;
+               VK_IMAGE_LAYOUT_UNDEFINED                               // initialLayout;
+       };
+}
+
+Move<VkPipeline> HelperInvocationsInstance::makePipeline (const DeviceInterface&       vk,
+                                                                                                                 const VkDevice                        device,
+                                                                                                                 const VkPipelineLayout        pipelineLayout,
+                                                                                                                 const VkShaderModule          vertexShader,
+                                                                                                                 const VkShaderModule          fragmentShader,
+                                                                                                                 const VkRenderPass            renderPass) const
+{
+       DE_ASSERT(sizeof(Vec3) == mapVkFormat(VK_FORMAT_R32G32B32_SFLOAT).getPixelSize());
+
+       const std::vector<VkViewport>                                   viewports                       { makeViewport(m_params.screen.first, m_params.screen.second) };
+       const std::vector<VkRect2D>                                             scissors                        { makeRect2D(m_params.screen.first, m_params.screen.second) };
+
+       const VkVertexInputBindingDescription                   vertexInputBindingDescription
+       {
+               0u,                                                                                                             // deUint32             binding
+               deUint32(sizeof(Vec3) * 3u),                                                    // deUint32             stride
+               VK_VERTEX_INPUT_RATE_VERTEX,                                                    // VkVertexInputRate    inputRate
+       };
+
+       const VkVertexInputAttributeDescription                 vertexInputAttributeDescription[]
+       {
+               {
+                       0u,                                                                                                     // deUint32    location
+                       0u,                                                                                                     // deUint32    binding
+                       VK_FORMAT_R32G32B32_SFLOAT,                                                     // VkFormat    format
+                       0u                                                                                                      // deUint32    offset
+               },                                                                                                              // vertices
+               {
+                       1u,                                                                                                     // deUint32    location
+                       0u,                                                                                                     // deUint32    binding
+                       VK_FORMAT_R32G32B32_SFLOAT,                                                     // VkFormat    format
+                       deUint32(sizeof(Vec3))                                                          // deUint32    offset
+               },                                                                                                              // coords
+               {
+                       2u,                                                                                                     // deUint32    location
+                       0u,                                                                                                     // deUint32    binding
+                       VK_FORMAT_R32G32B32_SFLOAT,                                                     // VkFormat    format
+                       deUint32(sizeof(Vec3) * 2u)                                                     // deUint32    offset
+               }                                                                                                               // centers
+       };
+
+       const VkPipelineVertexInputStateCreateInfo              vertexInputStateCreateInfo
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                             sType
+               nullptr,                                                                                                        // const void*                                 pNext
+               (VkPipelineVertexInputStateCreateFlags)0,                                       // VkPipelineVertexInputStateCreateFlags       flags
+               1u,                                                                                                                     // deUint32                                    vertexBindingDescriptionCount
+               &vertexInputBindingDescription,                                                         // const VkVertexInputBindingDescription*      pVertexBindingDescriptions
+               DE_LENGTH_OF_ARRAY(vertexInputAttributeDescription),            // deUint32                                    vertexAttributeDescriptionCount
+               vertexInputAttributeDescription                                                         // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
+       };
+
+       return makeGraphicsPipeline(vk, device, pipelineLayout,
+                                                               vertexShader, DE_NULL, DE_NULL, DE_NULL, fragmentShader,
+                                                               renderPass, viewports, scissors, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
+                                                               0u, 0u, &vertexInputStateCreateInfo);
+}
+
+de::MovePtr<TopLevelAccelerationStructure> HelperInvocationsInstance::createAccStructs (const DeviceInterface& vk,
+                                                                                                                                                                               const VkDevice                  device,
+                                                                                                                                                                               Allocator&                              allocator,
+                                                                                                                                                                               const VkCommandBuffer   cmdBuffer,
+                                                                                                                                                                               const std::vector<Vec3> coords) const
+{
+       const VkAccelerationStructureBuildTypeKHR               buildType       = m_params.buildGPU
+                                                                                                                                       ? VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR
+                                                                                                                                       : VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR;
+       de::MovePtr<TopLevelAccelerationStructure>              tlas            = makeTopLevelAccelerationStructure();
+       de::MovePtr<BottomLevelAccelerationStructure>   blas            = makeBottomLevelAccelerationStructure();
+
+       blas->setBuildType(buildType);
+       blas->addGeometry(coords, true, VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR);
+       blas->createAndBuild(vk, device, cmdBuffer, allocator);
+
+       tlas->setBuildType(buildType);
+       tlas->addInstance(de::SharedPtr<BottomLevelAccelerationStructure>(blas.release()));
+       tlas->createAndBuild(vk, device, cmdBuffer, allocator);
+
+       return tlas;
+}
+
+de::MovePtr<BufferWithMemory> HelperInvocationsInstance::makeAttribBuff        (const DeviceInterface&         vk,
+                                                                                                                                                const VkDevice                         device,
+                                                                                                                                                Allocator&                                     allocator,
+                                                                                                                                                const std::vector<Vec3>&       vertices,
+                                                                                                                                                const std::vector<Vec3>&       coords,
+                                                                                                                                                const std::vector<Vec3>&       centers) const
+{
+       DE_ASSERT(sizeof(Vec3) == mapVkFormat(VK_FORMAT_R32G32B32_SFLOAT).getPixelSize());
+       const deUint32                                  count                           = deUint32(vertices.size());
+       DE_ASSERT( count && (count == coords.size()) && (count == centers.size()) );
+       const VkDeviceSize                              bufferSize                      = 3 * count * sizeof(Vec3);
+       const VkBufferCreateInfo                bufferCreateInfo        = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
+       de::MovePtr<BufferWithMemory>   buffer                          (new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Coherent | MemoryRequirement::HostVisible));
+
+       Allocation&                                             allocation                      = buffer->getAllocation();
+       Vec3*                                                   data                            = static_cast<Vec3*>(allocation.getHostPtr());
+       for (deUint32 c = 0; c < count; ++c)
+       {
+               data[3*c] = vertices.at(c);
+               data[3*c+1] = coords.at(c);
+               data[3*c+2] = centers.at(c);
+       }
+       flushMappedMemoryRange(vk, device, allocation.getMemory(), 0u, bufferSize);
+
+       return buffer;
+}
+
+de::MovePtr<BufferWithMemory> HelperInvocationsInstance::makeResultBuff        (const DeviceInterface& vk,
+                                                                                                                                                const VkDevice                 device,
+                                                                                                                                                Allocator&                             allocator) const
+{
+       const TextureFormat                             texFormat                       = mapVkFormat(m_format);
+       const VkDeviceSize                              bufferSize                      = (m_params.screen.first * m_params.screen.second * texFormat.getPixelSize());
+       const VkBufferCreateInfo                bufferCreateInfo        = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
+       de::MovePtr<BufferWithMemory>   buffer                          (new BufferWithMemory(vk, device, allocator, bufferCreateInfo, MemoryRequirement::Coherent | MemoryRequirement::HostVisible));
+
+       Allocation&                                             allocation                      = buffer->getAllocation();
+       PixelBufferAccess                               pixels                          (texFormat, m_params.screen.first, m_params.screen.second, 1u, allocation.getHostPtr());
+
+       for (deUint32 y = 0; y < m_params.screen.second; ++y)
+       {
+               for (deUint32 x = 0; x < m_params.screen.first; ++x)
+               {
+                       pixels.setPixel(Vec4(0.0f, 0.0f, 0.0f, -1.0f), x, y);
+               }
+       }
+       flushMappedMemoryRange(vk, device, allocation.getMemory(), 0u, bufferSize);
+
+       return buffer;
+}
+
+bool HelperInvocationsInstance::verifyResult (const DeviceInterface&   vk,
+                                                                                         const VkDevice                        device,
+                                                                                         const BufferWithMemory&       buffer) const
+{
+       int                                             invalid = 0;
+       Allocation&                             alloc   = buffer.getAllocation();
+       invalidateMappedMemoryRange(vk, device, alloc.getMemory(), 0u, VK_WHOLE_SIZE);
+       ConstPixelBufferAccess  pixels  (mapVkFormat(m_format), m_params.screen.first, m_params.screen.second, 1u, alloc.getHostPtr());
+
+       for (deUint32 y = 0; y < m_params.screen.second; ++y)
+       {
+               for (deUint32 x = 0; x < m_params.screen.first; ++x)
+               {
+                       const Vec4 px = pixels.getPixel(x,y);
+                       if (px.z() < 0.0f || px.w() < 0.0f)
+                               invalid += 1;
+               }
+       }
+
+       return (0 == invalid);
+}
+
+VkWriteDescriptorSetAccelerationStructureKHR makeAccStructDescriptorWrite (const VkAccelerationStructureKHR* ptr, deUint32 count = 1u)
+{
+       return {
+               VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,      //      VkStructureType                                         sType;
+               nullptr,                                                                                                                        //      const void*                                                     pNext;
+               count,                                                                                                                          //      deUint32                                                        accelerationStructureCount;
+               ptr};                                                                                                                           //      const VkAccelerationStructureKHR*       pAccelerationStructures;
+};
+
+TestStatus HelperInvocationsInstance::iterate (void)
+{
+       const VkDevice                                                  device                                          = m_context.getDevice();
+       const DeviceInterface&                                  vk                                                      = m_context.getDeviceInterface();
+       Allocator&                                                              allocator                                       = m_context.getDefaultAllocator();
+       const deUint32                                                  queueFamilyIndex                        = m_context.getUniversalQueueFamilyIndex();
+       const VkQueue                                                   queue                                           = m_context.getUniversalQueue();
+
+       const VkRect2D                                                  renderArea                                      = makeRect2D(m_params.screen.first, m_params.screen.second);
+       const VkImageCreateInfo                                 imageCreateInfo                         = makeImgInfo(1, &queueFamilyIndex);
+       const de::MovePtr<ImageWithMemory>              image                                           (new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any));
+       const VkImageSubresourceRange                   imageSubresourceRange           = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0, 1u);
+       const Move<VkImageView>                                 view                                            = makeImageView(vk, device, **image, VK_IMAGE_VIEW_TYPE_2D, m_format, imageSubresourceRange);
+       const Move<VkRenderPass>                                renderPass                                      = makeRenderPass(vk, device, m_format);
+       const Move<VkFramebuffer>                               frameBuffer                                     = makeFramebuffer(vk, device, *renderPass, *view, m_params.screen.first, m_params.screen.second);
+       const de::MovePtr<BufferWithMemory>             resultBuffer                            = makeResultBuff(vk, device, allocator);
+       const VkImageSubresourceLayers                  imageSubresourceLayers          = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
+       const VkBufferImageCopy                                 bufferCopyImageRegion           = makeBufferImageCopy(makeExtent3D(UVec3(m_params.screen.first, m_params.screen.second, 1u)), imageSubresourceLayers);
+
+       const HelperInvocationsParams::func2D_t funcs                                           = m_params.mode.funcs;
+       struct PushConstants
+       {
+               int fun_x, fun_y;
+       } const                                 pushConstants                           { m_params.mode.types.first, m_params.mode.types.second };
+       const VkPushConstantRange                               pushConstantRange                       { VK_SHADER_STAGE_FRAGMENT_BIT, 0u, uint32_t(sizeof(pushConstants)) };
+       const std::vector<Vec3>                                 vertices                                        = createSurface(Points::Vertices, m_params.model.first, m_params.model.second, funcs);
+       const std::vector<Vec3>                                 coords                                          = createSurface(Points::Coords, m_params.model.first, m_params.model.second, funcs);
+       const std::vector<Vec3>                                 centers                                         = createSurface(Points::Centers, m_params.model.first, m_params.model.second, funcs);
+       const de::MovePtr<BufferWithMemory>             attribBuffer                            = makeAttribBuff(vk, device, allocator, vertices, coords, centers);
+
+       TopLevelAccelerationStructurePtr                topAccStruct                            {};
+       Move<VkDescriptorSetLayout>                             descriptorLayout                        = DescriptorSetLayoutBuilder()
+                                                                                                                                                       .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_FRAGMENT_BIT)
+                                                                                                                                                       .build(vk, device);
+       Move<VkDescriptorPool>                                  descriptorPool                          = DescriptorPoolBuilder()
+                                                                                                                                                       .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
+                                                                                                                                                       .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
+       Move<VkDescriptorSet>                                   descriptorSet                           = makeDescriptorSet(vk, device, *descriptorPool, *descriptorLayout);
+
+       Move<VkShaderModule>                                    vertexShader                            = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u);
+       Move<VkShaderModule>                                    fragmentShader                          = createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u);
+       Move<VkPipelineLayout>                                  pipelineLayout                          = makePipelineLayout(vk, device, 1u, &descriptorLayout.get(), 1u, &pushConstantRange);
+       Move<VkPipeline>                                                pipeline                                        = makePipeline(vk, device, *pipelineLayout, *vertexShader, *fragmentShader, *renderPass);
+       const Move<VkCommandPool>                               cmdPool                                         = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
+       const Move<VkCommandBuffer>                             cmdBuffer                                       = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+
+       const Vec4                                                              clearColor                                      ( 0.1f, 0.2f, 0.3f, 0.4f );
+       const VkImageMemoryBarrier                              postDrawImageBarrier            = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
+                                                                                                                                                                                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                                                                                                                                                                                                **image, imageSubresourceRange);
+       const VkMemoryBarrier                                   postCopyMemoryBarrier           = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
+
+       beginCommandBuffer(vk, *cmdBuffer, 0u);
+
+               topAccStruct = createAccStructs(vk, device, allocator, *cmdBuffer, coords);
+               const auto accStructWrite = makeAccStructDescriptorWrite(topAccStruct->getPtr());
+               DescriptorSetUpdateBuilder().writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
+                                                                                                VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accStructWrite).update(vk, device);
+
+               vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
+               vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &static_cast<const VkBuffer&>(**attribBuffer), &static_cast<const VkDeviceSize&>(0u));
+               vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, uint32_t(sizeof(pushConstants)), &pushConstants);
+               vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, nullptr);
+
+               beginRenderPass(vk, *cmdBuffer, *renderPass, *frameBuffer, renderArea, clearColor);
+                       vk.cmdDraw(*cmdBuffer, uint32_t(vertices.size()), 1u, 0u, 0u);
+               endRenderPass(vk, *cmdBuffer);
+
+               cmdPipelineImageMemoryBarrier(vk, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postDrawImageBarrier);
+               vk.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **resultBuffer, 1u, &bufferCopyImageRegion);
+               cmdPipelineMemoryBarrier(vk, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
+
+       endCommandBuffer(vk, *cmdBuffer);
+
+       submitCommandsAndWait(vk, device, queue, *cmdBuffer);
+
+       return verifyResult(vk, device, *resultBuffer) ? TestStatus::pass("") : TestStatus::fail("");
+}
+
 } // anonymous
 
+TestCaseGroup* addHelperInvocationsTests(TestContext& testCtx)
+{
+       std::pair<bool, const char*> const builds[]
+       {
+               { true,         "gpu"   },
+               { false,        "cpu"   }
+       };
+
+       std::pair<HelperInvocationsParams::DfStyle, const char*> const styles[]
+       {
+               { HelperInvocationsParams::Regular,     "regular"       },
+               { HelperInvocationsParams::Coarse,      "coarse"        },
+               { HelperInvocationsParams::Fine,        "fine"          }
+       };
+
+       std::pair<HelperInvocationsParams::test_mode_t, const char*> const modes[] =
+       {
+               { HelperInvocationsParams::MODE_LINEAR_QUADRATIC        , "linear_quadratic"    },
+               { HelperInvocationsParams::MODE_LINEAR_CUBIC            , "linear_cubic"                },
+               { HelperInvocationsParams::MODE_CUBIC_QUADRATIC         , "cubic_quadratic"             },
+#ifdef ENABLE_ALL_HELPER_COMBINATIONS
+               { HelperInvocationsParams::MODE_LINEAR_LINEAR           , "linear_linear"               },
+               { HelperInvocationsParams::MODE_QUADRATIC_LINEAR        , "quadratic_linear"    },
+               { HelperInvocationsParams::MODE_QUADRATIC_QUADRATIC     , "quadratic_quadratic" },
+               { HelperInvocationsParams::MODE_QUADRATIC_CUBIC         , "quadratic_cubic"             },
+               { HelperInvocationsParams::MODE_CUBIC_LINEAR            , "cubic_linear"                },
+               { HelperInvocationsParams::MODE_CUBIC_CUBIC                     , "cubic_cubic"                 },
+#endif
+       };
+
+       std::pair<deUint32, deUint32> const screens[]
+       {
+               { 64, 64 }, { 32, 64 }
+       };
+
+       std::pair<deUint32, deUint32> const models[]
+       {
+               { 64, 64 }, { 64, 32 }
+       };
+
+       auto makeTestName = [](const std::pair<deUint32, deUint32>& d) -> std::string
+       {
+               return std::to_string(d.first) + "x" + std::to_string(d.second);
+       };
+
+       auto rootGroup = new TestCaseGroup(testCtx, "helper_invocations", "Ray query helper invocation tests");
+       for (auto& build : builds)
+       {
+               auto buildGroup = new tcu::TestCaseGroup(testCtx, build.second, "");
+               for (auto& style : styles)
+               {
+                       auto styleGroup = new tcu::TestCaseGroup(testCtx, style.second, "");
+                       for (auto& mode : modes)
+                       {
+                               auto modeGroup = new tcu::TestCaseGroup(testCtx, mode.second, "");
+                               for (auto& screen : screens)
+                               {
+                                       auto screenGroup = new TestCaseGroup(testCtx, makeTestName(screen).c_str(), "");
+                                       for (auto& model : models)
+                                       {
+                                               HelperInvocationsParams p;
+                                               p.mode          = mode.first;
+                                               p.screen        = screen;
+                                               p.model         = model;
+                                               p.style         = style.first;
+                                               p.buildGPU      = build.first;
+
+                                               screenGroup->addChild(new HelperInvocationsCase(testCtx, p, makeTestName(model)));
+                                       }
+                                       modeGroup->addChild(screenGroup);
+                               }
+                               styleGroup->addChild(modeGroup);
+                       }
+                       buildGroup->addChild(styleGroup);
+               }
+               rootGroup->addChild(buildGroup);
+       }
+       return rootGroup;
+}
+
 tcu::TestCaseGroup*    createMiscTests (tcu::TestContext& testCtx)
 {
        de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "misc", "Miscellaneous ray query tests"));
index 16ea566..bab0d73 100644 (file)
@@ -33,6 +33,7 @@ namespace RayQuery
 {
 
 tcu::TestCaseGroup*    createMiscTests (tcu::TestContext& testCtx);
+tcu::TestCaseGroup* addHelperInvocationsTests(tcu::TestContext& testCtx);
 
 } // RayQuery
 } // vkt
index 5de23de..11f1c36 100644 (file)
@@ -58,6 +58,7 @@ tcu::TestCaseGroup*   createTests (tcu::TestContext& testCtx)
        group->addChild(createInsideAABBsTests(testCtx));
        group->addChild(createBarycentricCoordinatesTests(testCtx));
        group->addChild(createNonUniformArgsTests(testCtx));
+       group->addChild(addHelperInvocationsTests(testCtx));
 
        return group.release();
 }
index 2bb070f..97237ad 100644 (file)
@@ -23426,3 +23426,75 @@ dEQP-VK.ray_query.non_uniform_args.miss_cause_3
 dEQP-VK.ray_query.non_uniform_args.miss_cause_4
 dEQP-VK.ray_query.non_uniform_args.miss_cause_5
 dEQP-VK.ray_query.non_uniform_args.miss_cause_6
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.regular.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.regular.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.coarse.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.gpu.fine.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.gpu.fine.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.regular.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.regular.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.coarse.cubic_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_quadratic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_cubic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_cubic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_cubic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.linear_cubic.32x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.cubic_quadratic.64x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.cubic_quadratic.64x64.64x32
+dEQP-VK.ray_query.helper_invocations.cpu.fine.cubic_quadratic.32x64.64x64
+dEQP-VK.ray_query.helper_invocations.cpu.fine.cubic_quadratic.32x64.64x32