xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/ray_query/vktRayQueryBuiltinTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2020 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Ray Query Builtin tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktRayQueryBuiltinTests.hpp"
25 
26 #include "vkDefs.hpp"
27 
28 #include "vktTestCase.hpp"
29 #include "vktCustomInstancesDevices.hpp"
30 #include "vktTestGroupUtil.hpp"
31 #include "vkCmdUtil.hpp"
32 #include "vkObjUtil.hpp"
33 #include "vkBuilderUtil.hpp"
34 #include "vkBarrierUtil.hpp"
35 #include "vkBufferWithMemory.hpp"
36 #include "vkImageWithMemory.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkImageUtil.hpp"
39 #include "deRandom.hpp"
40 #include "tcuTexture.hpp"
41 #include "tcuTextureUtil.hpp"
42 #include "tcuTestLog.hpp"
43 #include "tcuImageCompare.hpp"
44 #include "tcuCommandLine.hpp"
45 
46 #include "vkRayTracingUtil.hpp"
47 
48 namespace vkt
49 {
50 namespace RayQuery
51 {
52 namespace
53 {
54 using namespace vk;
55 using namespace vkt;
56 
57 static const VkFlags ALL_RAY_TRACING_STAGES = VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
58                                               VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR |
59                                               VK_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
60 
61 enum TestType
62 {
63     TEST_TYPE_FLOW = 0,
64     TEST_TYPE_PRIMITIVE_ID,
65     TEST_TYPE_INSTANCE_ID,
66     TEST_TYPE_INSTANCE_CUSTOM_INDEX,
67     TEST_TYPE_INTERSECTION_T_KHR,
68     TEST_TYPE_OBJECT_RAY_ORIGIN_KHR,
69     TEST_TYPE_OBJECT_RAY_DIRECTION_KHR,
70     TEST_TYPE_OBJECT_TO_WORLD_KHR,
71     TEST_TYPE_WORLD_TO_OBJECT_KHR,
72     TEST_TYPE_NULL_ACCELERATION_STRUCTURE,
73     TEST_TYPE_USING_WRAPPER_FUNCTION,
74     TEST_TYPE_GET_RAY_TMIN,
75     TEST_TYPE_GET_WORLD_RAY_ORIGIN,
76     TEST_TYPE_GET_WORLD_RAY_DIRECTION,
77     TEST_TYPE_GET_INTERSECTION_CANDIDATE_AABB_OPAQUE,
78     TEST_TYPE_GET_INTERSECTION_FRONT_FACE_CANDIDATE,
79     TEST_TYPE_GET_INTERSECTION_FRONT_FACE_COMMITTED,
80     TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_CANDIDATE,
81     TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_COMMITTED,
82     TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_CANDIDATE,
83     TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_COMMITTED,
84     TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_CANDIDATE,
85     TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_COMMITTED,
86     TEST_TYPE_RAY_QUERY_TERMINATE,
87     TEST_TYPE_GET_INTERSECTION_TYPE_CANDIDATE,
88     TEST_TYPE_GET_INTERSECTION_TYPE_COMMITTED,
89 
90     TEST_TYPE_LAST
91 };
92 
93 enum GeomType
94 {
95     GEOM_TYPE_TRIANGLES,
96     GEOM_TYPE_AABBS,
97     GEOM_TYPE_LAST,
98 };
99 
100 const uint32_t TEST_WIDTH                = 8;
101 const uint32_t TEST_HEIGHT               = 8;
102 const uint32_t FIXED_POINT_DIVISOR       = 1024 * 1024;
103 const uint32_t FIXED_POINT_ALLOWED_ERROR = static_cast<uint32_t>(float(1e-3f) * FIXED_POINT_DIVISOR);
104 
105 struct TestParams;
106 
107 // Similar to a subset of the test context but allows us to plug in a custom device when needed.
108 // Note TestEnvironment objects do not own the resources they point to.
109 struct TestEnvironment
110 {
111     const InstanceInterface *vki;
112     VkPhysicalDevice physicalDevice;
113     const DeviceInterface *vkd;
114     VkDevice device;
115     Allocator *allocator;
116     VkQueue queue;
117     uint32_t queueFamilyIndex;
118     BinaryCollection *binaryCollection;
119     tcu::TestLog *log;
120 };
121 
122 typedef void (*CheckSupportFunc)(Context &context, const TestParams &testParams);
123 typedef void (*InitProgramsFunc)(SourceCollections &programCollection, const TestParams &testParams);
124 typedef const std::string (*ShaderBodyTextFunc)(const TestParams &testParams);
125 
126 class PipelineConfiguration
127 {
128 public:
PipelineConfiguration()129     PipelineConfiguration()
130     {
131     }
~PipelineConfiguration()132     virtual ~PipelineConfiguration()
133     {
134     }
135 
136     virtual void initConfiguration(const TestEnvironment &env, TestParams &testParams) = 0;
137     virtual void fillCommandBuffer(const TestEnvironment &env, TestParams &testParams, VkCommandBuffer commandBuffer,
138                                    const VkAccelerationStructureKHR *rayQueryTopAccelerationStructurePtr,
139                                    const VkDescriptorImageInfo &resultImageInfo)       = 0;
140 };
141 
142 class TestConfiguration
143 {
144 public:
TestConfiguration(Context & context)145     TestConfiguration(Context &context)
146         : m_bottomAccelerationStructures()
147         , m_topAccelerationStructure()
148         , m_expected()
149         , m_testEnvironment()
150     {
151         prepareTestEnvironment(context);
152     }
~TestConfiguration()153     virtual ~TestConfiguration()
154     {
155     }
156 
157     const TestEnvironment &getTestEnvironment() const;
158     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
159                                                                          VkCommandBuffer cmdBuffer) = 0;
160     virtual bool verify(BufferWithMemory *resultBuffer, TestParams &testParams);
161 
162 protected:
163     void prepareTestEnvironment(Context &context);
164 
165     std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> m_bottomAccelerationStructures;
166     de::SharedPtr<TopLevelAccelerationStructure> m_topAccelerationStructure;
167     std::vector<int32_t> m_expected;
168     de::MovePtr<TestEnvironment> m_testEnvironment;
169 };
170 
171 class TestConfigurationFloat : public TestConfiguration
172 {
173 public:
TestConfigurationFloat(Context & context)174     TestConfigurationFloat(Context &context) : TestConfiguration(context)
175     {
176     }
~TestConfigurationFloat()177     virtual ~TestConfigurationFloat()
178     {
179     }
180     virtual bool verify(BufferWithMemory *resultBuffer, TestParams &testParams) override;
181 };
182 
183 class TestConfigurationVector : public TestConfiguration
184 {
185 public:
TestConfigurationVector(Context & context,bool useStrictComponentMatching=true)186     TestConfigurationVector(Context &context, bool useStrictComponentMatching = true)
187         : TestConfiguration(context)
188         , m_useStrictComponentMatching(useStrictComponentMatching)
189     {
190     }
~TestConfigurationVector()191     virtual ~TestConfigurationVector()
192     {
193     }
194     virtual bool verify(BufferWithMemory *resultBuffer, TestParams &testParams) override;
195 
196 private:
197     bool m_useStrictComponentMatching;
198 };
199 
200 class TestConfigurationMatrix : public TestConfiguration
201 {
202 public:
TestConfigurationMatrix(Context & context)203     TestConfigurationMatrix(Context &context) : TestConfiguration(context)
204     {
205     }
~TestConfigurationMatrix()206     virtual ~TestConfigurationMatrix()
207     {
208     }
209     virtual bool verify(BufferWithMemory *resultBuffer, TestParams &testParams) override;
210 };
211 
212 struct TestParams
213 {
214     uint32_t width;
215     uint32_t height;
216     uint32_t depth;
217     TestType testType;
218     VkShaderStageFlagBits stage;
219     GeomType geomType;
220     uint32_t squaresGroupCount;
221     uint32_t geometriesGroupCount;
222     uint32_t instancesGroupCount;
223     VkFormat format;
224     CheckSupportFunc pipelineCheckSupport;
225     InitProgramsFunc pipelineInitPrograms;
226     ShaderBodyTextFunc testConfigShaderBodyText;
227     bool isSPIRV; // determines if shader body is defined in SPIR-V
228     CheckSupportFunc testConfigCheckSupport;
229 };
230 
getShaderGroupHandleSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)231 uint32_t getShaderGroupHandleSize(const InstanceInterface &vki, const VkPhysicalDevice physicalDevice)
232 {
233     de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
234 
235     rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
236 
237     return rayTracingPropertiesKHR->getShaderGroupHandleSize();
238 }
239 
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)240 uint32_t getShaderGroupBaseAlignment(const InstanceInterface &vki, const VkPhysicalDevice physicalDevice)
241 {
242     de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
243 
244     rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
245 
246     return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
247 }
248 
makeImageCreateInfo(VkFormat format,uint32_t width,uint32_t height,uint32_t 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)249 VkImageCreateInfo makeImageCreateInfo(VkFormat format, uint32_t width, uint32_t height, uint32_t depth,
250                                       VkImageType imageType        = VK_IMAGE_TYPE_3D,
251                                       VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT |
252                                                                      VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
253                                                                      VK_IMAGE_USAGE_TRANSFER_DST_BIT)
254 {
255     const VkImageCreateInfo imageCreateInfo = {
256         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
257         DE_NULL,                             // const void* pNext;
258         (VkImageCreateFlags)0u,              // VkImageCreateFlags flags;
259         imageType,                           // VkImageType imageType;
260         format,                              // VkFormat format;
261         makeExtent3D(width, height, depth),  // VkExtent3D extent;
262         1u,                                  // uint32_t mipLevels;
263         1u,                                  // uint32_t arrayLayers;
264         VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits samples;
265         VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling tiling;
266         usageFlags,                          // VkImageUsageFlags usage;
267         VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode sharingMode;
268         0u,                                  // uint32_t queueFamilyIndexCount;
269         DE_NULL,                             // const uint32_t* pQueueFamilyIndices;
270         VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout initialLayout;
271     };
272 
273     return imageCreateInfo;
274 }
275 
getMissPassthrough(void)276 static const std::string getMissPassthrough(void)
277 {
278     const std::string missPassthrough = "#version 460 core\n"
279                                         "#extension GL_EXT_ray_tracing : require\n"
280                                         "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
281                                         "\n"
282                                         "void main()\n"
283                                         "{\n"
284                                         "}\n";
285 
286     return missPassthrough;
287 }
288 
getHitPassthrough(void)289 static const std::string getHitPassthrough(void)
290 {
291     const std::string hitPassthrough = "#version 460 core\n"
292                                        "#extension GL_EXT_ray_tracing : require\n"
293                                        "hitAttributeEXT vec3 attribs;\n"
294                                        "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
295                                        "\n"
296                                        "void main()\n"
297                                        "{\n"
298                                        "}\n";
299 
300     return hitPassthrough;
301 }
302 
getGraphicsPassthrough(void)303 static const std::string getGraphicsPassthrough(void)
304 {
305     std::ostringstream src;
306 
307     src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
308         << "\n"
309         << "void main(void)\n"
310         << "{\n"
311         << "}\n";
312 
313     return src.str();
314 }
315 
getVertexPassthrough(void)316 static const std::string getVertexPassthrough(void)
317 {
318     std::ostringstream src;
319 
320     src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
321         << "\n"
322         << "layout(location = 0) in vec4 in_position;\n"
323         << "\n"
324         << "void main(void)\n"
325         << "{\n"
326         << "  gl_Position = in_position;\n"
327         << "}\n";
328 
329     return src.str();
330 }
331 
getGeomName(bool writePointSize)332 static const std::string getGeomName(bool writePointSize)
333 {
334     std::ostringstream str;
335     str << "geom" << (writePointSize ? "_point_size" : "");
336     return str.str();
337 }
338 
339 class GraphicsConfiguration : public PipelineConfiguration
340 {
341 public:
342     static void checkSupport(Context &context, const TestParams &testParams);
343     static void initPrograms(SourceCollections &programCollection, const TestParams &testParams);
344 
345     GraphicsConfiguration();
~GraphicsConfiguration()346     virtual ~GraphicsConfiguration()
347     {
348     }
349 
350     void initVertexBuffer(const TestEnvironment &env, TestParams &testParams);
351     Move<VkPipeline> makeGraphicsPipeline(const TestEnvironment &env, TestParams &testParams);
352     virtual void initConfiguration(const TestEnvironment &env, TestParams &testParams) override;
353     virtual void fillCommandBuffer(const TestEnvironment &env, TestParams &testParams, VkCommandBuffer commandBuffer,
354                                    const VkAccelerationStructureKHR *rayQueryTopAccelerationStructurePtr,
355                                    const VkDescriptorImageInfo &resultImageInfo) override;
356 
357 private:
358     Move<VkDescriptorSetLayout> m_descriptorSetLayout;
359     Move<VkDescriptorPool> m_descriptorPool;
360     Move<VkDescriptorSet> m_descriptorSet;
361 
362     VkFormat m_framebufferFormat;
363     Move<VkImage> m_framebufferImage;
364     de::MovePtr<Allocation> m_framebufferImageAlloc;
365     Move<VkImageView> m_framebufferAttachment;
366 
367     Move<VkShaderModule> m_vertShaderModule;
368     Move<VkShaderModule> m_geomShaderModule;
369     Move<VkShaderModule> m_tescShaderModule;
370     Move<VkShaderModule> m_teseShaderModule;
371     Move<VkShaderModule> m_fragShaderModule;
372 
373     Move<VkRenderPass> m_renderPass;
374     Move<VkFramebuffer> m_framebuffer;
375     Move<VkPipelineLayout> m_pipelineLayout;
376     Move<VkPipeline> m_pipeline;
377 
378     uint32_t m_vertexCount;
379     Move<VkBuffer> m_vertexBuffer;
380     de::MovePtr<Allocation> m_vertexBufferAlloc;
381 };
382 
GraphicsConfiguration()383 GraphicsConfiguration::GraphicsConfiguration()
384     : PipelineConfiguration()
385     , m_descriptorSetLayout()
386     , m_descriptorPool()
387     , m_descriptorSet()
388     , m_framebufferFormat(VK_FORMAT_R8G8B8A8_UNORM)
389     , m_framebufferImage()
390     , m_framebufferImageAlloc()
391     , m_framebufferAttachment()
392     , m_vertShaderModule()
393     , m_geomShaderModule()
394     , m_tescShaderModule()
395     , m_teseShaderModule()
396     , m_fragShaderModule()
397     , m_renderPass()
398     , m_framebuffer()
399     , m_pipelineLayout()
400     , m_pipeline()
401     , m_vertexCount(0)
402     , m_vertexBuffer()
403     , m_vertexBufferAlloc()
404 {
405 }
406 
checkSupport(Context & context,const TestParams & testParams)407 void GraphicsConfiguration::checkSupport(Context &context, const TestParams &testParams)
408 {
409     switch (testParams.stage)
410     {
411     case VK_SHADER_STAGE_VERTEX_BIT:
412     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
413     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
414     case VK_SHADER_STAGE_GEOMETRY_BIT:
415         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
416         break;
417     default:
418         break;
419     }
420 
421     switch (testParams.stage)
422     {
423     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
424     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
425         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
426         break;
427     case VK_SHADER_STAGE_GEOMETRY_BIT:
428         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
429         break;
430     default:
431         break;
432     }
433 }
434 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)435 void GraphicsConfiguration::initPrograms(SourceCollections &programCollection, const TestParams &testParams)
436 {
437     const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
438 
439     const std::string testShaderBody = testParams.testConfigShaderBodyText(testParams);
440 
441     switch (testParams.stage)
442     {
443     case VK_SHADER_STAGE_VERTEX_BIT:
444     {
445         {
446             std::ostringstream src;
447             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
448                 << "#extension GL_EXT_ray_query : require\n"
449                 << "#extension GL_EXT_ray_tracing : require\n"
450                 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
451                 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT "
452                    "rayQueryTopLevelAccelerationStructure;\n"
453                 << "\n"
454                 << "void testFunc(ivec3 pos, ivec3 size)\n"
455                 << "{\n"
456                 << testShaderBody << "}\n"
457                 << "\n"
458                 << "void main(void)\n"
459                 << "{\n"
460                 << "  const int   posId    = int(gl_VertexIndex / 3);\n"
461                 << "  const int   vertId   = int(gl_VertexIndex % 3);\n"
462                 << "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
463                 << "  const ivec3 pos      = ivec3(posId % size.x, posId / size.x, 0);\n"
464                 << "\n"
465                 << "  if (vertId == 0)\n"
466                 << "  {\n"
467                 << "    testFunc(pos, size);\n"
468                 << "  }\n"
469                 << "}\n";
470 
471             programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
472         }
473 
474         programCollection.glslSources.add("frag") << glu::FragmentSource(getGraphicsPassthrough()) << buildOptions;
475 
476         break;
477     }
478 
479     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
480     {
481         {
482             std::ostringstream src;
483             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
484                 << "\n"
485                 << "layout(location = 0) in vec4 in_position;\n"
486                 << "out gl_PerVertex\n"
487                 << "{\n"
488                 << "  vec4 gl_Position;\n"
489                 << "};\n"
490                 << "\n"
491                 << "void main(void)\n"
492                 << "{\n"
493                 << "  gl_Position = in_position;\n"
494                 << "}\n";
495 
496             programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
497         }
498 
499         {
500             std::ostringstream src;
501             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
502                 << "#extension GL_EXT_tessellation_shader : require\n"
503                 << "#extension GL_EXT_ray_query : require\n"
504                 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
505                 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT "
506                    "rayQueryTopLevelAccelerationStructure;\n"
507                 << "in gl_PerVertex\n"
508                 << "{\n"
509                 << "  vec4 gl_Position;\n"
510                 << "} gl_in[];\n"
511                 << "layout(vertices = 4) out;\n"
512                 << "out gl_PerVertex\n"
513                 << "{\n"
514                 << "  vec4 gl_Position;\n"
515                 << "} gl_out[];\n"
516                 << "\n"
517                 << "void testFunc(ivec3 pos, ivec3 size)\n"
518                 << "{\n"
519                 << testShaderBody << "}\n"
520                 << "\n"
521                 << "void main(void)\n"
522                 << "{\n"
523                 << "\n"
524                 << "  if (gl_InvocationID == 0)\n"
525                 << "  {\n"
526                 << "    const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
527                 << "    for (int y = 0; y < size.y; y++)\n"
528                 << "    for (int x = 0; x < size.x; x++)\n"
529                 << "    {\n"
530                 << "      const ivec3 pos = ivec3(x, y, 0);\n"
531                 << "      testFunc(pos, size);\n"
532                 << "    }\n"
533                 << "  }\n"
534                 << "\n"
535                 << "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
536                 << "  gl_TessLevelInner[0] = 1;\n"
537                 << "  gl_TessLevelInner[1] = 1;\n"
538                 << "  gl_TessLevelOuter[gl_InvocationID] = 1;\n"
539                 << "}\n";
540 
541             programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions;
542         }
543 
544         {
545             std::ostringstream src;
546             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
547                 << "#extension GL_EXT_tessellation_shader : require\n"
548                 << "layout(quads, equal_spacing, ccw) in;\n"
549                 << "in gl_PerVertex\n"
550                 << "{\n"
551                 << "  vec4 gl_Position;\n"
552                 << "} gl_in[];\n"
553                 << "\n"
554                 << "void main(void)\n"
555                 << "{\n"
556                 << "  gl_Position = gl_in[0].gl_Position;\n"
557                 << "}\n";
558 
559             programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions;
560         }
561 
562         break;
563     }
564 
565     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
566     {
567         {
568             std::ostringstream src;
569             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
570                 << "\n"
571                 << "layout(location = 0) in vec4 in_position;\n"
572                 << "out gl_PerVertex"
573                 << "{\n"
574                 << "  vec4 gl_Position;\n"
575                 << "};\n"
576                 << "\n"
577                 << "void main(void)\n"
578                 << "{\n"
579                 << "  gl_Position = in_position;\n"
580                 << "}\n";
581 
582             programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
583         }
584 
585         {
586             std::ostringstream src;
587             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
588                 << "#extension GL_EXT_tessellation_shader : require\n"
589                 << "in gl_PerVertex\n"
590                 << "{\n"
591                 << "  vec4 gl_Position;\n"
592                 << "} gl_in[];\n"
593                 << "layout(vertices = 4) out;\n"
594                 << "out gl_PerVertex\n"
595                 << "{\n"
596                 << "  vec4 gl_Position;\n"
597                 << "} gl_out[];\n"
598                 << "\n"
599                 << "void main(void)\n"
600                 << "{\n"
601                 << "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
602                 << "  gl_TessLevelInner[0] = 1;\n"
603                 << "  gl_TessLevelInner[1] = 1;\n"
604                 << "  gl_TessLevelOuter[gl_InvocationID] = 1;\n"
605                 << "}\n";
606 
607             programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions;
608         }
609 
610         {
611             std::ostringstream src;
612             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
613                 << "#extension GL_EXT_tessellation_shader : require\n"
614                 << "#extension GL_EXT_ray_query : require\n"
615                 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
616                 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT "
617                    "rayQueryTopLevelAccelerationStructure;\n"
618                 << "layout(quads, equal_spacing, ccw) in;\n"
619                 << "in gl_PerVertex\n"
620                 << "{\n"
621                 << "  vec4 gl_Position;\n"
622                 << "} gl_in[];\n"
623                 << "\n"
624                 << "void testFunc(ivec3 pos, ivec3 size)\n"
625                 << "{\n"
626                 << testShaderBody << "}\n"
627                 << "\n"
628                 << "void main(void)\n"
629                 << "{\n"
630                 << "  const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
631                 << "\n"
632                 << "  if (gl_PrimitiveID == 0)\n"
633                 << "  {\n"
634                 << "    const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
635                 << "    for (int y = 0; y < size.y; y++)\n"
636                 << "    for (int x = 0; x < size.x; x++)\n"
637                 << "    {\n"
638                 << "      const ivec3 pos = ivec3(x, y, 0);\n"
639                 << "      testFunc(pos, size);\n"
640                 << "    }\n"
641                 << "  }\n"
642                 << "\n"
643                 << "  gl_Position = gl_in[0].gl_Position;\n"
644                 << "}\n";
645 
646             programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions;
647         }
648 
649         break;
650     }
651 
652     case VK_SHADER_STAGE_GEOMETRY_BIT:
653     {
654         programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions;
655 
656         for (uint32_t i = 0; i < 2; ++i)
657         {
658             const bool writePointSize = i == 1;
659             std::string pointSize     = writePointSize ? "    gl_PointSize = 1.0f;\n" : "";
660 
661             std::ostringstream src;
662             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
663                 << "#extension GL_EXT_ray_query : require\n"
664                 << "layout(triangles) in;\n"
665                 << "layout(points, max_vertices = 1) out;\n"
666                 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
667                 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT "
668                    "rayQueryTopLevelAccelerationStructure;\n"
669                 << "\n"
670                 << "void testFunc(ivec3 pos, ivec3 size)\n"
671                 << "{\n"
672                 << testShaderBody << "}\n"
673                 << "\n"
674                 << "void main(void)\n"
675                 << "{\n"
676                 << "  const int   posId    = int(gl_PrimitiveIDIn);\n"
677                 << "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
678                 << "  const ivec3 pos      = ivec3(posId % size.x, posId / size.x, 0);\n"
679                 << "\n"
680                 << "  testFunc(pos, size);\n"
681                 << pointSize << "}\n";
682 
683             programCollection.glslSources.add(getGeomName(writePointSize))
684                 << glu::GeometrySource(src.str()) << buildOptions;
685         }
686 
687         break;
688     }
689 
690     case VK_SHADER_STAGE_FRAGMENT_BIT:
691     {
692         programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions;
693 
694         {
695             std::ostringstream src;
696             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
697                 << "#extension GL_EXT_ray_query : require\n"
698                 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
699                 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT "
700                    "rayQueryTopLevelAccelerationStructure;\n"
701                 << "\n"
702                 << "void testFunc(ivec3 pos, ivec3 size)\n"
703                 << "{\n"
704                 << testShaderBody << "}\n"
705                 << "\n"
706                 << "void main(void)\n"
707                 << "{\n"
708                 << "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
709                 << "  const ivec3 pos      = ivec3(int(gl_FragCoord.x - 0.5f), int(gl_FragCoord.y - 0.5f), 0);\n"
710                 << "\n"
711                 << "  testFunc(pos, size);\n"
712                 << "}\n";
713 
714             programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()) << buildOptions;
715         }
716 
717         break;
718     }
719 
720     default:
721         TCU_THROW(InternalError, "Unknown stage");
722     }
723 }
724 
initVertexBuffer(const TestEnvironment & env,TestParams & testParams)725 void GraphicsConfiguration::initVertexBuffer(const TestEnvironment &env, TestParams &testParams)
726 {
727     const DeviceInterface &vkd = *env.vkd;
728     const VkDevice device      = env.device;
729     Allocator &allocator       = *env.allocator;
730     const uint32_t width       = testParams.width;
731     const uint32_t height      = testParams.height;
732     std::vector<tcu::Vec4> vertices;
733 
734     switch (testParams.stage)
735     {
736     case VK_SHADER_STAGE_VERTEX_BIT:
737     {
738         const float z = 0.0f;
739         const float w = 1.0f;
740 
741         vertices.reserve(3 * height * width);
742 
743         for (uint32_t y = 0; y < height; ++y)
744             for (uint32_t x = 0; x < width; ++x)
745             {
746                 const float x0 = float(x + 0) / float(width);
747                 const float y0 = float(y + 0) / float(height);
748                 const float x1 = float(x + 1) / float(width);
749                 const float y1 = float(y + 1) / float(height);
750                 const float xm = (x0 + x1) / 2.0f;
751                 const float ym = (y0 + y1) / 2.0f;
752 
753                 vertices.push_back(tcu::Vec4(x0, y0, z, w));
754                 vertices.push_back(tcu::Vec4(xm, y1, z, w));
755                 vertices.push_back(tcu::Vec4(x1, ym, z, w));
756             }
757 
758         break;
759     }
760 
761     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
762     {
763         const float z     = 0.0f;
764         const float w     = 1.0f;
765         const tcu::Vec4 a = tcu::Vec4(-1.0f, -1.0f, z, w);
766         const tcu::Vec4 b = tcu::Vec4(+1.0f, -1.0f, z, w);
767         const tcu::Vec4 c = tcu::Vec4(+1.0f, +1.0f, z, w);
768         const tcu::Vec4 d = tcu::Vec4(-1.0f, +1.0f, z, w);
769 
770         vertices.push_back(a);
771         vertices.push_back(b);
772         vertices.push_back(c);
773         vertices.push_back(d);
774 
775         break;
776     }
777 
778     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
779     {
780         const float z     = 0.0f;
781         const float w     = 1.0f;
782         const tcu::Vec4 a = tcu::Vec4(-1.0f, -1.0f, z, w);
783         const tcu::Vec4 b = tcu::Vec4(+1.0f, -1.0f, z, w);
784         const tcu::Vec4 c = tcu::Vec4(+1.0f, +1.0f, z, w);
785         const tcu::Vec4 d = tcu::Vec4(-1.0f, +1.0f, z, w);
786 
787         vertices.push_back(a);
788         vertices.push_back(b);
789         vertices.push_back(c);
790         vertices.push_back(d);
791 
792         break;
793     }
794 
795     case VK_SHADER_STAGE_GEOMETRY_BIT:
796     {
797         const float z = 0.0f;
798         const float w = 1.0f;
799 
800         vertices.reserve(3 * height * width);
801 
802         for (uint32_t y = 0; y < height; ++y)
803             for (uint32_t x = 0; x < width; ++x)
804             {
805                 const float x0 = float(x + 0) / float(width);
806                 const float y0 = float(y + 0) / float(height);
807                 const float x1 = float(x + 1) / float(width);
808                 const float y1 = float(y + 1) / float(height);
809                 const float xm = (x0 + x1) / 2.0f;
810                 const float ym = (y0 + y1) / 2.0f;
811 
812                 vertices.push_back(tcu::Vec4(x0, y0, z, w));
813                 vertices.push_back(tcu::Vec4(xm, y1, z, w));
814                 vertices.push_back(tcu::Vec4(x1, ym, z, w));
815             }
816 
817         break;
818     }
819 
820     case VK_SHADER_STAGE_FRAGMENT_BIT:
821     {
822         const float z     = 1.0f;
823         const float w     = 1.0f;
824         const tcu::Vec4 a = tcu::Vec4(-1.0f, -1.0f, z, w);
825         const tcu::Vec4 b = tcu::Vec4(+1.0f, -1.0f, z, w);
826         const tcu::Vec4 c = tcu::Vec4(-1.0f, +1.0f, z, w);
827         const tcu::Vec4 d = tcu::Vec4(+1.0f, +1.0f, z, w);
828 
829         vertices.push_back(a);
830         vertices.push_back(b);
831         vertices.push_back(c);
832 
833         vertices.push_back(b);
834         vertices.push_back(c);
835         vertices.push_back(d);
836 
837         break;
838     }
839 
840     default:
841         TCU_THROW(InternalError, "Unknown stage");
842     }
843 
844     // Initialize vertex buffer
845     {
846         const VkDeviceSize vertexBufferSize = sizeof(vertices[0][0]) * vertices[0].SIZE * vertices.size();
847         const VkBufferCreateInfo vertexBufferCreateInfo =
848             makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
849 
850         m_vertexCount       = static_cast<uint32_t>(vertices.size());
851         m_vertexBuffer      = createBuffer(vkd, device, &vertexBufferCreateInfo);
852         m_vertexBufferAlloc = bindBuffer(vkd, device, allocator, *m_vertexBuffer, vk::MemoryRequirement::HostVisible);
853 
854         deMemcpy(m_vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexBufferSize);
855         flushAlloc(vkd, device, *m_vertexBufferAlloc);
856     }
857 }
858 
makeGraphicsPipeline(const TestEnvironment & env,TestParams & testParams)859 Move<VkPipeline> GraphicsConfiguration::makeGraphicsPipeline(const TestEnvironment &env, TestParams &testParams)
860 {
861     const DeviceInterface &vkd = *env.vkd;
862     const VkDevice device      = env.device;
863     const bool tessStageTest   = (testParams.stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
864                                 testParams.stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
865     const VkPrimitiveTopology topology =
866         tessStageTest ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
867     const uint32_t patchControlPoints = tessStageTest ? 4 : 0;
868     const std::vector<VkViewport> viewports(1, makeViewport(testParams.width, testParams.height));
869     const std::vector<VkRect2D> scissors(1, makeRect2D(testParams.width, testParams.height));
870 
871     return vk::makeGraphicsPipeline(vkd, device, *m_pipelineLayout, *m_vertShaderModule, *m_tescShaderModule,
872                                     *m_teseShaderModule, *m_geomShaderModule, *m_fragShaderModule, *m_renderPass,
873                                     viewports, scissors, topology, 0, patchControlPoints);
874 }
875 
initConfiguration(const TestEnvironment & env,TestParams & testParams)876 void GraphicsConfiguration::initConfiguration(const TestEnvironment &env, TestParams &testParams)
877 {
878     const InstanceInterface &vki          = *env.vki;
879     const DeviceInterface &vkd            = *env.vkd;
880     const VkPhysicalDevice physicalDevice = env.physicalDevice;
881     const VkDevice device                 = env.device;
882     Allocator &allocator                  = *env.allocator;
883     vk::BinaryCollection &collection      = *env.binaryCollection;
884     VkShaderStageFlags shaders            = static_cast<VkShaderStageFlags>(0);
885     uint32_t shaderCount                  = 0;
886 
887     VkPhysicalDeviceFeatures features;
888     vki.getPhysicalDeviceFeatures(physicalDevice, &features);
889     const bool pointSizeRequired = features.shaderTessellationAndGeometryPointSize;
890 
891     if (collection.contains("vert"))
892         shaders |= VK_SHADER_STAGE_VERTEX_BIT;
893     if (collection.contains(getGeomName(pointSizeRequired)))
894         shaders |= VK_SHADER_STAGE_GEOMETRY_BIT;
895     if (collection.contains("tesc"))
896         shaders |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
897     if (collection.contains("tese"))
898         shaders |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
899     if (collection.contains("frag"))
900         shaders |= VK_SHADER_STAGE_FRAGMENT_BIT;
901 
902     for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
903         shaderCount++;
904 
905     if (collection.contains(getGeomName(!pointSizeRequired)))
906         --shaderCount;
907 
908     if (shaderCount != (uint32_t)dePop32(shaders))
909         TCU_THROW(InternalError, "Unused shaders detected in the collection");
910 
911     if (0 != (shaders & VK_SHADER_STAGE_VERTEX_BIT))
912         m_vertShaderModule = createShaderModule(vkd, device, collection.get("vert"), 0);
913     if (0 != (shaders & VK_SHADER_STAGE_GEOMETRY_BIT))
914         m_geomShaderModule = createShaderModule(vkd, device, collection.get(getGeomName(pointSizeRequired)), 0);
915     if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT))
916         m_tescShaderModule = createShaderModule(vkd, device, collection.get("tesc"), 0);
917     if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
918         m_teseShaderModule = createShaderModule(vkd, device, collection.get("tese"), 0);
919     if (0 != (shaders & VK_SHADER_STAGE_FRAGMENT_BIT))
920         m_fragShaderModule = createShaderModule(vkd, device, collection.get("frag"), 0);
921 
922     m_descriptorSetLayout =
923         DescriptorSetLayoutBuilder()
924             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL_GRAPHICS)
925             .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL_GRAPHICS)
926             .build(vkd, device);
927     m_descriptorPool = DescriptorPoolBuilder()
928                            .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
929                            .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
930                            .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
931     m_descriptorSet         = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
932     m_framebufferImage      = makeImage(vkd, device,
933                                         makeImageCreateInfo(m_framebufferFormat, testParams.width, testParams.height, 1u,
934                                                             VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
935     m_framebufferImageAlloc = bindImage(vkd, device, allocator, *m_framebufferImage, MemoryRequirement::Any);
936     m_framebufferAttachment =
937         makeImageView(vkd, device, *m_framebufferImage, VK_IMAGE_VIEW_TYPE_2D, m_framebufferFormat,
938                       makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
939     m_renderPass = makeRenderPass(vkd, device, m_framebufferFormat);
940     m_framebuffer =
941         makeFramebuffer(vkd, device, *m_renderPass, *m_framebufferAttachment, testParams.width, testParams.height);
942     m_pipelineLayout = makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
943     m_pipeline       = makeGraphicsPipeline(env, testParams);
944 
945     initVertexBuffer(env, testParams);
946 }
947 
fillCommandBuffer(const TestEnvironment & env,TestParams & testParams,VkCommandBuffer cmdBuffer,const VkAccelerationStructureKHR * rayQueryTopAccelerationStructurePtr,const VkDescriptorImageInfo & resultImageInfo)948 void GraphicsConfiguration::fillCommandBuffer(const TestEnvironment &env, TestParams &testParams,
949                                               VkCommandBuffer cmdBuffer,
950                                               const VkAccelerationStructureKHR *rayQueryTopAccelerationStructurePtr,
951                                               const VkDescriptorImageInfo &resultImageInfo)
952 {
953     const DeviceInterface &vkd                                                                         = *env.vkd;
954     const VkDevice device                                                                              = env.device;
955     const VkDeviceSize vertexBufferOffset                                                              = 0;
956     const VkWriteDescriptorSetAccelerationStructureKHR rayQueryAccelerationStructureWriteDescriptorSet = {
957         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, //  VkStructureType sType;
958         DE_NULL,                                                           //  const void* pNext;
959         1u,                                                                //  uint32_t accelerationStructureCount;
960         rayQueryTopAccelerationStructurePtr, //  const VkAccelerationStructureKHR* pAccelerationStructures;
961     };
962 
963     DescriptorSetUpdateBuilder()
964         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
965                      VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
966         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
967                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
968         .update(vkd, device);
969 
970     vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1,
971                               &m_descriptorSet.get(), 0, DE_NULL);
972     vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
973     vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
974 
975     beginRenderPass(vkd, cmdBuffer, *m_renderPass, *m_framebuffer,
976                     makeRect2D(0, 0, testParams.width, testParams.height), tcu::UVec4());
977 
978     vkd.cmdDraw(cmdBuffer, m_vertexCount, 1u, 0u, 0u);
979 
980     endRenderPass(vkd, cmdBuffer);
981 }
982 
983 class ComputeConfiguration : public PipelineConfiguration
984 {
985 public:
986     ComputeConfiguration();
~ComputeConfiguration()987     virtual ~ComputeConfiguration()
988     {
989     }
990 
991     static void checkSupport(Context &context, const TestParams &testParams);
992     static void initPrograms(SourceCollections &programCollection, const TestParams &testParams);
993 
994     virtual void initConfiguration(const TestEnvironment &env, TestParams &testParams) override;
995     virtual void fillCommandBuffer(const TestEnvironment &env, TestParams &testParams, VkCommandBuffer commandBuffer,
996                                    const VkAccelerationStructureKHR *rayQueryTopAccelerationStructurePtr,
997                                    const VkDescriptorImageInfo &resultImageInfo) override;
998 
999 protected:
1000     Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1001     Move<VkDescriptorPool> m_descriptorPool;
1002     Move<VkDescriptorSet> m_descriptorSet;
1003     Move<VkPipelineLayout> m_pipelineLayout;
1004 
1005     Move<VkShaderModule> m_shaderModule;
1006 
1007     Move<VkPipeline> m_pipeline;
1008 };
1009 
ComputeConfiguration()1010 ComputeConfiguration::ComputeConfiguration()
1011     : PipelineConfiguration()
1012     , m_descriptorSetLayout()
1013     , m_descriptorPool()
1014     , m_descriptorSet()
1015     , m_pipelineLayout()
1016 
1017     , m_shaderModule()
1018 
1019     , m_pipeline()
1020 {
1021 }
1022 
checkSupport(Context & context,const TestParams & testParams)1023 void ComputeConfiguration::checkSupport(Context &context, const TestParams &testParams)
1024 {
1025     DE_UNREF(context);
1026     DE_UNREF(testParams);
1027 }
1028 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)1029 void ComputeConfiguration::initPrograms(SourceCollections &programCollection, const TestParams &testParams)
1030 {
1031     DE_ASSERT(testParams.stage == VK_SHADER_STAGE_COMPUTE_BIT);
1032 
1033     if (testParams.isSPIRV)
1034     {
1035         const vk::SpirVAsmBuildOptions spvBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4,
1036                                                        true);
1037 
1038         programCollection.spirvAsmSources.add("comp")
1039             << testParams.testConfigShaderBodyText(testParams) << spvBuildOptions;
1040     }
1041     else
1042     {
1043         const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1044         const std::string testShaderBody = testParams.testConfigShaderBodyText(testParams);
1045         const std::string testBody       = "  ivec3       pos      = ivec3(gl_WorkGroupID);\n"
1046                                            "  ivec3       size     = ivec3(gl_NumWorkGroups);\n" +
1047                                      testShaderBody;
1048 
1049         std::stringstream css;
1050         css << "#version 460 core\n"
1051                "#extension GL_EXT_ray_query : require\n"
1052                "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1053                "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1054                "\n"
1055                "void main()\n"
1056                "{\n"
1057             << testBody << "}\n";
1058 
1059         programCollection.glslSources.add("comp")
1060             << glu::ComputeSource(updateRayTracingGLSL(css.str())) << buildOptions;
1061     }
1062 }
1063 
initConfiguration(const TestEnvironment & env,TestParams & testParams)1064 void ComputeConfiguration::initConfiguration(const TestEnvironment &env, TestParams &testParams)
1065 {
1066     DE_UNREF(testParams);
1067 
1068     const DeviceInterface &vkd       = *env.vkd;
1069     const VkDevice device            = env.device;
1070     vk::BinaryCollection &collection = *env.binaryCollection;
1071 
1072     m_descriptorSetLayout =
1073         DescriptorSetLayoutBuilder()
1074             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1075             .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_COMPUTE_BIT)
1076             .build(vkd, device);
1077     m_descriptorPool = DescriptorPoolBuilder()
1078                            .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1079                            .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1080                            .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1081     m_descriptorSet  = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
1082     m_pipelineLayout = makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
1083     m_shaderModule   = createShaderModule(vkd, device, collection.get("comp"), 0);
1084     m_pipeline       = makeComputePipeline(vkd, device, *m_pipelineLayout, *m_shaderModule);
1085 }
1086 
fillCommandBuffer(const TestEnvironment & env,TestParams & testParams,VkCommandBuffer cmdBuffer,const VkAccelerationStructureKHR * rayQueryTopAccelerationStructurePtr,const VkDescriptorImageInfo & resultImageInfo)1087 void ComputeConfiguration::fillCommandBuffer(const TestEnvironment &env, TestParams &testParams,
1088                                              VkCommandBuffer cmdBuffer,
1089                                              const VkAccelerationStructureKHR *rayQueryTopAccelerationStructurePtr,
1090                                              const VkDescriptorImageInfo &resultImageInfo)
1091 {
1092     const DeviceInterface &vkd                                                                         = *env.vkd;
1093     const VkDevice device                                                                              = env.device;
1094     const VkWriteDescriptorSetAccelerationStructureKHR rayQueryAccelerationStructureWriteDescriptorSet = {
1095         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, //  VkStructureType sType;
1096         DE_NULL,                                                           //  const void* pNext;
1097         1u,                                                                //  uint32_t accelerationStructureCount;
1098         rayQueryTopAccelerationStructurePtr, //  const VkAccelerationStructureKHR* pAccelerationStructures;
1099     };
1100 
1101     DescriptorSetUpdateBuilder()
1102         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
1103                      VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
1104         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
1105                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
1106         .update(vkd, device);
1107 
1108     vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1,
1109                               &m_descriptorSet.get(), 0, DE_NULL);
1110 
1111     vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline.get());
1112 
1113     vkd.cmdDispatch(cmdBuffer, testParams.width, testParams.height, 1);
1114 }
1115 
1116 class RayTracingConfiguration : public PipelineConfiguration
1117 {
1118 public:
1119     RayTracingConfiguration();
~RayTracingConfiguration()1120     virtual ~RayTracingConfiguration()
1121     {
1122     }
1123 
1124     static void checkSupport(Context &context, const TestParams &testParams);
1125     static void initPrograms(SourceCollections &programCollection, const TestParams &testParams);
1126 
1127     virtual void initConfiguration(const TestEnvironment &env, TestParams &testParams) override;
1128     virtual void fillCommandBuffer(const TestEnvironment &env, TestParams &testParams, VkCommandBuffer commandBuffer,
1129                                    const VkAccelerationStructureKHR *rayQueryTopAccelerationStructurePtr,
1130                                    const VkDescriptorImageInfo &resultImageInfo) override;
1131 
1132 protected:
1133     de::MovePtr<BufferWithMemory> createShaderBindingTable(const InstanceInterface &vki, const DeviceInterface &vkd,
1134                                                            const VkDevice device, const VkPhysicalDevice physicalDevice,
1135                                                            const VkPipeline pipeline, Allocator &allocator,
1136                                                            de::MovePtr<RayTracingPipeline> &rayTracingPipeline,
1137                                                            const uint32_t group);
1138 
1139 protected:
1140     uint32_t m_shaders;
1141     uint32_t m_raygenShaderGroup;
1142     uint32_t m_missShaderGroup;
1143     uint32_t m_hitShaderGroup;
1144     uint32_t m_callableShaderGroup;
1145     uint32_t m_shaderGroupCount;
1146 
1147     Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1148     Move<VkDescriptorPool> m_descriptorPool;
1149     Move<VkDescriptorSet> m_descriptorSet;
1150     Move<VkPipelineLayout> m_pipelineLayout;
1151 
1152     de::MovePtr<RayTracingPipeline> m_rayTracingPipeline;
1153     Move<VkPipeline> m_pipeline;
1154 
1155     de::MovePtr<BufferWithMemory> m_raygenShaderBindingTable;
1156     de::MovePtr<BufferWithMemory> m_hitShaderBindingTable;
1157     de::MovePtr<BufferWithMemory> m_missShaderBindingTable;
1158     de::MovePtr<BufferWithMemory> m_callableShaderBindingTable;
1159 
1160     VkStridedDeviceAddressRegionKHR m_raygenShaderBindingTableRegion;
1161     VkStridedDeviceAddressRegionKHR m_missShaderBindingTableRegion;
1162     VkStridedDeviceAddressRegionKHR m_hitShaderBindingTableRegion;
1163     VkStridedDeviceAddressRegionKHR m_callableShaderBindingTableRegion;
1164 
1165     de::SharedPtr<BottomLevelAccelerationStructure> m_bottomLevelAccelerationStructure;
1166     de::SharedPtr<TopLevelAccelerationStructure> m_topLevelAccelerationStructure;
1167 };
1168 
RayTracingConfiguration()1169 RayTracingConfiguration::RayTracingConfiguration()
1170     : m_shaders(0)
1171     , m_raygenShaderGroup(~0u)
1172     , m_missShaderGroup(~0u)
1173     , m_hitShaderGroup(~0u)
1174     , m_callableShaderGroup(~0u)
1175     , m_shaderGroupCount(0)
1176 
1177     , m_descriptorSetLayout()
1178     , m_descriptorPool()
1179     , m_descriptorSet()
1180     , m_pipelineLayout()
1181 
1182     , m_rayTracingPipeline()
1183     , m_pipeline()
1184 
1185     , m_raygenShaderBindingTable()
1186     , m_hitShaderBindingTable()
1187     , m_missShaderBindingTable()
1188     , m_callableShaderBindingTable()
1189 
1190     , m_raygenShaderBindingTableRegion()
1191     , m_missShaderBindingTableRegion()
1192     , m_hitShaderBindingTableRegion()
1193     , m_callableShaderBindingTableRegion()
1194 
1195     , m_bottomLevelAccelerationStructure()
1196     , m_topLevelAccelerationStructure()
1197 {
1198 }
1199 
checkSupport(Context & context,const TestParams & testParams)1200 void RayTracingConfiguration::checkSupport(Context &context, const TestParams &testParams)
1201 {
1202     DE_UNREF(testParams);
1203 
1204     context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1205     const VkPhysicalDeviceRayTracingPipelineFeaturesKHR &rayTracingPipelineFeaturesKHR =
1206         context.getRayTracingPipelineFeatures();
1207     if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == false)
1208         TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1209 }
1210 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)1211 void RayTracingConfiguration::initPrograms(SourceCollections &programCollection, const TestParams &testParams)
1212 {
1213     const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1214 
1215     const std::string testShaderBody = testParams.testConfigShaderBodyText(testParams);
1216     const std::string testBody       = "  ivec3       pos      = ivec3(gl_LaunchIDEXT);\n"
1217                                        "  ivec3       size     = ivec3(gl_LaunchSizeEXT);\n" +
1218                                  testShaderBody;
1219 
1220     switch (testParams.stage)
1221     {
1222     case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
1223     {
1224         std::stringstream css;
1225         css << "#version 460 core\n"
1226                "#extension GL_EXT_ray_tracing : require\n"
1227                "#extension GL_EXT_ray_query : require\n"
1228                "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1229                "layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1230                "\n"
1231                "void main()\n"
1232                "{\n"
1233             << testBody << "}\n";
1234 
1235         programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1236 
1237         break;
1238     }
1239 
1240     case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
1241     {
1242         programCollection.glslSources.add("rgen")
1243             << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1244 
1245         {
1246             std::stringstream css;
1247             css << "#version 460 core\n"
1248                    "#extension GL_EXT_ray_tracing : require\n"
1249                    "#extension GL_EXT_ray_query : require\n"
1250                    "hitAttributeEXT vec3 attribs;\n"
1251                    "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1252                    "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1253                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT "
1254                    "rayQueryTopLevelAccelerationStructure;\n"
1255                    "\n"
1256                    "void main()\n"
1257                    "{\n"
1258                 << testBody << "}\n";
1259 
1260             programCollection.glslSources.add("ahit")
1261                 << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1262         }
1263 
1264         programCollection.glslSources.add("chit")
1265             << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1266         programCollection.glslSources.add("miss")
1267             << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1268 
1269         break;
1270     }
1271 
1272     case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
1273     {
1274         programCollection.glslSources.add("rgen")
1275             << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1276 
1277         {
1278             std::stringstream css;
1279             css << "#version 460 core\n"
1280                    "#extension GL_EXT_ray_tracing : require\n"
1281                    "#extension GL_EXT_ray_query : require\n"
1282                    "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1283                    "hitAttributeEXT vec3 attribs;\n"
1284                    "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1285                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT "
1286                    "rayQueryTopLevelAccelerationStructure;\n"
1287                    "\n"
1288                    "void main()\n"
1289                    "{\n"
1290                 << testBody << "}\n";
1291 
1292             programCollection.glslSources.add("chit")
1293                 << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1294         }
1295 
1296         programCollection.glslSources.add("ahit")
1297             << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1298         programCollection.glslSources.add("miss")
1299             << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1300 
1301         break;
1302     }
1303 
1304     case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
1305     {
1306         programCollection.glslSources.add("rgen")
1307             << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1308 
1309         {
1310             std::stringstream css;
1311             css << "#version 460 core\n"
1312                    "#extension GL_EXT_ray_tracing : require\n"
1313                    "#extension GL_EXT_ray_query : require\n"
1314                    "hitAttributeEXT vec3 hitAttribute;\n"
1315                    "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1316                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT "
1317                    "rayQueryTopLevelAccelerationStructure;\n"
1318                    "\n"
1319                    "void main()\n"
1320                    "{\n"
1321                 << testBody
1322                 << "  hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n"
1323                    "  reportIntersectionEXT(1.0f, 0);\n"
1324                    "}\n";
1325 
1326             programCollection.glslSources.add("sect")
1327                 << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1328         }
1329 
1330         programCollection.glslSources.add("ahit")
1331             << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1332         programCollection.glslSources.add("chit")
1333             << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1334         programCollection.glslSources.add("miss")
1335             << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1336 
1337         break;
1338     }
1339 
1340     case VK_SHADER_STAGE_MISS_BIT_KHR:
1341     {
1342         programCollection.glslSources.add("rgen")
1343             << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1344 
1345         {
1346             std::stringstream css;
1347             css << "#version 460 core\n"
1348                    "#extension GL_EXT_ray_tracing : require\n"
1349                    "#extension GL_EXT_ray_query : require\n"
1350                    "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1351                    "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1352                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT "
1353                    "rayQueryTopLevelAccelerationStructure;\n"
1354                    "\n"
1355                    "void main()\n"
1356                    "{\n"
1357                 << testBody << "}\n";
1358 
1359             programCollection.glslSources.add("miss")
1360                 << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1361         }
1362 
1363         programCollection.glslSources.add("ahit")
1364             << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1365         programCollection.glslSources.add("chit")
1366             << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1367 
1368         break;
1369     }
1370 
1371     case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
1372     {
1373         {
1374             std::stringstream css;
1375             css << "#version 460 core\n"
1376                    "#extension GL_EXT_ray_tracing : require\n"
1377                    "#extension GL_EXT_ray_query : require\n"
1378                    "layout(location = 0) callableDataEXT float dummy;"
1379                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1380                    "\n"
1381                    "void main()\n"
1382                    "{\n"
1383                    "  executeCallableEXT(0, 0);\n"
1384                    "}\n";
1385 
1386             programCollection.glslSources.add("rgen")
1387                 << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1388         }
1389 
1390         {
1391             std::stringstream css;
1392             css << "#version 460 core\n"
1393                    "#extension GL_EXT_ray_tracing : require\n"
1394                    "#extension GL_EXT_ray_query : require\n"
1395                    "layout(location = 0) callableDataInEXT float dummy;"
1396                    "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1397                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT "
1398                    "rayQueryTopLevelAccelerationStructure;\n"
1399                    "\n"
1400                    "void main()\n"
1401                    "{\n"
1402                 << testBody << "}\n";
1403 
1404             programCollection.glslSources.add("call")
1405                 << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
1406         }
1407 
1408         programCollection.glslSources.add("ahit")
1409             << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1410         programCollection.glslSources.add("chit")
1411             << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1412         programCollection.glslSources.add("miss")
1413             << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1414 
1415         break;
1416     }
1417 
1418     default:
1419         TCU_THROW(InternalError, "Unknown stage");
1420     }
1421 }
1422 
createShaderBindingTable(const InstanceInterface & vki,const DeviceInterface & vkd,const VkDevice device,const VkPhysicalDevice physicalDevice,const VkPipeline pipeline,Allocator & allocator,de::MovePtr<RayTracingPipeline> & rayTracingPipeline,const uint32_t group)1423 de::MovePtr<BufferWithMemory> RayTracingConfiguration::createShaderBindingTable(
1424     const InstanceInterface &vki, const DeviceInterface &vkd, const VkDevice device,
1425     const VkPhysicalDevice physicalDevice, const VkPipeline pipeline, Allocator &allocator,
1426     de::MovePtr<RayTracingPipeline> &rayTracingPipeline, const uint32_t group)
1427 {
1428     de::MovePtr<BufferWithMemory> shaderBindingTable;
1429 
1430     if (group < m_shaderGroupCount)
1431     {
1432         const uint32_t shaderGroupHandleSize    = getShaderGroupHandleSize(vki, physicalDevice);
1433         const uint32_t shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice);
1434 
1435         shaderBindingTable = rayTracingPipeline->createShaderBindingTable(
1436             vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, group, 1u);
1437     }
1438 
1439     return shaderBindingTable;
1440 }
1441 
initConfiguration(const TestEnvironment & env,TestParams & testParams)1442 void RayTracingConfiguration::initConfiguration(const TestEnvironment &env, TestParams &testParams)
1443 {
1444     DE_UNREF(testParams);
1445 
1446     const InstanceInterface &vki          = *env.vki;
1447     const DeviceInterface &vkd            = *env.vkd;
1448     const VkDevice device                 = env.device;
1449     const VkPhysicalDevice physicalDevice = env.physicalDevice;
1450     vk::BinaryCollection &collection      = *env.binaryCollection;
1451     Allocator &allocator                  = *env.allocator;
1452     const uint32_t shaderGroupHandleSize  = getShaderGroupHandleSize(vki, physicalDevice);
1453     const VkShaderStageFlags hitStages =
1454         VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
1455     uint32_t shaderCount = 0;
1456 
1457     m_shaderGroupCount = 0;
1458 
1459     if (collection.contains("rgen"))
1460         m_shaders |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
1461     if (collection.contains("ahit"))
1462         m_shaders |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
1463     if (collection.contains("chit"))
1464         m_shaders |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
1465     if (collection.contains("miss"))
1466         m_shaders |= VK_SHADER_STAGE_MISS_BIT_KHR;
1467     if (collection.contains("sect"))
1468         m_shaders |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
1469     if (collection.contains("call"))
1470         m_shaders |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
1471 
1472     for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
1473         shaderCount++;
1474 
1475     if (shaderCount != (uint32_t)dePop32(m_shaders))
1476         TCU_THROW(InternalError, "Unused shaders detected in the collection");
1477 
1478     if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))
1479         m_raygenShaderGroup = m_shaderGroupCount++;
1480 
1481     if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))
1482         m_missShaderGroup = m_shaderGroupCount++;
1483 
1484     if (0 != (m_shaders & hitStages))
1485         m_hitShaderGroup = m_shaderGroupCount++;
1486 
1487     if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))
1488         m_callableShaderGroup = m_shaderGroupCount++;
1489 
1490     m_rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
1491 
1492     m_descriptorSetLayout = DescriptorSetLayoutBuilder()
1493                                 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
1494                                 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1495                                 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1496                                 .build(vkd, device);
1497     m_descriptorPool = DescriptorPoolBuilder()
1498                            .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1499                            .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1500                            .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1501                            .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1502     m_descriptorSet = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
1503 
1504     if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))
1505         m_rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR,
1506                                         createShaderModule(vkd, device, collection.get("rgen"), 0),
1507                                         m_raygenShaderGroup);
1508     if (0 != (m_shaders & VK_SHADER_STAGE_ANY_HIT_BIT_KHR))
1509         m_rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR,
1510                                         createShaderModule(vkd, device, collection.get("ahit"), 0), m_hitShaderGroup);
1511     if (0 != (m_shaders & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR))
1512         m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,
1513                                         createShaderModule(vkd, device, collection.get("chit"), 0), m_hitShaderGroup);
1514     if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))
1515         m_rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR,
1516                                         createShaderModule(vkd, device, collection.get("miss"), 0), m_missShaderGroup);
1517     if (0 != (m_shaders & VK_SHADER_STAGE_INTERSECTION_BIT_KHR))
1518         m_rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR,
1519                                         createShaderModule(vkd, device, collection.get("sect"), 0), m_hitShaderGroup);
1520     if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))
1521         m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR,
1522                                         createShaderModule(vkd, device, collection.get("call"), 0),
1523                                         m_callableShaderGroup);
1524 
1525     m_pipelineLayout = makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
1526     m_pipeline       = m_rayTracingPipeline->createPipeline(vkd, device, *m_pipelineLayout);
1527 
1528     m_raygenShaderBindingTable   = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator,
1529                                                             m_rayTracingPipeline, m_raygenShaderGroup);
1530     m_missShaderBindingTable     = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator,
1531                                                             m_rayTracingPipeline, m_missShaderGroup);
1532     m_hitShaderBindingTable      = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator,
1533                                                             m_rayTracingPipeline, m_hitShaderGroup);
1534     m_callableShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator,
1535                                                             m_rayTracingPipeline, m_callableShaderGroup);
1536 
1537     m_raygenShaderBindingTableRegion =
1538         m_raygenShaderBindingTable.get() != NULL ?
1539             makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, m_raygenShaderBindingTable->get(), 0),
1540                                               shaderGroupHandleSize, shaderGroupHandleSize) :
1541             makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1542     m_missShaderBindingTableRegion =
1543         m_missShaderBindingTable.get() != NULL ?
1544             makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, m_missShaderBindingTable->get(), 0),
1545                                               shaderGroupHandleSize, shaderGroupHandleSize) :
1546             makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1547     m_hitShaderBindingTableRegion =
1548         m_hitShaderBindingTable.get() != NULL ?
1549             makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, m_hitShaderBindingTable->get(), 0),
1550                                               shaderGroupHandleSize, shaderGroupHandleSize) :
1551             makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1552     m_callableShaderBindingTableRegion =
1553         m_callableShaderBindingTable.get() != NULL ?
1554             makeStridedDeviceAddressRegionKHR(
1555                 getBufferDeviceAddress(vkd, device, m_callableShaderBindingTable->get(), 0), shaderGroupHandleSize,
1556                 shaderGroupHandleSize) :
1557             makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1558 }
1559 
fillCommandBuffer(const TestEnvironment & env,TestParams & testParams,VkCommandBuffer commandBuffer,const VkAccelerationStructureKHR * rayQueryTopAccelerationStructurePtr,const VkDescriptorImageInfo & resultImageInfo)1560 void RayTracingConfiguration::fillCommandBuffer(const TestEnvironment &env, TestParams &testParams,
1561                                                 VkCommandBuffer commandBuffer,
1562                                                 const VkAccelerationStructureKHR *rayQueryTopAccelerationStructurePtr,
1563                                                 const VkDescriptorImageInfo &resultImageInfo)
1564 {
1565     const DeviceInterface &vkd = *env.vkd;
1566     const VkDevice device      = env.device;
1567     Allocator &allocator       = *env.allocator;
1568     de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure =
1569         makeBottomLevelAccelerationStructure();
1570     de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1571 
1572     m_bottomLevelAccelerationStructure =
1573         de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release());
1574     m_bottomLevelAccelerationStructure->setDefaultGeometryData(testParams.stage);
1575     m_bottomLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1576 
1577     m_topLevelAccelerationStructure =
1578         de::SharedPtr<TopLevelAccelerationStructure>(topLevelAccelerationStructure.release());
1579     m_topLevelAccelerationStructure->setInstanceCount(1);
1580     m_topLevelAccelerationStructure->addInstance(m_bottomLevelAccelerationStructure);
1581     m_topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1582 
1583     const TopLevelAccelerationStructure *topLevelAccelerationStructurePtr = m_topLevelAccelerationStructure.get();
1584     const VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = {
1585         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, //  VkStructureType sType;
1586         DE_NULL,                                                           //  const void* pNext;
1587         1u,                                                                //  uint32_t accelerationStructureCount;
1588         topLevelAccelerationStructurePtr->getPtr(), //  const VkAccelerationStructureKHR* pAccelerationStructures;
1589     };
1590     const VkWriteDescriptorSetAccelerationStructureKHR rayQueryAccelerationStructureWriteDescriptorSet = {
1591         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, //  VkStructureType sType;
1592         DE_NULL,                                                           //  const void* pNext;
1593         1u,                                                                //  uint32_t accelerationStructureCount;
1594         rayQueryTopAccelerationStructurePtr, //  const VkAccelerationStructureKHR* pAccelerationStructures;
1595     };
1596 
1597     DescriptorSetUpdateBuilder()
1598         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
1599                      VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
1600         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
1601                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1602         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u),
1603                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
1604         .update(vkd, device);
1605 
1606     vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *m_pipelineLayout, 0, 1,
1607                               &m_descriptorSet.get(), 0, DE_NULL);
1608 
1609     vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, m_pipeline.get());
1610 
1611     cmdTraceRays(vkd, commandBuffer, &m_raygenShaderBindingTableRegion, &m_missShaderBindingTableRegion,
1612                  &m_hitShaderBindingTableRegion, &m_callableShaderBindingTableRegion, testParams.width,
1613                  testParams.height, 1);
1614 }
1615 
prepareTestEnvironment(Context & context)1616 void TestConfiguration::prepareTestEnvironment(Context &context)
1617 {
1618     // By default, all data comes from the context.
1619     m_testEnvironment = de::MovePtr<TestEnvironment>(new TestEnvironment{
1620         &context.getInstanceInterface(),        // const InstanceInterface* vki;
1621         context.getPhysicalDevice(),            // VkPhysicalDevice physicalDevice;
1622         &context.getDeviceInterface(),          // const DeviceInterface* vkd;
1623         context.getDevice(),                    // VkDevice device;
1624         &context.getDefaultAllocator(),         // Allocator* allocator;
1625         context.getUniversalQueue(),            // VkQueue queue;
1626         context.getUniversalQueueFamilyIndex(), // uint32_t queueFamilyIndex;
1627         &context.getBinaryCollection(),         // BinaryCollection* binaryCollection;
1628         &context.getTestContext().getLog(),     // tcu::TestLog* log;
1629     });
1630 }
1631 
getTestEnvironment() const1632 const TestEnvironment &TestConfiguration::getTestEnvironment() const
1633 {
1634     return *m_testEnvironment;
1635 }
1636 
verify(BufferWithMemory * resultBuffer,TestParams & testParams)1637 bool TestConfiguration::verify(BufferWithMemory *resultBuffer, TestParams &testParams)
1638 {
1639     tcu::TestLog &log          = *(m_testEnvironment->log);
1640     const uint32_t width       = testParams.width;
1641     const uint32_t height      = testParams.height;
1642     const int32_t *resultPtr   = (int32_t *)resultBuffer->getAllocation().getHostPtr();
1643     const int32_t *expectedPtr = m_expected.data();
1644     uint32_t failures          = 0;
1645     uint32_t pos               = 0;
1646 
1647     for (uint32_t y = 0; y < height; ++y)
1648         for (uint32_t x = 0; x < width; ++x)
1649         {
1650             if (resultPtr[pos] != expectedPtr[pos])
1651                 failures++;
1652 
1653             pos++;
1654         }
1655 
1656     if (failures != 0)
1657     {
1658         const char *names[] = {"Retrieved:", "Expected:"};
1659 
1660         for (uint32_t n = 0; n < 2; ++n)
1661         {
1662             std::stringstream css;
1663 
1664             pos = 0;
1665 
1666             for (uint32_t y = 0; y < height; ++y)
1667             {
1668                 for (uint32_t x = 0; x < width; ++x)
1669                 {
1670                     if (resultPtr[pos] != expectedPtr[pos])
1671                         css << std::setw(12) << (n == 0 ? resultPtr[pos] : expectedPtr[pos]) << ",";
1672                     else
1673                         css << "____________,";
1674 
1675                     pos++;
1676                 }
1677 
1678                 css << std::endl;
1679             }
1680 
1681             log << tcu::TestLog::Message << names[n] << tcu::TestLog::EndMessage;
1682             log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
1683         }
1684     }
1685 
1686     return (failures == 0);
1687 }
1688 
verify(BufferWithMemory * resultBuffer,TestParams & testParams)1689 bool TestConfigurationFloat::verify(BufferWithMemory *resultBuffer, TestParams &testParams)
1690 {
1691     tcu::TestLog &log          = *(m_testEnvironment->log);
1692     const float eps            = float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
1693     const uint32_t width       = testParams.width;
1694     const uint32_t height      = testParams.height;
1695     const int32_t *resultPtr   = (int32_t *)resultBuffer->getAllocation().getHostPtr();
1696     const int32_t *expectedPtr = m_expected.data();
1697     uint32_t failures          = 0;
1698     uint32_t pos               = 0;
1699 
1700     for (uint32_t y = 0; y < height; ++y)
1701         for (uint32_t x = 0; x < width; ++x)
1702         {
1703             const float retrievedValue = float(resultPtr[pos]) / float(FIXED_POINT_DIVISOR);
1704             const float expectedValue  = float(expectedPtr[pos]) / float(FIXED_POINT_DIVISOR);
1705 
1706             if (deFloatAbs(retrievedValue - expectedValue) > eps)
1707                 failures++;
1708 
1709             pos++;
1710         }
1711 
1712     if (failures != 0)
1713     {
1714         const char *names[] = {"Retrieved:", "Expected:"};
1715 
1716         for (uint32_t n = 0; n < 2; ++n)
1717         {
1718             std::stringstream css;
1719 
1720             pos = 0;
1721 
1722             for (uint32_t y = 0; y < height; ++y)
1723             {
1724                 for (uint32_t x = 0; x < width; ++x)
1725                 {
1726                     const float retrievedValue = float(resultPtr[pos]) / float(FIXED_POINT_DIVISOR);
1727                     const float expectedValue  = float(expectedPtr[pos]) / float(FIXED_POINT_DIVISOR);
1728 
1729                     if (deFloatAbs(retrievedValue - expectedValue) > eps)
1730                         css << std::setprecision(8) << std::setw(12) << (n == 0 ? retrievedValue : expectedValue)
1731                             << ",";
1732                     else
1733                         css << "____________,";
1734 
1735                     pos++;
1736                 }
1737 
1738                 css << std::endl;
1739             }
1740 
1741             log << tcu::TestLog::Message << names[n] << tcu::TestLog::EndMessage;
1742             log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
1743         }
1744     }
1745 
1746     return (failures == 0);
1747 }
1748 
verify(BufferWithMemory * resultBuffer,TestParams & testParams)1749 bool TestConfigurationVector::verify(BufferWithMemory *resultBuffer, TestParams &testParams)
1750 {
1751     tcu::TestLog &log          = *(m_testEnvironment->log);
1752     const float eps            = float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
1753     const uint32_t width       = testParams.width;
1754     const uint32_t height      = testParams.height;
1755     const uint32_t depth       = 3u; // vec3
1756     const int32_t *resultPtr   = (int32_t *)resultBuffer->getAllocation().getHostPtr();
1757     const int32_t *expectedPtr = m_expected.data();
1758     uint32_t failures          = 0;
1759     uint32_t pos               = 0;
1760 
1761     if (m_useStrictComponentMatching)
1762     {
1763         for (uint32_t z = 0; z < depth; ++z)
1764         {
1765             for (uint32_t y = 0; y < height; ++y)
1766             {
1767                 for (uint32_t x = 0; x < width; ++x)
1768                 {
1769                     const float retrievedValue = float(resultPtr[pos]) / float(FIXED_POINT_DIVISOR);
1770                     const float expectedValue  = float(expectedPtr[pos]) / float(FIXED_POINT_DIVISOR);
1771 
1772                     if (deFloatAbs(retrievedValue - expectedValue) > eps)
1773                         failures++;
1774 
1775                     ++pos;
1776                 }
1777             }
1778         }
1779     }
1780     else
1781     {
1782         // This path is taken for barycentric coords, which can be returned in any order.
1783         //
1784         // We need to ensure that:
1785         // 1. Each component value found in the retrieved value has a match in the expected value vec.
1786         // 2. Only one mapping exists per each component in the expected value vec.
1787         const auto nSquares = width * height;
1788 
1789         for (uint32_t y = 0; y < height; ++y)
1790         {
1791             for (uint32_t x = 0; x < width; ++x)
1792             {
1793                 bool expectedVectorComponentUsed[3] = {false};
1794                 const auto squareNdx                = y * width + x;
1795 
1796                 for (uint32_t retrievedComponentNdx = 0; retrievedComponentNdx < 3 /* vec3 */; ++retrievedComponentNdx)
1797                 {
1798                     const float retrievedValue =
1799                         float(resultPtr[nSquares * retrievedComponentNdx + squareNdx]) / float(FIXED_POINT_DIVISOR);
1800 
1801                     for (uint32_t expectedComponentNdx = 0; expectedComponentNdx < 3 /* vec3 */; ++expectedComponentNdx)
1802                     {
1803                         const float expectedValue = float(expectedPtr[nSquares * expectedComponentNdx + squareNdx]) /
1804                                                     float(FIXED_POINT_DIVISOR);
1805 
1806                         if (deFloatAbs(retrievedValue - expectedValue) <= eps &&
1807                             expectedVectorComponentUsed[expectedComponentNdx] == false)
1808                         {
1809                             expectedVectorComponentUsed[expectedComponentNdx] = true;
1810 
1811                             break;
1812                         }
1813 
1814                         ++pos;
1815                     }
1816                 }
1817 
1818                 if (expectedVectorComponentUsed[0] == false || expectedVectorComponentUsed[1] == false ||
1819                     expectedVectorComponentUsed[2] == false)
1820                 {
1821                     ++failures;
1822                 }
1823             }
1824         }
1825     }
1826 
1827     if (failures != 0)
1828     {
1829         const char *names[] = {
1830             "Retrieved", (m_useStrictComponentMatching) ? "Expected" : "Expected (component order is irrelevant)"};
1831 
1832         std::stringstream css;
1833 
1834         for (uint32_t y = 0; y < height; ++y)
1835         {
1836             for (uint32_t x = 0; x < width; ++x)
1837             {
1838                 for (uint32_t n = 0; n < 2; ++n)
1839                 {
1840                     css << names[n] << " at (" << x << "," << y << ") {";
1841 
1842                     for (uint32_t z = 0; z < depth; ++z)
1843                     {
1844                         pos = x + width * (y + height * z);
1845 
1846                         const float retrievedValue = float(resultPtr[pos]) / float(FIXED_POINT_DIVISOR);
1847                         const float expectedValue  = float(expectedPtr[pos]) / float(FIXED_POINT_DIVISOR);
1848 
1849                         if (deFloatAbs(retrievedValue - expectedValue) > eps || m_useStrictComponentMatching == false)
1850                         {
1851                             css << std::setprecision(8) << std::setw(12) << (n == 0 ? retrievedValue : expectedValue)
1852                                 << ",";
1853                         }
1854                         else
1855                             css << "____________,";
1856                     }
1857 
1858                     css << "}" << std::endl;
1859                 }
1860             }
1861         }
1862 
1863         log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
1864     }
1865 
1866     return failures == 0;
1867 }
1868 
verify(BufferWithMemory * resultBuffer,TestParams & testParams)1869 bool TestConfigurationMatrix::verify(BufferWithMemory *resultBuffer, TestParams &testParams)
1870 {
1871     tcu::TestLog &log          = *(m_testEnvironment->log);
1872     const float eps            = float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
1873     const uint32_t width       = testParams.width;
1874     const uint32_t height      = testParams.height;
1875     const uint32_t depth       = 12u; // mat3x4 or mat4x3
1876     const int32_t *resultPtr   = (int32_t *)resultBuffer->getAllocation().getHostPtr();
1877     const int32_t *expectedPtr = m_expected.data();
1878     uint32_t failures          = 0;
1879     uint32_t pos               = 0;
1880 
1881     for (uint32_t z = 0; z < depth; ++z)
1882         for (uint32_t y = 0; y < height; ++y)
1883             for (uint32_t x = 0; x < width; ++x)
1884             {
1885                 const float retrievedValue = float(resultPtr[pos]) / float(FIXED_POINT_DIVISOR);
1886                 const float expectedValue  = float(expectedPtr[pos]) / float(FIXED_POINT_DIVISOR);
1887 
1888                 if (deFloatAbs(retrievedValue - expectedValue) > eps)
1889                     failures++;
1890 
1891                 ++pos;
1892             }
1893 
1894     if (failures != 0)
1895     {
1896         const char *names[] = {"Retrieved", "Expected"};
1897         std::stringstream css;
1898 
1899         for (uint32_t y = 0; y < height; ++y)
1900         {
1901             for (uint32_t x = 0; x < width; ++x)
1902             {
1903                 css << "At (" << x << "," << y << ")" << std::endl;
1904                 for (uint32_t n = 0; n < 2; ++n)
1905                 {
1906                     css << names[n] << std::endl << "{" << std::endl;
1907 
1908                     for (uint32_t z = 0; z < depth; ++z)
1909                     {
1910                         pos = x + width * (y + height * z);
1911 
1912                         const float retrievedValue = float(resultPtr[pos]) / float(FIXED_POINT_DIVISOR);
1913                         const float expectedValue  = float(expectedPtr[pos]) / float(FIXED_POINT_DIVISOR);
1914 
1915                         if (z % 4 == 0)
1916                             css << "    {";
1917 
1918                         if (deFloatAbs(retrievedValue - expectedValue) > eps)
1919                             css << std::setprecision(5) << std::setw(9) << (n == 0 ? retrievedValue : expectedValue)
1920                                 << ",";
1921                         else
1922                             css << "_________,";
1923 
1924                         if (z % 4 == 3)
1925                             css << "}" << std::endl;
1926                     }
1927 
1928                     css << "}" << std::endl;
1929                 }
1930             }
1931         }
1932 
1933         log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
1934     }
1935 
1936     return failures == 0;
1937 }
1938 
1939 class TestConfigurationFlow : public TestConfiguration
1940 {
1941 public:
TestConfigurationFlow(Context & context)1942     TestConfigurationFlow(Context &context) : TestConfiguration(context)
1943     {
1944     }
1945 
1946     static const std::string getShaderBodyText(const TestParams &testParams);
1947 
1948     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
1949                                                                          VkCommandBuffer cmdBuffer) override;
1950 };
1951 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)1952 const VkAccelerationStructureKHR *TestConfigurationFlow::initAccelerationStructures(TestParams &testParams,
1953                                                                                     VkCommandBuffer cmdBuffer)
1954 {
1955     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
1956     const VkDevice device               = m_testEnvironment->device;
1957     Allocator &allocator                = *m_testEnvironment->allocator;
1958     const uint32_t width                = testParams.width;
1959     const uint32_t height               = testParams.height;
1960     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
1961     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
1962     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
1963     const bool triangles                = (testParams.geomType == GEOM_TYPE_TRIANGLES);
1964     const float z                       = -1.0f;
1965     tcu::UVec2 startPos                 = tcu::UVec2(0, 0);
1966     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
1967         makeTopLevelAccelerationStructure();
1968 
1969     m_topAccelerationStructure =
1970         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
1971 
1972     m_expected = std::vector<int32_t>(width * height, 1);
1973 
1974     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
1975 
1976     for (size_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
1977     {
1978         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
1979             makeBottomLevelAccelerationStructure();
1980 
1981         for (size_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
1982         {
1983             std::vector<tcu::Vec3> geometryData;
1984 
1985             geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
1986 
1987             for (size_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
1988             {
1989                 const uint32_t n = width * startPos.y() + startPos.x();
1990                 const uint32_t m = n + 1;
1991                 const float x0   = float(startPos.x() + 0) / float(width);
1992                 const float y0   = float(startPos.y() + 0) / float(height);
1993                 const float x1   = float(startPos.x() + 1) / float(width);
1994                 const float y1   = float(startPos.y() + 1) / float(height);
1995 
1996                 if (triangles)
1997                 {
1998                     const float xm = (x0 + x1) / 2.0f;
1999                     const float ym = (y0 + y1) / 2.0f;
2000 
2001                     geometryData.push_back(tcu::Vec3(x0, y0, z));
2002                     geometryData.push_back(tcu::Vec3(xm, y1, z));
2003                     geometryData.push_back(tcu::Vec3(x1, ym, z));
2004                 }
2005                 else
2006                 {
2007                     geometryData.push_back(tcu::Vec3(x0, y0, z));
2008                     geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
2009                 }
2010 
2011                 startPos.y() = m / width;
2012                 startPos.x() = m % width;
2013             }
2014 
2015             rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
2016         }
2017 
2018         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2019         m_bottomAccelerationStructures.push_back(
2020             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
2021         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back());
2022     }
2023 
2024     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2025 
2026     return m_topAccelerationStructure.get()->getPtr();
2027 }
2028 
getShaderBodyText(const TestParams & testParams)2029 const std::string TestConfigurationFlow::getShaderBodyText(const TestParams &testParams)
2030 {
2031     if (testParams.geomType == GEOM_TYPE_AABBS)
2032     {
2033         const std::string result =
2034             "  uint        rayFlags = 0;\n"
2035             "  uint        cullMask = 0xFF;\n"
2036             "  float       tmin     = 0.0;\n"
2037             "  float       tmax     = 9.0;\n"
2038             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
2039             "float(size.y), 0.0);\n"
2040             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
2041             "  uint        value    = 4;\n"
2042             "  rayQueryEXT rayQuery;\n"
2043             "\n"
2044             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
2045             "tmin, direct, tmax);\n"
2046             "\n"
2047             "  if (rayQueryProceedEXT(rayQuery))\n"
2048             "  {\n"
2049             "    value--;\n"
2050             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
2051             "    {\n"
2052             "      value--;\n"
2053             "      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n"
2054             "\n"
2055             "      rayQueryProceedEXT(rayQuery);\n"
2056             "\n"
2057             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == "
2058             "gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
2059             "        value--;\n"
2060             "    }\n"
2061             "  }\n"
2062             "\n"
2063             "  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2064 
2065         return result;
2066     }
2067     else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
2068     {
2069         const std::string result =
2070             "  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
2071             "  uint        cullMask = 0xFF;\n"
2072             "  float       tmin     = 0.0;\n"
2073             "  float       tmax     = 9.0;\n"
2074             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
2075             "float(size.y), 0.0);\n"
2076             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
2077             "  uint        value    = 4;\n"
2078             "  rayQueryEXT rayQuery;\n"
2079             "\n"
2080             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
2081             "tmin, direct, tmax);\n"
2082             "\n"
2083             "  if (rayQueryProceedEXT(rayQuery))\n"
2084             "  {\n"
2085             "    value--;\n"
2086             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
2087             "    {\n"
2088             "      value--;\n"
2089             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
2090             "\n"
2091             "      rayQueryProceedEXT(rayQuery);\n"
2092             "\n"
2093             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
2094             "        value--;\n"
2095             "    }\n"
2096             "  }\n"
2097             "\n"
2098             "  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2099 
2100         return result;
2101     }
2102     else
2103     {
2104         TCU_THROW(InternalError, "Unknown geometry type");
2105     }
2106 }
2107 
2108 class TestConfigurationPrimitiveId : public TestConfiguration
2109 {
2110 public:
TestConfigurationPrimitiveId(Context & context)2111     TestConfigurationPrimitiveId(Context &context) : TestConfiguration(context)
2112     {
2113     }
2114     static const std::string getShaderBodyText(const TestParams &testParams);
2115 
2116     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
2117                                                                          VkCommandBuffer cmdBuffer) override;
2118 };
2119 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)2120 const VkAccelerationStructureKHR *TestConfigurationPrimitiveId::initAccelerationStructures(TestParams &testParams,
2121                                                                                            VkCommandBuffer cmdBuffer)
2122 {
2123     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
2124     const VkDevice device               = m_testEnvironment->device;
2125     Allocator &allocator                = *m_testEnvironment->allocator;
2126     const uint32_t width                = testParams.width;
2127     const uint32_t height               = testParams.height;
2128     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
2129     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
2130     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
2131     const bool triangles                = (testParams.geomType == GEOM_TYPE_TRIANGLES);
2132     const float z                       = -1.0f;
2133     tcu::UVec2 startPos                 = tcu::UVec2(0, 0);
2134     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
2135         makeTopLevelAccelerationStructure();
2136 
2137     DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
2138 
2139     m_topAccelerationStructure =
2140         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
2141 
2142     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
2143 
2144     m_expected.resize(width * height);
2145 
2146     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
2147     {
2148         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
2149             makeBottomLevelAccelerationStructure();
2150 
2151         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
2152         {
2153             std::vector<tcu::Vec3> geometryData;
2154 
2155             geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
2156 
2157             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2158             {
2159                 const uint32_t n = width * startPos.y() + startPos.x();
2160                 const uint32_t m = (n + 11) % (width * height);
2161                 const float x0   = float(startPos.x() + 0) / float(width);
2162                 const float y0   = float(startPos.y() + 0) / float(height);
2163                 const float x1   = float(startPos.x() + 1) / float(width);
2164                 const float y1   = float(startPos.y() + 1) / float(height);
2165 
2166                 if (triangles)
2167                 {
2168                     const float xm = (x0 + x1) / 2.0f;
2169                     const float ym = (y0 + y1) / 2.0f;
2170 
2171                     geometryData.push_back(tcu::Vec3(x0, y0, z));
2172                     geometryData.push_back(tcu::Vec3(xm, y1, z));
2173                     geometryData.push_back(tcu::Vec3(x1, ym, z));
2174                 }
2175                 else
2176                 {
2177                     geometryData.push_back(tcu::Vec3(x0, y0, z));
2178                     geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
2179                 }
2180 
2181                 m_expected[n] = squareNdx;
2182 
2183                 startPos.y() = m / width;
2184                 startPos.x() = m % width;
2185             }
2186 
2187             rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
2188         }
2189 
2190         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2191         m_bottomAccelerationStructures.push_back(
2192             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
2193         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4,
2194                                                 instanceNdx + 1);
2195     }
2196 
2197     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2198 
2199     return m_topAccelerationStructure.get()->getPtr();
2200 }
2201 
getShaderBodyText(const TestParams & testParams)2202 const std::string TestConfigurationPrimitiveId::getShaderBodyText(const TestParams &testParams)
2203 {
2204     if (testParams.geomType == GEOM_TYPE_AABBS)
2205     {
2206         const std::string result =
2207             "  uint        rayFlags = 0;\n"
2208             "  uint        cullMask = 0xFF;\n"
2209             "  float       tmin     = 0.0;\n"
2210             "  float       tmax     = 9.0;\n"
2211             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
2212             "float(size.y), 0.0);\n"
2213             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
2214             "  uint        value    = -1;\n"
2215             "  rayQueryEXT rayQuery;\n"
2216             "\n"
2217             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
2218             "tmin, direct, tmax);\n"
2219             "\n"
2220             "  if (rayQueryProceedEXT(rayQuery))\n"
2221             "  {\n"
2222             "    value--;\n"
2223             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
2224             "    {\n"
2225             "      value--;\n"
2226             "      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n"
2227             "\n"
2228             "      rayQueryProceedEXT(rayQuery);\n"
2229             "\n"
2230             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == "
2231             "gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
2232             "        value = rayQueryGetIntersectionPrimitiveIndexEXT(rayQuery, true);\n"
2233             "    }\n"
2234             "  }\n"
2235             "\n"
2236             "  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2237 
2238         return result;
2239     }
2240     else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
2241     {
2242         const std::string result =
2243             "  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
2244             "  uint        cullMask = 0xFF;\n"
2245             "  float       tmin     = 0.0;\n"
2246             "  float       tmax     = 9.0;\n"
2247             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
2248             "float(size.y), 0.0);\n"
2249             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
2250             "  uint        value    = -1;\n"
2251             "  rayQueryEXT rayQuery;\n"
2252             "\n"
2253             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
2254             "tmin, direct, tmax);\n"
2255             "\n"
2256             "  if (rayQueryProceedEXT(rayQuery))\n"
2257             "  {\n"
2258             "    value--;\n"
2259             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
2260             "    {\n"
2261             "      value--;\n"
2262             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
2263             "\n"
2264             "      rayQueryProceedEXT(rayQuery);\n"
2265             "\n"
2266             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
2267             "        value = rayQueryGetIntersectionPrimitiveIndexEXT(rayQuery, true);\n"
2268             "    }\n"
2269             "  }\n"
2270             "\n"
2271             "  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2272 
2273         return result;
2274     }
2275     else
2276     {
2277         TCU_THROW(InternalError, "Unknown geometry type");
2278     }
2279 }
2280 
2281 class TestConfigurationGetRayTMin : public TestConfiguration
2282 {
2283 public:
TestConfigurationGetRayTMin(Context & context)2284     TestConfigurationGetRayTMin(Context &context) : TestConfiguration(context)
2285     {
2286     }
2287     static const std::string getShaderBodyText(const TestParams &testParams);
2288 
2289     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
2290                                                                          VkCommandBuffer cmdBuffer) override;
2291 };
2292 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)2293 const VkAccelerationStructureKHR *TestConfigurationGetRayTMin::initAccelerationStructures(TestParams &testParams,
2294                                                                                           VkCommandBuffer cmdBuffer)
2295 {
2296     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
2297     const VkDevice device               = m_testEnvironment->device;
2298     Allocator &allocator                = *m_testEnvironment->allocator;
2299     const uint32_t width                = testParams.width;
2300     const uint32_t height               = testParams.height;
2301     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
2302     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
2303     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
2304     const bool usesTriangles            = (testParams.geomType == GEOM_TYPE_TRIANGLES);
2305     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
2306         makeTopLevelAccelerationStructure();
2307 
2308     DE_ASSERT(instancesGroupCount == 1);
2309     DE_ASSERT(geometriesGroupCount == 1);
2310     DE_ASSERT(squaresGroupCount == width * height);
2311 
2312     m_topAccelerationStructure =
2313         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
2314 
2315     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
2316 
2317     m_expected.resize(width * height);
2318 
2319     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
2320     {
2321         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
2322             makeBottomLevelAccelerationStructure();
2323 
2324         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
2325         {
2326             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2327             {
2328                 std::vector<tcu::Vec3> geometryData;
2329 
2330                 const auto squareX = (squareNdx % width);
2331                 const auto squareY = (squareNdx / width);
2332 
2333                 const float x0 = float(squareX + 0) / float(width);
2334                 const float y0 = float(squareY + 0) / float(height);
2335                 const float x1 = float(squareX + 1) / float(width);
2336                 const float y1 = float(squareY + 1) / float(height);
2337 
2338                 if (usesTriangles)
2339                 {
2340                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
2341                     geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
2342                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
2343 
2344                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
2345                     geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
2346                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
2347                 }
2348                 else
2349                 {
2350                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
2351                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
2352                 }
2353 
2354                 rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, usesTriangles);
2355             }
2356         }
2357 
2358         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2359         m_bottomAccelerationStructures.push_back(
2360             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
2361         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4,
2362                                                 instanceNdx + 1);
2363     }
2364 
2365     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2366 
2367     for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2368     {
2369         const float expected_value    = 1.0f + static_cast<float>(squareNdx) / static_cast<float>(squaresGroupCount);
2370         const auto expected_value_i32 = static_cast<int32_t>(expected_value * FIXED_POINT_DIVISOR);
2371 
2372         m_expected.at(squareNdx) = expected_value_i32;
2373     }
2374 
2375     return m_topAccelerationStructure.get()->getPtr();
2376 }
2377 
getShaderBodyText(const TestParams & testParams)2378 const std::string TestConfigurationGetRayTMin::getShaderBodyText(const TestParams &testParams)
2379 {
2380     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
2381     {
2382         const std::string result =
2383             "  uint        rayFlags = 0;\n"
2384             "  uint        cullMask = 0xFF;\n"
2385             "  float       tmin     = 1.0 + float(pos.y * size.x + pos.x) / float(size.x * size.y);\n"
2386             "  float       tmax     = 9.0;\n"
2387             "  vec3        origin   = vec3(0.0, 0.0, -1.0);\n"
2388             "  vec3        direct   = vec3(0.0, 0.0,  1.0);\n"
2389             "  rayQueryEXT rayQuery;\n"
2390             "\n"
2391             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
2392             "tmin, direct, tmax);\n"
2393             "\n"
2394             "  while (rayQueryProceedEXT(rayQuery))\n"
2395             "  {\n"
2396             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
2397             "      {\n"
2398             "          rayQueryConfirmIntersectionEXT(rayQuery);\n"
2399             "      }\n"
2400             "  }\n"
2401             "\n"
2402             "  float result_fp32 = rayQueryGetRayTMinEXT(rayQuery);\n"
2403             "  imageStore(result, pos, ivec4(int(result_fp32 * " +
2404             de::toString(FIXED_POINT_DIVISOR) + "), 0, 0, 0));\n";
2405 
2406         return result;
2407     }
2408     else
2409     {
2410         TCU_THROW(InternalError, "Unknown geometry type");
2411     }
2412 }
2413 
2414 class TestConfigurationGetWorldRayOrigin : public TestConfigurationVector
2415 {
2416 public:
TestConfigurationGetWorldRayOrigin(Context & context)2417     TestConfigurationGetWorldRayOrigin(Context &context) : TestConfigurationVector(context)
2418     {
2419     }
2420     static const std::string getShaderBodyText(const TestParams &testParams);
2421 
2422     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
2423                                                                          VkCommandBuffer cmdBuffer) override;
2424 };
2425 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)2426 const VkAccelerationStructureKHR *TestConfigurationGetWorldRayOrigin::initAccelerationStructures(
2427     TestParams &testParams, VkCommandBuffer cmdBuffer)
2428 {
2429     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
2430     const VkDevice device               = m_testEnvironment->device;
2431     Allocator &allocator                = *m_testEnvironment->allocator;
2432     const uint32_t width                = testParams.width;
2433     const uint32_t height               = testParams.height;
2434     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
2435     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
2436     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
2437     const bool usesTriangles            = (testParams.geomType == GEOM_TYPE_TRIANGLES);
2438     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
2439         makeTopLevelAccelerationStructure();
2440 
2441     DE_ASSERT(instancesGroupCount == 1);
2442     DE_ASSERT(geometriesGroupCount == 1);
2443     DE_ASSERT(squaresGroupCount == width * height);
2444 
2445     m_topAccelerationStructure =
2446         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
2447 
2448     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
2449 
2450     m_expected.resize(width * height * 4 /* components */);
2451 
2452     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
2453     {
2454         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
2455             makeBottomLevelAccelerationStructure();
2456 
2457         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
2458         {
2459             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2460             {
2461                 std::vector<tcu::Vec3> geometryData;
2462 
2463                 const auto squareX = (squareNdx % width);
2464                 const auto squareY = (squareNdx / width);
2465 
2466                 const float x0 = float(squareX + 0) / float(width);
2467                 const float y0 = float(squareY + 0) / float(height);
2468                 const float x1 = float(squareX + 1) / float(width);
2469                 const float y1 = float(squareY + 1) / float(height);
2470 
2471                 if (usesTriangles)
2472                 {
2473                     geometryData.push_back(tcu::Vec3(x0, y0, -0.2f));
2474                     geometryData.push_back(tcu::Vec3(x0, y1, -0.2f));
2475                     geometryData.push_back(tcu::Vec3(x1, y1, -0.2f));
2476 
2477                     geometryData.push_back(tcu::Vec3(x1, y1, -0.2f));
2478                     geometryData.push_back(tcu::Vec3(x1, y0, -0.2f));
2479                     geometryData.push_back(tcu::Vec3(x0, y0, -0.2f));
2480                 }
2481                 else
2482                 {
2483                     geometryData.push_back(tcu::Vec3(x0, y0, -0.2f));
2484                     geometryData.push_back(tcu::Vec3(x1, y1, -0.2f));
2485                 }
2486 
2487                 rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, usesTriangles);
2488             }
2489         }
2490 
2491         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2492         m_bottomAccelerationStructures.push_back(
2493             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
2494         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4,
2495                                                 instanceNdx + 1);
2496     }
2497 
2498     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2499 
2500     for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2501     {
2502         const auto squareX = squareNdx % width;
2503         const auto squareY = squareNdx / width;
2504 
2505         const float expected_values[3] = {
2506             (float(squareX) + 0.5f) / float(width),
2507             (float(squareY) + 0.5f) / float(height),
2508             float(squareX + squareY) / float(width + height),
2509         };
2510 
2511         const int32_t expected_value_i32vec3[3] = {
2512             static_cast<int32_t>(expected_values[0] * FIXED_POINT_DIVISOR),
2513             static_cast<int32_t>(expected_values[1] * FIXED_POINT_DIVISOR),
2514             static_cast<int32_t>(expected_values[2] * FIXED_POINT_DIVISOR),
2515         };
2516 
2517         /* m_expected data layout is:
2518          *
2519          * XXXXXXXX ..
2520          * YYYYYYYY ..
2521          * ZZZZZZZZ ..
2522          * WWWWWWWW
2523          */
2524         m_expected.at(0 * squaresGroupCount + squareNdx) = expected_value_i32vec3[0];
2525         m_expected.at(1 * squaresGroupCount + squareNdx) = expected_value_i32vec3[1];
2526         m_expected.at(2 * squaresGroupCount + squareNdx) = expected_value_i32vec3[2];
2527         m_expected.at(3 * squaresGroupCount + squareNdx) = 0;
2528     }
2529 
2530     return m_topAccelerationStructure.get()->getPtr();
2531 }
2532 
getShaderBodyText(const TestParams & testParams)2533 const std::string TestConfigurationGetWorldRayOrigin::getShaderBodyText(const TestParams &testParams)
2534 {
2535     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
2536     {
2537         const std::string result =
2538             "  uint        rayFlags = 0;\n"
2539             "  uint        cullMask = 0xFF;\n"
2540             "  float       tmin     = 0.00001;\n"
2541             "  float       tmax     = 9.0;\n"
2542             "  vec3        origin   = vec3((float(pos.x) + 0.5)/ float(size.x), float(float(pos.y) + 0.5) / "
2543             "float(size.y), float(pos.x + pos.y) / float(size.x + size.y));\n"
2544             "  vec3        direct   = vec3(0, 0, -1);\n"
2545             "  rayQueryEXT rayQuery;\n"
2546             "\n"
2547             "  bool intersection_found = false;\n"
2548             "\n"
2549             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
2550             "tmin, direct, tmax);\n"
2551             "\n"
2552             "  while (rayQueryProceedEXT(rayQuery))\n"
2553             "  {\n"
2554             "      intersection_found = true;\n"
2555             "\n"
2556             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
2557             "  }\n"
2558             "\n"
2559             "  vec3 result_fp32 = (intersection_found) ? rayQueryGetWorldRayOriginEXT(rayQuery)\n"
2560             "                                          : vec3(1234.0, 5678, 9.0);\n"
2561             "\n"
2562             "  imageStore(result, ivec3(pos.xy, 0), ivec4(result_fp32.x * " +
2563             de::toString(FIXED_POINT_DIVISOR) +
2564             ", 0, 0, 0) );\n"
2565             "  imageStore(result, ivec3(pos.xy, 1), ivec4(result_fp32.y * " +
2566             de::toString(FIXED_POINT_DIVISOR) +
2567             ", 0, 0, 0) );\n"
2568             "  imageStore(result, ivec3(pos.xy, 2), ivec4(result_fp32.z * " +
2569             de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0) );\n";
2570 
2571         return result;
2572     }
2573     else
2574     {
2575         TCU_THROW(InternalError, "Unknown geometry type");
2576     }
2577 }
2578 
2579 class TestConfigurationGetWorldRayDirection : public TestConfigurationVector
2580 {
2581 public:
TestConfigurationGetWorldRayDirection(Context & context)2582     TestConfigurationGetWorldRayDirection(Context &context) : TestConfigurationVector(context)
2583     {
2584     }
2585     static const std::string getShaderBodyText(const TestParams &testParams);
2586 
2587     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
2588                                                                          VkCommandBuffer cmdBuffer) override;
2589 };
2590 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)2591 const VkAccelerationStructureKHR *TestConfigurationGetWorldRayDirection::initAccelerationStructures(
2592     TestParams &testParams, VkCommandBuffer cmdBuffer)
2593 {
2594     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
2595     const VkDevice device               = m_testEnvironment->device;
2596     Allocator &allocator                = *m_testEnvironment->allocator;
2597     const uint32_t width                = testParams.width;
2598     const uint32_t height               = testParams.height;
2599     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
2600     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
2601     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
2602     const bool usesTriangles            = (testParams.geomType == GEOM_TYPE_TRIANGLES);
2603     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
2604         makeTopLevelAccelerationStructure();
2605 
2606     DE_ASSERT(instancesGroupCount == 1);
2607     DE_ASSERT(geometriesGroupCount == 1);
2608     DE_ASSERT(squaresGroupCount == width * height);
2609 
2610     m_topAccelerationStructure =
2611         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
2612 
2613     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
2614 
2615     m_expected.resize(width * height * 3 /* components in vec3 */);
2616 
2617     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
2618     {
2619         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
2620             makeBottomLevelAccelerationStructure();
2621 
2622         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
2623         {
2624             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2625             {
2626                 std::vector<tcu::Vec3> geometryData;
2627 
2628                 const auto squareX = (squareNdx % width);
2629                 const auto squareY = (squareNdx / width);
2630 
2631                 const float x0 = float(squareX + 0) / float(width);
2632                 const float y0 = float(squareY + 0) / float(height);
2633                 const float x1 = float(squareX + 1) / float(width);
2634                 const float y1 = float(squareY + 1) / float(height);
2635 
2636                 if (usesTriangles)
2637                 {
2638                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
2639                     geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
2640                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
2641 
2642                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
2643                     geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
2644                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
2645                 }
2646                 else
2647                 {
2648                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
2649                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
2650                 }
2651 
2652                 rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, usesTriangles);
2653             }
2654         }
2655 
2656         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2657         m_bottomAccelerationStructures.push_back(
2658             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
2659         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4,
2660                                                 instanceNdx + 1);
2661     }
2662 
2663     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2664 
2665     const auto normalize = [](const tcu::Vec3 &in_vec3)
2666     {
2667         const auto distance = deFloatSqrt(in_vec3[0] * in_vec3[0] + in_vec3[1] * in_vec3[1] + in_vec3[2] * in_vec3[2]);
2668 
2669         return tcu::Vec3(in_vec3[0] / distance, in_vec3[1] / distance, in_vec3[2] / distance);
2670     };
2671 
2672     for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2673     {
2674         const auto squareX = squareNdx % width;
2675         const auto squareY = squareNdx / width;
2676 
2677         const auto origin = tcu::Vec3(0.5f, 0.5f, -1.0f);
2678         const auto target =
2679             tcu::Vec3((float(squareX) + 0.5f) / float(width), (float(squareY) + 0.5f) / float(height), 0.0);
2680         const auto dir_vector            = target - origin;
2681         const auto dir_vector_normalized = normalize(dir_vector);
2682 
2683         const int32_t expected_value_i32vec3[3] = {
2684             static_cast<int32_t>(dir_vector_normalized[0] * FIXED_POINT_DIVISOR),
2685             static_cast<int32_t>(dir_vector_normalized[1] * FIXED_POINT_DIVISOR),
2686             static_cast<int32_t>(dir_vector_normalized[2] * FIXED_POINT_DIVISOR),
2687         };
2688 
2689         /* Data layout for m_expected is:
2690          *
2691          * XXXX...XX
2692          * YYYY...YY
2693          * ZZZZ...ZZ
2694          * WWWW...WW
2695          */
2696         m_expected.at(0 * squaresGroupCount + squareNdx) = expected_value_i32vec3[0];
2697         m_expected.at(1 * squaresGroupCount + squareNdx) = expected_value_i32vec3[1];
2698         m_expected.at(2 * squaresGroupCount + squareNdx) = expected_value_i32vec3[2];
2699     }
2700 
2701     return m_topAccelerationStructure.get()->getPtr();
2702 }
2703 
getShaderBodyText(const TestParams & testParams)2704 const std::string TestConfigurationGetWorldRayDirection::getShaderBodyText(const TestParams &testParams)
2705 {
2706     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
2707     {
2708         const std::string result =
2709             "  uint        rayFlags = 0;\n"
2710             "  uint        cullMask = 0xFF;\n"
2711             "  float       tmin     = 0.00001;\n"
2712             "  float       tmax     = 9.0;\n"
2713             "  vec3        origin   = vec3(0.5, 0.5, -1.0);\n"
2714             "  vec3        target   = vec3(float(float(pos.x) + 0.5) / float(size.x), float(float(pos.y) + 0.5) / "
2715             "float(size.y), 0.0);\n"
2716             "  vec3        direct   = normalize(target - origin);\n"
2717             "  rayQueryEXT rayQuery;\n"
2718             "\n"
2719             "  bool intersection_found = false;\n"
2720             "\n"
2721             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
2722             "tmin, direct, tmax);\n"
2723             "\n"
2724             "  while (rayQueryProceedEXT(rayQuery))\n"
2725             "  {\n"
2726             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
2727             "\n"
2728             "      intersection_found = true;\n"
2729             "  }\n"
2730             "\n"
2731             "  vec3 result_fp32 = (intersection_found) ? rayQueryGetWorldRayDirectionEXT(rayQuery)\n"
2732             "                                          : vec3(1234.0, 5678.0, 9.0);\n"
2733             "\n"
2734             "  imageStore(result, ivec3(pos.xy, 0), ivec4(result_fp32.x * " +
2735             de::toString(FIXED_POINT_DIVISOR) +
2736             ", 0, 0, 0) );\n"
2737             "  imageStore(result, ivec3(pos.xy, 1), ivec4(result_fp32.y * " +
2738             de::toString(FIXED_POINT_DIVISOR) +
2739             ", 0, 0, 0) );\n"
2740             "  imageStore(result, ivec3(pos.xy, 2), ivec4(result_fp32.z * " +
2741             de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0) );\n";
2742 
2743         return result;
2744     }
2745     else
2746     {
2747         TCU_THROW(InternalError, "Unknown geometry type");
2748     }
2749 }
2750 
2751 class TestConfigurationInstanceId : public TestConfiguration
2752 {
2753 public:
TestConfigurationInstanceId(Context & context)2754     TestConfigurationInstanceId(Context &context) : TestConfiguration(context)
2755     {
2756     }
2757     static const std::string getShaderBodyText(const TestParams &testParams);
2758 
2759     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
2760                                                                          VkCommandBuffer cmdBuffer) override;
2761 };
2762 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)2763 const VkAccelerationStructureKHR *TestConfigurationInstanceId::initAccelerationStructures(TestParams &testParams,
2764                                                                                           VkCommandBuffer cmdBuffer)
2765 {
2766     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
2767     const VkDevice device               = m_testEnvironment->device;
2768     Allocator &allocator                = *m_testEnvironment->allocator;
2769     const uint32_t width                = testParams.width;
2770     const uint32_t height               = testParams.height;
2771     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
2772     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
2773     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
2774     const bool triangles                = (testParams.geomType == GEOM_TYPE_TRIANGLES);
2775     const float z                       = -1.0f;
2776     tcu::UVec2 startPos                 = tcu::UVec2(0, 0);
2777     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
2778         makeTopLevelAccelerationStructure();
2779 
2780     DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
2781 
2782     m_topAccelerationStructure =
2783         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
2784 
2785     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
2786 
2787     m_expected.resize(width * height);
2788 
2789     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
2790     {
2791         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
2792             makeBottomLevelAccelerationStructure();
2793 
2794         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
2795         {
2796             std::vector<tcu::Vec3> geometryData;
2797 
2798             geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
2799 
2800             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2801             {
2802                 const uint32_t n = width * startPos.y() + startPos.x();
2803                 const uint32_t m = (n + 11) % (width * height);
2804                 const float x0   = float(startPos.x() + 0) / float(width);
2805                 const float y0   = float(startPos.y() + 0) / float(height);
2806                 const float x1   = float(startPos.x() + 1) / float(width);
2807                 const float y1   = float(startPos.y() + 1) / float(height);
2808 
2809                 m_expected[n] = instanceNdx;
2810 
2811                 if (triangles)
2812                 {
2813                     const float xm = (x0 + x1) / 2.0f;
2814                     const float ym = (y0 + y1) / 2.0f;
2815 
2816                     geometryData.push_back(tcu::Vec3(x0, y0, z));
2817                     geometryData.push_back(tcu::Vec3(xm, y1, z));
2818                     geometryData.push_back(tcu::Vec3(x1, ym, z));
2819                 }
2820                 else
2821                 {
2822                     geometryData.push_back(tcu::Vec3(x0, y0, z));
2823                     geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
2824                 }
2825 
2826                 startPos.y() = m / width;
2827                 startPos.x() = m % width;
2828             }
2829 
2830             rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
2831         }
2832 
2833         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2834         m_bottomAccelerationStructures.push_back(
2835             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
2836         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4,
2837                                                 instanceNdx + 1);
2838     }
2839 
2840     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2841 
2842     return m_topAccelerationStructure.get()->getPtr();
2843 }
2844 
getShaderBodyText(const TestParams & testParams)2845 const std::string TestConfigurationInstanceId::getShaderBodyText(const TestParams &testParams)
2846 {
2847     if (testParams.geomType == GEOM_TYPE_AABBS)
2848     {
2849         const std::string result =
2850             "  uint        rayFlags = 0;\n"
2851             "  uint        cullMask = 0xFF;\n"
2852             "  float       tmin     = 0.0;\n"
2853             "  float       tmax     = 9.0;\n"
2854             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
2855             "float(size.y), 0.0);\n"
2856             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
2857             "  uint        value    = -1;\n"
2858             "  rayQueryEXT rayQuery;\n"
2859             "\n"
2860             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
2861             "tmin, direct, tmax);\n"
2862             "\n"
2863             "  if (rayQueryProceedEXT(rayQuery))\n"
2864             "  {\n"
2865             "    value--;\n"
2866             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
2867             "    {\n"
2868             "      value--;\n"
2869             "      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n"
2870             "\n"
2871             "      rayQueryProceedEXT(rayQuery);\n"
2872             "\n"
2873             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == "
2874             "gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
2875             "        value = rayQueryGetIntersectionInstanceIdEXT(rayQuery, true);\n"
2876             "    }\n"
2877             "  }\n"
2878             "\n"
2879             "  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2880 
2881         return result;
2882     }
2883     else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
2884     {
2885         const std::string result =
2886             "  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
2887             "  uint        cullMask = 0xFF;\n"
2888             "  float       tmin     = 0.0;\n"
2889             "  float       tmax     = 9.0;\n"
2890             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
2891             "float(size.y), 0.0);\n"
2892             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
2893             "  uint        value    = -1;\n"
2894             "  rayQueryEXT rayQuery;\n"
2895             "\n"
2896             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
2897             "tmin, direct, tmax);\n"
2898             "\n"
2899             "  if (rayQueryProceedEXT(rayQuery))\n"
2900             "  {\n"
2901             "    value--;\n"
2902             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
2903             "    {\n"
2904             "      value--;\n"
2905             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
2906             "\n"
2907             "      rayQueryProceedEXT(rayQuery);\n"
2908             "\n"
2909             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
2910             "        value = rayQueryGetIntersectionInstanceIdEXT(rayQuery, true);\n"
2911             "    }\n"
2912             "  }\n"
2913             "\n"
2914             "  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2915 
2916         return result;
2917     }
2918     else
2919     {
2920         TCU_THROW(InternalError, "Unknown geometry type");
2921     }
2922 }
2923 
2924 class TestConfigurationInstanceCustomIndex : public TestConfiguration
2925 {
2926 public:
TestConfigurationInstanceCustomIndex(Context & context)2927     TestConfigurationInstanceCustomIndex(Context &context) : TestConfiguration(context)
2928     {
2929     }
2930     static const std::string getShaderBodyText(const TestParams &testParams);
2931 
2932     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
2933                                                                          VkCommandBuffer cmdBuffer) override;
2934 };
2935 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)2936 const VkAccelerationStructureKHR *TestConfigurationInstanceCustomIndex::initAccelerationStructures(
2937     TestParams &testParams, VkCommandBuffer cmdBuffer)
2938 {
2939     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
2940     const VkDevice device               = m_testEnvironment->device;
2941     Allocator &allocator                = *m_testEnvironment->allocator;
2942     const uint32_t width                = testParams.width;
2943     const uint32_t height               = testParams.height;
2944     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
2945     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
2946     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
2947     const bool triangles                = (testParams.geomType == GEOM_TYPE_TRIANGLES);
2948     const float z                       = -1.0f;
2949     tcu::UVec2 startPos                 = tcu::UVec2(0, 0);
2950     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
2951         makeTopLevelAccelerationStructure();
2952 
2953     DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
2954 
2955     m_topAccelerationStructure =
2956         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
2957 
2958     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
2959 
2960     m_expected.resize(width * height);
2961 
2962     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
2963     {
2964         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
2965             makeBottomLevelAccelerationStructure();
2966 
2967         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
2968         {
2969             std::vector<tcu::Vec3> geometryData;
2970 
2971             geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
2972 
2973             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2974             {
2975                 const uint32_t n = width * startPos.y() + startPos.x();
2976                 const uint32_t m = (n + 11) % (width * height);
2977                 const float x0   = float(startPos.x() + 0) / float(width);
2978                 const float y0   = float(startPos.y() + 0) / float(height);
2979                 const float x1   = float(startPos.x() + 1) / float(width);
2980                 const float y1   = float(startPos.y() + 1) / float(height);
2981 
2982                 m_expected[n] = instanceNdx + 1;
2983 
2984                 if (triangles)
2985                 {
2986                     const float xm = (x0 + x1) / 2.0f;
2987                     const float ym = (y0 + y1) / 2.0f;
2988 
2989                     geometryData.push_back(tcu::Vec3(x0, y0, z));
2990                     geometryData.push_back(tcu::Vec3(xm, y1, z));
2991                     geometryData.push_back(tcu::Vec3(x1, ym, z));
2992                 }
2993                 else
2994                 {
2995                     geometryData.push_back(tcu::Vec3(x0, y0, z));
2996                     geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
2997                 }
2998 
2999                 startPos.y() = m / width;
3000                 startPos.x() = m % width;
3001             }
3002 
3003             rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
3004         }
3005 
3006         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3007         m_bottomAccelerationStructures.push_back(
3008             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
3009         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4,
3010                                                 instanceNdx + 1);
3011     }
3012 
3013     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3014 
3015     return m_topAccelerationStructure.get()->getPtr();
3016 }
3017 
getShaderBodyText(const TestParams & testParams)3018 const std::string TestConfigurationInstanceCustomIndex::getShaderBodyText(const TestParams &testParams)
3019 {
3020     if (testParams.geomType == GEOM_TYPE_AABBS)
3021     {
3022         const std::string result =
3023             "  uint        rayFlags = 0;\n"
3024             "  uint        cullMask = 0xFF;\n"
3025             "  float       tmin     = 0.0;\n"
3026             "  float       tmax     = 9.0;\n"
3027             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
3028             "float(size.y), 0.0);\n"
3029             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3030             "  uint        value    = -1;\n"
3031             "  rayQueryEXT rayQuery;\n"
3032             "\n"
3033             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
3034             "tmin, direct, tmax);\n"
3035             "\n"
3036             "  if (rayQueryProceedEXT(rayQuery))\n"
3037             "  {\n"
3038             "    value--;\n"
3039             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
3040             "    {\n"
3041             "      value--;\n"
3042             "      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n"
3043             "\n"
3044             "      rayQueryProceedEXT(rayQuery);\n"
3045             "\n"
3046             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == "
3047             "gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
3048             "        value = rayQueryGetIntersectionInstanceCustomIndexEXT(rayQuery, true);\n"
3049             "    }\n"
3050             "  }\n"
3051             "\n"
3052             "  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
3053 
3054         return result;
3055     }
3056     else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
3057     {
3058         const std::string result =
3059             "  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
3060             "  uint        cullMask = 0xFF;\n"
3061             "  float       tmin     = 0.0;\n"
3062             "  float       tmax     = 9.0;\n"
3063             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
3064             "float(size.y), 0.0);\n"
3065             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3066             "  uint        value    = -1;\n"
3067             "  rayQueryEXT rayQuery;\n"
3068             "\n"
3069             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
3070             "tmin, direct, tmax);\n"
3071             "\n"
3072             "  if (rayQueryProceedEXT(rayQuery))\n"
3073             "  {\n"
3074             "    value--;\n"
3075             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
3076             "    {\n"
3077             "      value--;\n"
3078             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
3079             "\n"
3080             "      rayQueryProceedEXT(rayQuery);\n"
3081             "\n"
3082             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
3083             "        value = rayQueryGetIntersectionInstanceCustomIndexEXT(rayQuery, true);\n"
3084             "    }\n"
3085             "  }\n"
3086             "\n"
3087             "  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
3088 
3089         return result;
3090     }
3091     else
3092     {
3093         TCU_THROW(InternalError, "Unknown geometry type");
3094     }
3095 }
3096 
3097 class TestConfigurationIntersectionT : public TestConfigurationFloat
3098 {
3099 public:
TestConfigurationIntersectionT(Context & context)3100     TestConfigurationIntersectionT(Context &context) : TestConfigurationFloat(context)
3101     {
3102     }
3103     static const std::string getShaderBodyText(const TestParams &testParams);
3104 
3105     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
3106                                                                          VkCommandBuffer cmdBuffer) override;
3107 };
3108 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)3109 const VkAccelerationStructureKHR *TestConfigurationIntersectionT::initAccelerationStructures(TestParams &testParams,
3110                                                                                              VkCommandBuffer cmdBuffer)
3111 {
3112     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
3113     const VkDevice device               = m_testEnvironment->device;
3114     Allocator &allocator                = *m_testEnvironment->allocator;
3115     const uint32_t width                = testParams.width;
3116     const uint32_t height               = testParams.height;
3117     const bool triangles                = (testParams.geomType == GEOM_TYPE_TRIANGLES);
3118     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
3119     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
3120     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
3121     tcu::UVec2 startPos                 = tcu::UVec2(0, 0);
3122     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
3123         makeTopLevelAccelerationStructure();
3124 
3125     DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
3126 
3127     m_topAccelerationStructure =
3128         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
3129 
3130     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
3131 
3132     m_expected.resize(width * height);
3133 
3134     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
3135     {
3136         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
3137             makeBottomLevelAccelerationStructure();
3138 
3139         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
3140         {
3141             std::vector<tcu::Vec3> geometryData;
3142 
3143             geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
3144 
3145             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
3146             {
3147                 const uint32_t n = width * startPos.y() + startPos.x();
3148                 const uint32_t m = (n + 11) % (width * height);
3149                 const float x0   = float(startPos.x() + 0) / float(width);
3150                 const float y0   = float(startPos.y() + 0) / float(height);
3151                 const float x1   = float(startPos.x() + 1) / float(width);
3152                 const float y1   = float(startPos.y() + 1) / float(height);
3153                 const float eps  = 1.0f / float(FIXED_POINT_DIVISOR);
3154                 const float z    = -deFloatAbs(eps + float(startPos.x()) * float(startPos.y()) / float(width * height));
3155 
3156                 m_expected[n] = -int(z * FIXED_POINT_DIVISOR);
3157 
3158                 if (triangles)
3159                 {
3160                     const float xm = (x0 + x1) / 2.0f;
3161                     const float ym = (y0 + y1) / 2.0f;
3162 
3163                     geometryData.push_back(tcu::Vec3(x0, y0, z));
3164                     geometryData.push_back(tcu::Vec3(xm, y1, z));
3165                     geometryData.push_back(tcu::Vec3(x1, ym, z));
3166                 }
3167                 else
3168                 {
3169                     geometryData.push_back(tcu::Vec3(x0, y0, z));
3170                     geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
3171                 }
3172 
3173                 startPos.y() = m / width;
3174                 startPos.x() = m % width;
3175             }
3176 
3177             rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
3178         }
3179 
3180         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3181         m_bottomAccelerationStructures.push_back(
3182             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
3183         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4);
3184     }
3185 
3186     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3187 
3188     return m_topAccelerationStructure.get()->getPtr();
3189 }
3190 
getShaderBodyText(const TestParams & testParams)3191 const std::string TestConfigurationIntersectionT::getShaderBodyText(const TestParams &testParams)
3192 {
3193     if (testParams.geomType == GEOM_TYPE_AABBS)
3194     {
3195         const std::string result =
3196             "  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) +
3197             ";\n"
3198             "  uint        rayFlags = 0;\n"
3199             "  uint        cullMask = 0xFF;\n"
3200             "  float       tmin     = 0.0;\n"
3201             "  float       tmax     = 9.0;\n"
3202             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
3203             "float(size.y), 0.0);\n"
3204             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3205             "  int         value    = -k;\n"
3206             "  const float t        = abs(float(pos.x * pos.y) / float (size.x * size.y));\n"
3207             "  rayQueryEXT rayQuery;\n"
3208             "\n"
3209             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
3210             "tmin, direct, tmax);\n"
3211             "\n"
3212             "  if (rayQueryProceedEXT(rayQuery))\n"
3213             "  {\n"
3214             "    value -= k;\n"
3215             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
3216             "    {\n"
3217             "      value -= k;\n"
3218             "      rayQueryGenerateIntersectionEXT(rayQuery, t);\n"
3219             "\n"
3220             "      rayQueryProceedEXT(rayQuery);\n"
3221             "\n"
3222             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == "
3223             "gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
3224             "        value = int(k * rayQueryGetIntersectionTEXT(rayQuery, true));\n"
3225             "    }\n"
3226             "  }\n"
3227             "\n"
3228             "  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
3229 
3230         return result;
3231     }
3232     else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
3233     {
3234         const std::string result =
3235             "  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) +
3236             ";\n"
3237             "  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
3238             "  uint        cullMask = 0xFF;\n"
3239             "  float       tmin     = 0.0;\n"
3240             "  float       tmax     = 9.0;\n"
3241             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
3242             "float(size.y), 0.0);\n"
3243             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3244             "  int         value    = -k;\n"
3245             "  rayQueryEXT rayQuery;\n"
3246             "\n"
3247             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
3248             "tmin, direct, tmax);\n"
3249             "\n"
3250             "  if (rayQueryProceedEXT(rayQuery))\n"
3251             "  {\n"
3252             "    value -= k;\n"
3253             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
3254             "    {\n"
3255             "      value -= k;\n"
3256             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
3257             "\n"
3258             "      rayQueryProceedEXT(rayQuery);\n"
3259             "\n"
3260             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
3261             "        value = int(k * rayQueryGetIntersectionTEXT(rayQuery, true));\n"
3262             "    }\n"
3263             "  }\n"
3264             "\n"
3265             "  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
3266 
3267         return result;
3268     }
3269     else
3270     {
3271         TCU_THROW(InternalError, "Unknown geometry type");
3272     }
3273 }
3274 
3275 class TestConfigurationObjectRayOrigin : public TestConfigurationVector
3276 {
3277 public:
TestConfigurationObjectRayOrigin(Context & context)3278     TestConfigurationObjectRayOrigin(Context &context) : TestConfigurationVector(context)
3279     {
3280     }
3281     static const std::string getShaderBodyText(const TestParams &testParams);
3282 
3283     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
3284                                                                          VkCommandBuffer cmdBuffer) override;
3285 };
3286 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)3287 const VkAccelerationStructureKHR *TestConfigurationObjectRayOrigin::initAccelerationStructures(
3288     TestParams &testParams, VkCommandBuffer cmdBuffer)
3289 {
3290     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
3291     const VkDevice device               = m_testEnvironment->device;
3292     Allocator &allocator                = *m_testEnvironment->allocator;
3293     const uint32_t width                = testParams.width;
3294     const uint32_t height               = testParams.height;
3295     const uint32_t depth                = testParams.depth;
3296     const bool triangles                = (testParams.geomType == GEOM_TYPE_TRIANGLES);
3297     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
3298     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
3299     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
3300     const float z                       = -1.0f;
3301     tcu::UVec2 startPos                 = tcu::UVec2(0, 0);
3302     uint32_t pos                        = 0;
3303     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
3304         makeTopLevelAccelerationStructure();
3305 
3306     DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
3307 
3308     m_topAccelerationStructure =
3309         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
3310 
3311     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
3312 
3313     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
3314     {
3315         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
3316             makeBottomLevelAccelerationStructure();
3317 
3318         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
3319         {
3320             std::vector<tcu::Vec3> geometryData;
3321 
3322             geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
3323 
3324             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
3325             {
3326                 const uint32_t n = width * startPos.y() + startPos.x();
3327                 const uint32_t m = (n + 11) % (width * height);
3328                 const float x0   = float(startPos.x() + 0) / float(width);
3329                 const float y0   = float(startPos.y() + 0) / float(height);
3330                 const float x1   = float(startPos.x() + 1) / float(width);
3331                 const float y1   = float(startPos.y() + 1) / float(height);
3332 
3333                 if (triangles)
3334                 {
3335                     const float xm = (x0 + x1) / 2.0f;
3336                     const float ym = (y0 + y1) / 2.0f;
3337 
3338                     geometryData.push_back(tcu::Vec3(x0, y0, z));
3339                     geometryData.push_back(tcu::Vec3(xm, y1, z));
3340                     geometryData.push_back(tcu::Vec3(x1, ym, z));
3341                 }
3342                 else
3343                 {
3344                     geometryData.push_back(tcu::Vec3(x0, y0, z));
3345                     geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
3346                 }
3347 
3348                 startPos.y() = m / width;
3349                 startPos.x() = m % width;
3350             }
3351 
3352             rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
3353         }
3354 
3355         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3356         m_bottomAccelerationStructures.push_back(
3357             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
3358         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4);
3359     }
3360 
3361     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3362 
3363     m_expected.resize(width * height * depth);
3364     for (uint32_t y = 0; y < height; ++y)
3365         for (uint32_t x = 0; x < width; ++x)
3366             m_expected[pos++] = int(float(FIXED_POINT_DIVISOR) * (0.5f + float(x)) / float(width));
3367 
3368     for (uint32_t y = 0; y < height; ++y)
3369         for (uint32_t x = 0; x < width; ++x)
3370             m_expected[pos++] = int(float(FIXED_POINT_DIVISOR) * (0.5f + float(y)) / float(height));
3371 
3372     for (uint32_t y = 0; y < height; ++y)
3373         for (uint32_t x = 0; x < width; ++x)
3374             m_expected[pos++] = 0;
3375 
3376     return m_topAccelerationStructure.get()->getPtr();
3377 }
3378 
getShaderBodyText(const TestParams & testParams)3379 const std::string TestConfigurationObjectRayOrigin::getShaderBodyText(const TestParams &testParams)
3380 {
3381     if (testParams.geomType == GEOM_TYPE_AABBS)
3382     {
3383         const std::string result =
3384             "  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) +
3385             ";\n"
3386             "  uint        rayFlags = 0;\n"
3387             "  uint        cullMask = 0xFF;\n"
3388             "  float       tmin     = 0.0;\n"
3389             "  float       tmax     = 9.0;\n"
3390             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
3391             "float(size.y), 0.0);\n"
3392             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3393             "  ivec3       value    = ivec3(-k);\n"
3394             "  const float t        = abs(float(pos.x * pos.y) / float (size.x * size.y));\n"
3395             "  rayQueryEXT rayQuery;\n"
3396             "\n"
3397             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
3398             "tmin, direct, tmax);\n"
3399             "\n"
3400             "  if (rayQueryProceedEXT(rayQuery))\n"
3401             "  {\n"
3402             "    value -= ivec3(k);\n"
3403             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
3404             "    {\n"
3405             "      value -= ivec3(k);\n"
3406             "      rayQueryGenerateIntersectionEXT(rayQuery, t);\n"
3407             "\n"
3408             "      rayQueryProceedEXT(rayQuery);\n"
3409             "\n"
3410             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == "
3411             "gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
3412             "        value = ivec3(k * rayQueryGetIntersectionObjectRayOriginEXT(rayQuery, true));\n"
3413             "    }\n"
3414             "  }\n"
3415             "\n"
3416             "  imageStore(result, ivec3(pos.x, pos.y, 0), ivec4(value.x, 0, 0, 0));\n"
3417             "  imageStore(result, ivec3(pos.x, pos.y, 1), ivec4(value.y, 0, 0, 0));\n"
3418             "  imageStore(result, ivec3(pos.x, pos.y, 2), ivec4(value.z, 0, 0, 0));\n";
3419 
3420         return result;
3421     }
3422     else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
3423     {
3424         const std::string result =
3425             "  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) +
3426             ";\n"
3427             "  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
3428             "  uint        cullMask = 0xFF;\n"
3429             "  float       tmin     = 0.0;\n"
3430             "  float       tmax     = 9.0;\n"
3431             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
3432             "float(size.y), 0.0);\n"
3433             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3434             "  ivec3       value    = ivec3(-k);\n"
3435             "  rayQueryEXT rayQuery;\n"
3436             "\n"
3437             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
3438             "tmin, direct, tmax);\n"
3439             "\n"
3440             "  if (rayQueryProceedEXT(rayQuery))\n"
3441             "  {\n"
3442             "    value -= ivec3(k);\n"
3443             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
3444             "    {\n"
3445             "      value -= ivec3(k);\n"
3446             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
3447             "\n"
3448             "      rayQueryProceedEXT(rayQuery);\n"
3449             "\n"
3450             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
3451             "        value = ivec3(k * rayQueryGetIntersectionObjectRayOriginEXT(rayQuery, true));\n"
3452             "    }\n"
3453             "  }\n"
3454             "\n"
3455             "  imageStore(result, ivec3(pos.x, pos.y, 0), ivec4(value.x, 0, 0, 0));\n"
3456             "  imageStore(result, ivec3(pos.x, pos.y, 1), ivec4(value.y, 0, 0, 0));\n"
3457             "  imageStore(result, ivec3(pos.x, pos.y, 2), ivec4(value.z, 0, 0, 0));\n";
3458 
3459         return result;
3460     }
3461     else
3462     {
3463         TCU_THROW(InternalError, "Unknown geometry type");
3464     }
3465 }
3466 
3467 class TestConfigurationObjectRayDirection : public TestConfigurationVector
3468 {
3469 public:
TestConfigurationObjectRayDirection(Context & context)3470     TestConfigurationObjectRayDirection(Context &context) : TestConfigurationVector(context)
3471     {
3472     }
3473     static const std::string getShaderBodyText(const TestParams &testParams);
3474 
3475     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
3476                                                                          VkCommandBuffer cmdBuffer) override;
3477 };
3478 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)3479 const VkAccelerationStructureKHR *TestConfigurationObjectRayDirection::initAccelerationStructures(
3480     TestParams &testParams, VkCommandBuffer cmdBuffer)
3481 {
3482     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
3483     const VkDevice device               = m_testEnvironment->device;
3484     Allocator &allocator                = *m_testEnvironment->allocator;
3485     const uint32_t width                = testParams.width;
3486     const uint32_t height               = testParams.height;
3487     const uint32_t depth                = testParams.depth;
3488     const bool triangles                = (testParams.geomType == GEOM_TYPE_TRIANGLES);
3489     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
3490     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
3491     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
3492     const float z                       = -1.0f;
3493     tcu::UVec2 startPos                 = tcu::UVec2(0, 0);
3494     uint32_t pos                        = 0;
3495     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
3496         makeTopLevelAccelerationStructure();
3497 
3498     DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
3499 
3500     m_topAccelerationStructure =
3501         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
3502 
3503     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
3504 
3505     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
3506     {
3507         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
3508             makeBottomLevelAccelerationStructure();
3509 
3510         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
3511         {
3512             std::vector<tcu::Vec3> geometryData;
3513 
3514             geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
3515 
3516             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
3517             {
3518                 const uint32_t n = width * startPos.y() + startPos.x();
3519                 const uint32_t m = (n + 11) % (width * height);
3520                 const float x0   = float(startPos.x() + 0) / float(width);
3521                 const float y0   = float(startPos.y() + 0) / float(height);
3522                 const float x1   = float(startPos.x() + 1) / float(width);
3523                 const float y1   = float(startPos.y() + 1) / float(height);
3524 
3525                 if (triangles)
3526                 {
3527                     const float xm = (x0 + x1) / 2.0f;
3528                     const float ym = (y0 + y1) / 2.0f;
3529 
3530                     geometryData.push_back(tcu::Vec3(x0, y0, z));
3531                     geometryData.push_back(tcu::Vec3(xm, y1, z));
3532                     geometryData.push_back(tcu::Vec3(x1, ym, z));
3533                 }
3534                 else
3535                 {
3536                     geometryData.push_back(tcu::Vec3(x0, y0, z));
3537                     geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
3538                 }
3539 
3540                 startPos.y() = m / width;
3541                 startPos.x() = m % width;
3542             }
3543 
3544             rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
3545         }
3546 
3547         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3548         m_bottomAccelerationStructures.push_back(
3549             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
3550         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4);
3551     }
3552 
3553     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3554 
3555     m_expected.resize(width * height * depth);
3556     for (uint32_t y = 0; y < height; ++y)
3557         for (uint32_t x = 0; x < width; ++x)
3558             m_expected[pos++] = 0;
3559 
3560     for (uint32_t y = 0; y < height; ++y)
3561         for (uint32_t x = 0; x < width; ++x)
3562             m_expected[pos++] = 0;
3563 
3564     for (uint32_t y = 0; y < height; ++y)
3565         for (uint32_t x = 0; x < width; ++x)
3566             m_expected[pos++] = -static_cast<int32_t>(FIXED_POINT_DIVISOR);
3567 
3568     return m_topAccelerationStructure.get()->getPtr();
3569 }
3570 
getShaderBodyText(const TestParams & testParams)3571 const std::string TestConfigurationObjectRayDirection::getShaderBodyText(const TestParams &testParams)
3572 {
3573     if (testParams.geomType == GEOM_TYPE_AABBS)
3574     {
3575         const std::string result =
3576             "  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) +
3577             ";\n"
3578             "  uint        rayFlags = 0;\n"
3579             "  uint        cullMask = 0xFF;\n"
3580             "  float       tmin     = 0.0;\n"
3581             "  float       tmax     = 9.0;\n"
3582             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
3583             "float(size.y), 0.0);\n"
3584             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3585             "  ivec3       value    = ivec3(-k);\n"
3586             "  const float t        = abs(float(pos.x * pos.y) / float (size.x * size.y));\n"
3587             "  rayQueryEXT rayQuery;\n"
3588             "\n"
3589             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
3590             "tmin, direct, tmax);\n"
3591             "\n"
3592             "  if (rayQueryProceedEXT(rayQuery))\n"
3593             "  {\n"
3594             "    value -= ivec3(k);\n"
3595             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
3596             "    {\n"
3597             "      value -= ivec3(k);\n"
3598             "      rayQueryGenerateIntersectionEXT(rayQuery, t);\n"
3599             "\n"
3600             "      rayQueryProceedEXT(rayQuery);\n"
3601             "\n"
3602             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == "
3603             "gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
3604             "        value = ivec3(k * rayQueryGetIntersectionObjectRayDirectionEXT(rayQuery, true));\n"
3605             "    }\n"
3606             "  }\n"
3607             "\n"
3608             "  imageStore(result, ivec3(pos.x, pos.y, 0), ivec4(value.x, 0, 0, 0));\n"
3609             "  imageStore(result, ivec3(pos.x, pos.y, 1), ivec4(value.y, 0, 0, 0));\n"
3610             "  imageStore(result, ivec3(pos.x, pos.y, 2), ivec4(value.z, 0, 0, 0));\n";
3611 
3612         return result;
3613     }
3614     else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
3615     {
3616         const std::string result =
3617             "  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) +
3618             ";\n"
3619             "  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
3620             "  uint        cullMask = 0xFF;\n"
3621             "  float       tmin     = 0.0;\n"
3622             "  float       tmax     = 9.0;\n"
3623             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
3624             "float(size.y), 0.0);\n"
3625             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3626             "  ivec3       value    = ivec3(-k);\n"
3627             "  rayQueryEXT rayQuery;\n"
3628             "\n"
3629             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
3630             "tmin, direct, tmax);\n"
3631             "\n"
3632             "  if (rayQueryProceedEXT(rayQuery))\n"
3633             "  {\n"
3634             "    value -= ivec3(k);\n"
3635             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
3636             "    {\n"
3637             "      value -= ivec3(k);\n"
3638             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
3639             "\n"
3640             "      rayQueryProceedEXT(rayQuery);\n"
3641             "\n"
3642             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
3643             "        value = ivec3(k * rayQueryGetIntersectionObjectRayDirectionEXT(rayQuery, true));\n"
3644             "    }\n"
3645             "  }\n"
3646             "\n"
3647             "  imageStore(result, ivec3(pos.x, pos.y, 0), ivec4(value.x, 0, 0, 0));\n"
3648             "  imageStore(result, ivec3(pos.x, pos.y, 1), ivec4(value.y, 0, 0, 0));\n"
3649             "  imageStore(result, ivec3(pos.x, pos.y, 2), ivec4(value.z, 0, 0, 0));\n";
3650 
3651         return result;
3652     }
3653     else
3654     {
3655         TCU_THROW(InternalError, "Unknown geometry type");
3656     }
3657 }
3658 
3659 class TestConfigurationObjectToWorld : public TestConfigurationMatrix
3660 {
3661 public:
TestConfigurationObjectToWorld(Context & context)3662     TestConfigurationObjectToWorld(Context &context) : TestConfigurationMatrix(context)
3663     {
3664     }
3665     static const std::string getShaderBodyText(const TestParams &testParams);
3666 
3667     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
3668                                                                          VkCommandBuffer cmdBuffer) override;
3669 };
3670 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)3671 const VkAccelerationStructureKHR *TestConfigurationObjectToWorld::initAccelerationStructures(TestParams &testParams,
3672                                                                                              VkCommandBuffer cmdBuffer)
3673 {
3674     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
3675     const VkDevice device               = m_testEnvironment->device;
3676     Allocator &allocator                = *m_testEnvironment->allocator;
3677     const uint32_t width                = testParams.width;
3678     const uint32_t height               = testParams.height;
3679     const bool triangles                = (testParams.geomType == GEOM_TYPE_TRIANGLES);
3680     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
3681     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
3682     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
3683     const float z                       = -1.0f;
3684     tcu::UVec2 startPos                 = tcu::UVec2(0, 0);
3685     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
3686         makeTopLevelAccelerationStructure();
3687 
3688     DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
3689 
3690     m_topAccelerationStructure =
3691         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
3692 
3693     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
3694 
3695     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
3696     {
3697         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
3698             makeBottomLevelAccelerationStructure();
3699         VkTransformMatrixKHR transform = identityMatrix3x4;
3700 
3701         transform.matrix[0][3] = (1.0f / 8.0f) / float(width);
3702         transform.matrix[1][3] = (1.0f / 16.0f) / float(height);
3703 
3704         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
3705         {
3706             std::vector<tcu::Vec3> geometryData;
3707 
3708             geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
3709 
3710             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
3711             {
3712                 const uint32_t n = width * startPos.y() + startPos.x();
3713                 const uint32_t m = (n + 11) % (width * height);
3714                 const float x0   = float(startPos.x() + 0) / float(width);
3715                 const float y0   = float(startPos.y() + 0) / float(height);
3716                 const float x1   = float(startPos.x() + 1) / float(width);
3717                 const float y1   = float(startPos.y() + 1) / float(height);
3718 
3719                 if (triangles)
3720                 {
3721                     const float xm = (x0 + x1) / 2.0f;
3722                     const float ym = (y0 + y1) / 2.0f;
3723 
3724                     geometryData.push_back(tcu::Vec3(x0, y0, z));
3725                     geometryData.push_back(tcu::Vec3(xm, y1, z));
3726                     geometryData.push_back(tcu::Vec3(x1, ym, z));
3727                 }
3728                 else
3729                 {
3730                     geometryData.push_back(tcu::Vec3(x0, y0, z));
3731                     geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
3732                 }
3733 
3734                 startPos.y() = m / width;
3735                 startPos.x() = m % width;
3736             }
3737 
3738             rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
3739         }
3740 
3741         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3742         m_bottomAccelerationStructures.push_back(
3743             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
3744         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), transform);
3745     }
3746 
3747     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3748 
3749     {
3750         const uint32_t imageDepth       = 4 * 4;
3751         const int translateColumnNumber = 3;
3752         const uint32_t colCount         = 4;
3753         const uint32_t rowCount         = 3;
3754         const uint32_t zStride          = height * width;
3755         const uint32_t expectedFloats   = imageDepth * zStride;
3756         const float translateX          = (+1.0f / 8.0f) / float(width);
3757         const float translateY          = (+1.0f / 16.0f) / float(height);
3758         tcu::Matrix<float, rowCount, colCount> m;
3759 
3760         m[translateColumnNumber][0] = translateX;
3761         m[translateColumnNumber][1] = translateY;
3762 
3763         m_expected.resize(expectedFloats);
3764 
3765         for (uint32_t y = 0; y < height; ++y)
3766         {
3767             for (uint32_t x = 0; x < width; ++x)
3768             {
3769                 const uint32_t elem0Pos = x + width * y;
3770 
3771                 for (uint32_t rowNdx = 0; rowNdx < rowCount; ++rowNdx)
3772                     for (uint32_t colNdx = 0; colNdx < colCount; ++colNdx)
3773                     {
3774                         const uint32_t zNdx   = rowNdx * colCount + colNdx;
3775                         const uint32_t posNdx = elem0Pos + zStride * zNdx;
3776 
3777                         m_expected[posNdx] = static_cast<int32_t>(FIXED_POINT_DIVISOR * m[colNdx][rowNdx]);
3778                     }
3779             }
3780         }
3781     }
3782 
3783     return m_topAccelerationStructure.get()->getPtr();
3784 }
3785 
getShaderBodyText(const TestParams & testParams)3786 const std::string TestConfigurationObjectToWorld::getShaderBodyText(const TestParams &testParams)
3787 {
3788     if (testParams.geomType == GEOM_TYPE_AABBS)
3789     {
3790         const std::string result =
3791             "  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) +
3792             ";\n"
3793             "  uint        rayFlags = 0;\n"
3794             "  uint        cullMask = 0xFF;\n"
3795             "  float       tmin     = 0.0;\n"
3796             "  float       tmax     = 9.0;\n"
3797             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
3798             "float(size.y), 0.0);\n"
3799             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3800             "  mat4x3      value    = mat4x3(-k);\n"
3801             "  const float t        = abs(float(pos.x * pos.y) / float (size.x * size.y));\n"
3802             "  rayQueryEXT rayQuery;\n"
3803             "\n"
3804             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
3805             "tmin, direct, tmax);\n"
3806             "\n"
3807             "  if (rayQueryProceedEXT(rayQuery))\n"
3808             "  {\n"
3809             "    value -= mat4x3(k);\n"
3810             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
3811             "    {\n"
3812             "      value -= mat4x3(k);\n"
3813             "      rayQueryGenerateIntersectionEXT(rayQuery, t);\n"
3814             "\n"
3815             "      rayQueryProceedEXT(rayQuery);\n"
3816             "\n"
3817             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == "
3818             "gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
3819             "        value = mat4x3(k * rayQueryGetIntersectionObjectToWorldEXT(rayQuery, true));\n"
3820             "    }\n"
3821             "  }\n"
3822             "\n"
3823             "  int ndx = -1;\n"
3824             "  for (int row = 0; row < 3; row++)\n"
3825             "  for (int col = 0; col < 4; col++)\n"
3826             "  {\n"
3827             "    ndx++;\n"
3828             "    ivec3 p = ivec3(pos.xy, ndx);\n"
3829             "    float r = value[col][row];\n"
3830             "    ivec4 c = ivec4(int(r),0,0,1);\n"
3831             "    imageStore(result, p, c);\n"
3832             "  }\n";
3833 
3834         return result;
3835     }
3836     else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
3837     {
3838         const std::string result =
3839             "  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) +
3840             ";\n"
3841             "  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
3842             "  uint        cullMask = 0xFF;\n"
3843             "  float       tmin     = 0.0;\n"
3844             "  float       tmax     = 9.0;\n"
3845             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
3846             "float(size.y), 0.0);\n"
3847             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3848             "  mat4x3      value    = mat4x3(-k);\n"
3849             "  rayQueryEXT rayQuery;\n"
3850             "\n"
3851             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
3852             "tmin, direct, tmax);\n"
3853             "\n"
3854             "  if (rayQueryProceedEXT(rayQuery))\n"
3855             "  {\n"
3856             "    value -= mat4x3(k);\n"
3857             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
3858             "    {\n"
3859             "      value -= mat4x3(k);\n"
3860             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
3861             "\n"
3862             "      rayQueryProceedEXT(rayQuery);\n"
3863             "\n"
3864             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
3865             "        value = mat4x3(k * rayQueryGetIntersectionObjectToWorldEXT(rayQuery, true));\n"
3866             "    }\n"
3867             "  }\n"
3868             "\n"
3869             "  int ndx = -1;\n"
3870             "  for (int row = 0; row < 3; row++)\n"
3871             "  for (int col = 0; col < 4; col++)\n"
3872             "  {\n"
3873             "    ndx++;\n"
3874             "    ivec3 p = ivec3(pos.xy, ndx);\n"
3875             "    float r = value[col][row];\n"
3876             "    ivec4 c = ivec4(int(r),0,0,1);\n"
3877             "    imageStore(result, p, c);\n"
3878             "  }\n";
3879 
3880         return result;
3881     }
3882     else
3883     {
3884         TCU_THROW(InternalError, "Unknown geometry type");
3885     }
3886 }
3887 
3888 class TestConfigurationWorldToObject : public TestConfigurationMatrix
3889 {
3890 public:
TestConfigurationWorldToObject(Context & context)3891     TestConfigurationWorldToObject(Context &context) : TestConfigurationMatrix(context)
3892     {
3893     }
3894     static const std::string getShaderBodyText(const TestParams &testParams);
3895 
3896     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
3897                                                                          VkCommandBuffer cmdBuffer) override;
3898 };
3899 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)3900 const VkAccelerationStructureKHR *TestConfigurationWorldToObject::initAccelerationStructures(TestParams &testParams,
3901                                                                                              VkCommandBuffer cmdBuffer)
3902 {
3903     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
3904     const VkDevice device               = m_testEnvironment->device;
3905     Allocator &allocator                = *m_testEnvironment->allocator;
3906     const uint32_t width                = testParams.width;
3907     const uint32_t height               = testParams.height;
3908     const bool triangles                = (testParams.geomType == GEOM_TYPE_TRIANGLES);
3909     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
3910     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
3911     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
3912     const float z                       = -1.0f;
3913     tcu::UVec2 startPos                 = tcu::UVec2(0, 0);
3914     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
3915         makeTopLevelAccelerationStructure();
3916 
3917     DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
3918 
3919     m_topAccelerationStructure =
3920         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
3921 
3922     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
3923 
3924     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
3925     {
3926         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
3927             makeBottomLevelAccelerationStructure();
3928         VkTransformMatrixKHR transform = identityMatrix3x4;
3929 
3930         transform.matrix[0][3] = (1.0f / 8.0f) / float(width);
3931         transform.matrix[1][3] = (1.0f / 16.0f) / float(height);
3932 
3933         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
3934         {
3935             std::vector<tcu::Vec3> geometryData;
3936 
3937             geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
3938 
3939             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
3940             {
3941                 const uint32_t n = width * startPos.y() + startPos.x();
3942                 const uint32_t m = (n + 11) % (width * height);
3943                 const float x0   = float(startPos.x() + 0) / float(width);
3944                 const float y0   = float(startPos.y() + 0) / float(height);
3945                 const float x1   = float(startPos.x() + 1) / float(width);
3946                 const float y1   = float(startPos.y() + 1) / float(height);
3947 
3948                 if (triangles)
3949                 {
3950                     const float xm = (x0 + x1) / 2.0f;
3951                     const float ym = (y0 + y1) / 2.0f;
3952 
3953                     geometryData.push_back(tcu::Vec3(x0, y0, z));
3954                     geometryData.push_back(tcu::Vec3(xm, y1, z));
3955                     geometryData.push_back(tcu::Vec3(x1, ym, z));
3956                 }
3957                 else
3958                 {
3959                     geometryData.push_back(tcu::Vec3(x0, y0, z));
3960                     geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
3961                 }
3962 
3963                 startPos.y() = m / width;
3964                 startPos.x() = m % width;
3965             }
3966 
3967             rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
3968         }
3969 
3970         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3971         m_bottomAccelerationStructures.push_back(
3972             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
3973         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), transform);
3974     }
3975 
3976     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3977 
3978     {
3979         const uint32_t imageDepth       = 4 * 4;
3980         const int translateColumnNumber = 3;
3981         const uint32_t colCount         = 4;
3982         const uint32_t rowCount         = 3;
3983         const uint32_t zStride          = height * width;
3984         const uint32_t expectedFloats   = imageDepth * zStride;
3985         const float translateX          = (-1.0f / 8.0f) / float(width);
3986         const float translateY          = (-1.0f / 16.0f) / float(height);
3987         tcu::Matrix<float, rowCount, colCount> m;
3988 
3989         m[translateColumnNumber][0] = translateX;
3990         m[translateColumnNumber][1] = translateY;
3991 
3992         m_expected.resize(expectedFloats);
3993 
3994         for (uint32_t y = 0; y < height; ++y)
3995         {
3996             for (uint32_t x = 0; x < width; ++x)
3997             {
3998                 const uint32_t elem0Pos = x + width * y;
3999 
4000                 for (uint32_t rowNdx = 0; rowNdx < rowCount; ++rowNdx)
4001                     for (uint32_t colNdx = 0; colNdx < colCount; ++colNdx)
4002                     {
4003                         const uint32_t zNdx   = rowNdx * colCount + colNdx;
4004                         const uint32_t posNdx = elem0Pos + zStride * zNdx;
4005 
4006                         m_expected[posNdx] = static_cast<int32_t>(FIXED_POINT_DIVISOR * m[colNdx][rowNdx]);
4007                     }
4008             }
4009         }
4010     }
4011 
4012     return m_topAccelerationStructure.get()->getPtr();
4013 }
4014 
getShaderBodyText(const TestParams & testParams)4015 const std::string TestConfigurationWorldToObject::getShaderBodyText(const TestParams &testParams)
4016 {
4017     if (testParams.geomType == GEOM_TYPE_AABBS)
4018     {
4019         const std::string result =
4020             "  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) +
4021             ";\n"
4022             "  uint        rayFlags = 0;\n"
4023             "  uint        cullMask = 0xFF;\n"
4024             "  float       tmin     = 0.0;\n"
4025             "  float       tmax     = 9.0;\n"
4026             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
4027             "float(size.y), 0.0);\n"
4028             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
4029             "  mat4x3      value    = mat4x3(-k);\n"
4030             "  const float t        = abs(float(pos.x * pos.y) / float (size.x * size.y));\n"
4031             "  rayQueryEXT rayQuery;\n"
4032             "\n"
4033             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
4034             "tmin, direct, tmax);\n"
4035             "\n"
4036             "  if (rayQueryProceedEXT(rayQuery))\n"
4037             "  {\n"
4038             "    value -= mat4x3(k);\n"
4039             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
4040             "    {\n"
4041             "      value -= mat4x3(k);\n"
4042             "      rayQueryGenerateIntersectionEXT(rayQuery, t);\n"
4043             "\n"
4044             "      rayQueryProceedEXT(rayQuery);\n"
4045             "\n"
4046             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == "
4047             "gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
4048             "        value = mat4x3(k * rayQueryGetIntersectionWorldToObjectEXT(rayQuery, true));\n"
4049             "    }\n"
4050             "  }\n"
4051             "\n"
4052             "  int ndx = -1;\n"
4053             "  for (int row = 0; row < 3; row++)\n"
4054             "  for (int col = 0; col < 4; col++)\n"
4055             "  {\n"
4056             "    ndx++;\n"
4057             "    ivec3 p = ivec3(pos.xy, ndx);\n"
4058             "    float r = value[col][row];\n"
4059             "    ivec4 c = ivec4(int(r),0,0,1);\n"
4060             "    imageStore(result, p, c);\n"
4061             "  }\n";
4062 
4063         return result;
4064     }
4065     else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
4066     {
4067         const std::string result =
4068             "  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) +
4069             ";\n"
4070             "  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
4071             "  uint        cullMask = 0xFF;\n"
4072             "  float       tmin     = 0.0;\n"
4073             "  float       tmax     = 9.0;\n"
4074             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
4075             "float(size.y), 0.0);\n"
4076             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
4077             "  mat4x3      value    = mat4x3(-k);\n"
4078             "  rayQueryEXT rayQuery;\n"
4079             "\n"
4080             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
4081             "tmin, direct, tmax);\n"
4082             "\n"
4083             "  if (rayQueryProceedEXT(rayQuery))\n"
4084             "  {\n"
4085             "    value -= mat4x3(k);\n"
4086             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
4087             "    {\n"
4088             "      value -= mat4x3(k);\n"
4089             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
4090             "\n"
4091             "      rayQueryProceedEXT(rayQuery);\n"
4092             "\n"
4093             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
4094             "        value = mat4x3(k * rayQueryGetIntersectionWorldToObjectEXT(rayQuery, true));\n"
4095             "    }\n"
4096             "  }\n"
4097             "\n"
4098             "  int ndx = -1;\n"
4099             "  for (int row = 0; row < 3; row++)\n"
4100             "  for (int col = 0; col < 4; col++)\n"
4101             "  {\n"
4102             "    ndx++;\n"
4103             "    ivec3 p = ivec3(pos.xy, ndx);\n"
4104             "    float r = value[col][row];\n"
4105             "    ivec4 c = ivec4(int(r),0,0,1);\n"
4106             "    imageStore(result, p, c);\n"
4107             "  }\n";
4108 
4109         return result;
4110     }
4111     else
4112     {
4113         TCU_THROW(InternalError, "Unknown geometry type");
4114     }
4115 }
4116 
4117 class TestConfigurationNullASStruct : public TestConfiguration
4118 {
4119 public:
4120     TestConfigurationNullASStruct(Context &context);
4121     ~TestConfigurationNullASStruct();
4122 
4123     static const std::string getShaderBodyText(const TestParams &testParams);
4124     static void checkSupport(Context &context, const TestParams &testParams);
4125 
4126     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
4127                                                                          VkCommandBuffer cmdBuffer) override;
4128 
4129 protected:
4130     void prepareTestEnvironment(Context &context);
4131     Move<VkAccelerationStructureKHR> m_emptyAccelerationStructure;
4132 
4133     Move<VkDevice> m_device;
4134     de::MovePtr<DeviceDriver> m_vkd;
4135     de::MovePtr<SimpleAllocator> m_allocator;
4136 };
4137 
TestConfigurationNullASStruct(Context & context)4138 TestConfigurationNullASStruct::TestConfigurationNullASStruct(Context &context)
4139     : TestConfiguration(context)
4140     , m_emptyAccelerationStructure()
4141     , m_device()
4142     , m_vkd()
4143     , m_allocator()
4144 {
4145     prepareTestEnvironment(context);
4146 }
4147 
~TestConfigurationNullASStruct()4148 TestConfigurationNullASStruct::~TestConfigurationNullASStruct()
4149 {
4150 }
4151 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)4152 const VkAccelerationStructureKHR *TestConfigurationNullASStruct::initAccelerationStructures(TestParams &testParams,
4153                                                                                             VkCommandBuffer cmdBuffer)
4154 {
4155     DE_UNREF(cmdBuffer);
4156 
4157     m_expected = std::vector<int32_t>(testParams.width * testParams.height, 1);
4158 
4159     return &m_emptyAccelerationStructure.get();
4160 }
4161 
checkSupport(Context & context,const TestParams & testParams)4162 void TestConfigurationNullASStruct::checkSupport(Context &context, const TestParams &testParams)
4163 {
4164     DE_UNREF(testParams);
4165 
4166     // Check if the physical device supports VK_EXT_robustness2 and the nullDescriptor feature.
4167     const auto &vki                 = context.getInstanceInterface();
4168     const auto physicalDevice       = context.getPhysicalDevice();
4169     const auto &supportedExtensions = enumerateCachedDeviceExtensionProperties(vki, physicalDevice);
4170 
4171     if (!isExtensionStructSupported(supportedExtensions, RequiredExtension("VK_EXT_robustness2")))
4172         TCU_THROW(NotSupportedError, "VK_EXT_robustness2 not supported");
4173 
4174     VkPhysicalDeviceRobustness2FeaturesEXT robustness2Features = initVulkanStructure();
4175     VkPhysicalDeviceFeatures2 features2                        = initVulkanStructure(&robustness2Features);
4176 
4177     vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
4178     if (!robustness2Features.nullDescriptor)
4179         TCU_THROW(NotSupportedError, "VkPhysicalDeviceRobustness2FeaturesEXT::nullDescriptor not supported");
4180 }
4181 
prepareTestEnvironment(Context & context)4182 void TestConfigurationNullASStruct::prepareTestEnvironment(Context &context)
4183 {
4184     // Check if the physical device supports VK_EXT_robustness2 and the nullDescriptor feature.
4185     const auto &vkp             = context.getPlatformInterface();
4186     const auto &vki             = context.getInstanceInterface();
4187     const auto instance         = context.getInstance();
4188     const auto physicalDevice   = context.getPhysicalDevice();
4189     const auto queueFamilyIndex = context.getUniversalQueueFamilyIndex();
4190     const auto queuePriority    = 1.0f;
4191     bool accelStructSupport     = false;
4192 
4193     // Add anything that's supported and may be needed, including nullDescriptor.
4194     VkPhysicalDeviceFeatures2 features2                                            = initVulkanStructure();
4195     VkPhysicalDeviceBufferDeviceAddressFeaturesKHR deviceAddressFeatures           = initVulkanStructure();
4196     VkPhysicalDeviceAccelerationStructureFeaturesKHR accelerationStructureFeatures = initVulkanStructure();
4197     VkPhysicalDeviceRayQueryFeaturesKHR rayQueryFeatures                           = initVulkanStructure();
4198     VkPhysicalDeviceRayTracingPipelineFeaturesKHR raytracingPipelineFeatures       = initVulkanStructure();
4199     VkPhysicalDeviceRobustness2FeaturesEXT robustness2Features                     = initVulkanStructure();
4200     std::vector<const char *> deviceExtensions;
4201 
4202     if (context.isDeviceFunctionalitySupported("VK_KHR_deferred_host_operations"))
4203     {
4204         deviceExtensions.push_back("VK_KHR_deferred_host_operations");
4205     }
4206     if (context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address"))
4207     {
4208         deviceAddressFeatures.pNext = features2.pNext;
4209         features2.pNext             = &deviceAddressFeatures;
4210         deviceExtensions.push_back("VK_KHR_buffer_device_address");
4211     }
4212     if (context.isDeviceFunctionalitySupported("VK_KHR_acceleration_structure"))
4213     {
4214         accelerationStructureFeatures.pNext = features2.pNext;
4215         features2.pNext                     = &accelerationStructureFeatures;
4216         deviceExtensions.push_back("VK_KHR_acceleration_structure");
4217         accelStructSupport = true;
4218     }
4219 
4220     if (context.isDeviceFunctionalitySupported("VK_KHR_ray_query"))
4221     {
4222         rayQueryFeatures.pNext = features2.pNext;
4223         features2.pNext        = &rayQueryFeatures;
4224         deviceExtensions.push_back("VK_KHR_ray_query");
4225     }
4226 
4227     if (context.isDeviceFunctionalitySupported("VK_KHR_ray_tracing_pipeline"))
4228     {
4229         raytracingPipelineFeatures.pNext = features2.pNext;
4230         features2.pNext                  = &raytracingPipelineFeatures;
4231         deviceExtensions.push_back("VK_KHR_ray_tracing_pipeline");
4232     }
4233 
4234     vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
4235 
4236     // Add robustness2 features to the chain and make sure robustBufferAccess is consistent with robustBufferAccess2.
4237     features2.features.robustBufferAccess = VK_FALSE;
4238     robustness2Features.nullDescriptor    = VK_TRUE;
4239     robustness2Features.pNext             = features2.pNext;
4240     features2.pNext                       = &robustness2Features;
4241 
4242     // Add more needed extensions.
4243     deviceExtensions.push_back("VK_EXT_robustness2");
4244     if (accelStructSupport)
4245     {
4246         // Not promoted yet in Vulkan 1.1.
4247         deviceExtensions.push_back("VK_EXT_descriptor_indexing");
4248         deviceExtensions.push_back("VK_KHR_spirv_1_4");
4249         deviceExtensions.push_back("VK_KHR_shader_float_controls");
4250     }
4251 
4252     const VkDeviceQueueCreateInfo queueInfo = {
4253         VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
4254         nullptr,                                    // const void* pNext;
4255         0u,                                         // VkDeviceQueueCreateFlags flags;
4256         queueFamilyIndex,                           // uint32_t queueFamilyIndex;
4257         1u,                                         // uint32_t queueCount;
4258         &queuePriority,                             // const float* pQueuePriorities;
4259     };
4260 
4261     const VkDeviceCreateInfo createInfo = {
4262         VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,           // VkStructureType sType;
4263         features2.pNext,                                // const void* pNext;
4264         0u,                                             // VkDeviceCreateFlags flags;
4265         1u,                                             // uint32_t queueCreateInfoCount;
4266         &queueInfo,                                     // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
4267         0u,                                             // uint32_t enabledLayerCount;
4268         nullptr,                                        // const char* const* ppEnabledLayerNames;
4269         static_cast<uint32_t>(deviceExtensions.size()), // uint32_t enabledExtensionCount;
4270         deviceExtensions.data(),                        // const char* const* ppEnabledExtensionNames;
4271         &features2.features,                            // const VkPhysicalDeviceFeatures* pEnabledFeatures;
4272     };
4273 
4274     m_device = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki,
4275                                   physicalDevice, &createInfo);
4276     m_vkd    = de::MovePtr<DeviceDriver>(new DeviceDriver(vkp, instance, m_device.get(), context.getUsedApiVersion(),
4277                                                           context.getTestContext().getCommandLine()));
4278     const auto queue = getDeviceQueue(*m_vkd, *m_device, queueFamilyIndex, 0u);
4279     m_allocator      = de::MovePtr<SimpleAllocator>(
4280         new SimpleAllocator(*m_vkd, m_device.get(), getPhysicalDeviceMemoryProperties(vki, physicalDevice)));
4281 
4282     m_testEnvironment = de::MovePtr<TestEnvironment>(new TestEnvironment{
4283         &vki,                               // const InstanceInterface* vki;
4284         physicalDevice,                     // VkPhysicalDevice physicalDevice;
4285         m_vkd.get(),                        // const DeviceInterface* vkd;
4286         m_device.get(),                     // VkDevice device;
4287         m_allocator.get(),                  // Allocator* allocator;
4288         queue,                              // VkQueue queue;
4289         queueFamilyIndex,                   // uint32_t queueFamilyIndex;
4290         &context.getBinaryCollection(),     // BinaryCollection* binaryCollection;
4291         &context.getTestContext().getLog(), // tcu::TestLog* log;
4292     });
4293 }
4294 
getShaderBodyText(const TestParams & testParams)4295 const std::string TestConfigurationNullASStruct::getShaderBodyText(const TestParams &testParams)
4296 {
4297     DE_UNREF(testParams);
4298 
4299     const std::string result = "  uint        rayFlags = 0;\n"
4300                                "  uint        cullMask = 0xFF;\n"
4301                                "  float       tmin     = 0.0;\n"
4302                                "  float       tmax     = 9.0;\n"
4303                                "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + "
4304                                "0.5f) / float(size.y), 0.0);\n"
4305                                "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
4306                                "  uint        value    = 1;\n"
4307                                "  rayQueryEXT rayQuery;\n"
4308                                "\n"
4309                                "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, "
4310                                "cullMask, origin, tmin, direct, tmax);\n"
4311                                "\n"
4312                                "  if (rayQueryProceedEXT(rayQuery))\n"
4313                                "  {\n"
4314                                "    value++;\n"
4315                                "\n"
4316                                "    rayQueryTerminateEXT(rayQuery);\n"
4317                                "  }\n"
4318                                "\n"
4319                                "  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
4320 
4321     return result;
4322 }
4323 
4324 class TestConfigurationGetIntersectionCandidateAABBOpaque : public TestConfiguration
4325 {
4326 public:
TestConfigurationGetIntersectionCandidateAABBOpaque(Context & context)4327     TestConfigurationGetIntersectionCandidateAABBOpaque(Context &context) : TestConfiguration(context)
4328     {
4329     }
4330     static const std::string getShaderBodyText(const TestParams &testParams);
4331 
4332     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
4333                                                                          VkCommandBuffer cmdBuffer) override;
4334 };
4335 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)4336 const VkAccelerationStructureKHR *TestConfigurationGetIntersectionCandidateAABBOpaque::initAccelerationStructures(
4337     TestParams &testParams, VkCommandBuffer cmdBuffer)
4338 {
4339     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
4340     const VkDevice device               = m_testEnvironment->device;
4341     Allocator &allocator                = *m_testEnvironment->allocator;
4342     const uint32_t width                = testParams.width;
4343     const uint32_t height               = testParams.height;
4344     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
4345     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
4346     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
4347     const bool usesTriangles            = (testParams.geomType == GEOM_TYPE_TRIANGLES);
4348     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
4349         makeTopLevelAccelerationStructure();
4350 
4351     DE_ASSERT(instancesGroupCount == 1);
4352     DE_ASSERT(geometriesGroupCount == 1);
4353     DE_ASSERT(squaresGroupCount == width * height);
4354 
4355     m_topAccelerationStructure =
4356         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
4357 
4358     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
4359 
4360     m_expected.resize(width * height);
4361 
4362     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
4363     {
4364         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
4365             makeBottomLevelAccelerationStructure();
4366 
4367         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
4368         {
4369             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
4370             {
4371                 std::vector<tcu::Vec3> geometryData;
4372 
4373                 const auto squareX             = (squareNdx % width);
4374                 const auto squareY             = (squareNdx / width);
4375                 const bool isOpaque            = (squareNdx % 2) == 0;
4376                 const VkGeometryFlagsKHR flags = (isOpaque) ? VK_GEOMETRY_OPAQUE_BIT_KHR : 0;
4377 
4378                 const float x0 = float(squareX + 0) / float(width);
4379                 const float y0 = float(squareY + 0) / float(height);
4380                 const float x1 = float(squareX + 1) / float(width);
4381                 const float y1 = float(squareY + 1) / float(height);
4382 
4383                 if (usesTriangles)
4384                 {
4385                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4386                     geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
4387                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4388 
4389                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4390                     geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
4391                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4392                 }
4393                 else
4394                 {
4395                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4396                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4397                 }
4398 
4399                 rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, usesTriangles, flags);
4400             }
4401         }
4402 
4403         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4404         m_bottomAccelerationStructures.push_back(
4405             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
4406         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4,
4407                                                 instanceNdx + 1);
4408     }
4409 
4410     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4411 
4412     for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
4413     {
4414         m_expected.at(squareNdx) = (squareNdx % 2) == 0;
4415     }
4416 
4417     return m_topAccelerationStructure.get()->getPtr();
4418 }
4419 
getShaderBodyText(const TestParams & testParams)4420 const std::string TestConfigurationGetIntersectionCandidateAABBOpaque::getShaderBodyText(const TestParams &testParams)
4421 {
4422     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
4423     {
4424         const std::string result =
4425             "  uint        rayFlags = 0;\n"
4426             "  uint        cullMask = 0xFF;\n"
4427             "  float       tmin     = 0.0001;\n"
4428             "  float       tmax     = 9.0;\n"
4429             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
4430             "float(size.y), 0.2);\n"
4431             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
4432             "  rayQueryEXT rayQuery;\n"
4433             "\n"
4434             "  int result_i32 = 0;\n"
4435             "\n"
4436             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
4437             "tmin, direct, tmax);\n"
4438             "\n"
4439             "  while (rayQueryProceedEXT(rayQuery))\n"
4440             "  {\n"
4441             "      if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
4442             "      {\n"
4443             "          result_i32 |= rayQueryGetIntersectionCandidateAABBOpaqueEXT(rayQuery) ? 1 : 0;\n"
4444             "\n"
4445             "          rayQueryConfirmIntersectionEXT(rayQuery);\n"
4446             "      }\n"
4447             "  }\n"
4448             "\n"
4449             "  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
4450 
4451         return result;
4452     }
4453     else
4454     {
4455         TCU_THROW(InternalError, "Unknown geometry type");
4456     }
4457 }
4458 
4459 class TestConfigurationGetIntersectionFrontFace : public TestConfiguration
4460 {
4461 public:
TestConfigurationGetIntersectionFrontFace(Context & context)4462     TestConfigurationGetIntersectionFrontFace(Context &context) : TestConfiguration(context)
4463     {
4464     }
4465     static const std::string getShaderBodyTextCandidate(const TestParams &testParams);
4466     static const std::string getShaderBodyTextCommitted(const TestParams &testParams);
4467 
4468     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
4469                                                                          VkCommandBuffer cmdBuffer) override;
4470 };
4471 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)4472 const VkAccelerationStructureKHR *TestConfigurationGetIntersectionFrontFace::initAccelerationStructures(
4473     TestParams &testParams, VkCommandBuffer cmdBuffer)
4474 {
4475     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
4476     const VkDevice device               = m_testEnvironment->device;
4477     Allocator &allocator                = *m_testEnvironment->allocator;
4478     const uint32_t width                = testParams.width;
4479     const uint32_t height               = testParams.height;
4480     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
4481     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
4482     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
4483     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
4484         makeTopLevelAccelerationStructure();
4485 
4486     DE_ASSERT(instancesGroupCount == 1);
4487     DE_ASSERT(geometriesGroupCount == 1);
4488     DE_ASSERT(squaresGroupCount == width * height);
4489 
4490     m_topAccelerationStructure =
4491         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
4492 
4493     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
4494 
4495     m_expected.resize(width * height);
4496 
4497     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
4498     {
4499         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
4500             makeBottomLevelAccelerationStructure();
4501 
4502         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
4503         {
4504             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
4505             {
4506                 std::vector<tcu::Vec3> geometryData;
4507 
4508                 const auto squareX = (squareNdx % width);
4509                 const auto squareY = (squareNdx / width);
4510 
4511                 const float x0 = float(squareX + 0) / float(width);
4512                 const float y0 = float(squareY + 0) / float(height);
4513                 const float x1 = float(squareX + 1) / float(width);
4514                 const float y1 = float(squareY + 1) / float(height);
4515 
4516                 if ((squareNdx % 2) == 0)
4517                 {
4518                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4519                     geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
4520                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4521 
4522                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4523                     geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
4524                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4525                 }
4526                 else
4527                 {
4528                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4529                     geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
4530                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4531 
4532                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4533                     geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
4534                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4535                 }
4536 
4537                 rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, true /* triangles */);
4538             }
4539         }
4540 
4541         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4542         m_bottomAccelerationStructures.push_back(
4543             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
4544         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4,
4545                                                 instanceNdx + 1);
4546     }
4547 
4548     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4549 
4550     for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
4551     {
4552         m_expected.at(squareNdx) = (squareNdx % 2) != 0;
4553     }
4554 
4555     return m_topAccelerationStructure.get()->getPtr();
4556 }
4557 
getShaderBodyTextCandidate(const TestParams & testParams)4558 const std::string TestConfigurationGetIntersectionFrontFace::getShaderBodyTextCandidate(const TestParams &testParams)
4559 {
4560     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
4561     {
4562         const std::string result = "  uint        rayFlags = 0;\n"
4563                                    "  uint        cullMask = 0xFF;\n"
4564                                    "  float       tmin     = 0.0001;\n"
4565                                    "  float       tmax     = 9.0;\n"
4566                                    "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) "
4567                                    "+ 0.5f) / float(size.y),  0.2);\n"
4568                                    "  vec3        direct   = vec3(0,   0, "
4569                                    "                             -1.0);\n"
4570                                    "  rayQueryEXT rayQuery;\n"
4571                                    "\n"
4572                                    "  int result_i32 = 2;\n"
4573                                    "\n"
4574                                    "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, "
4575                                    "cullMask, origin, tmin, direct, tmax);\n"
4576                                    "\n"
4577                                    "  while (rayQueryProceedEXT(rayQuery))\n"
4578                                    "  {\n"
4579                                    "      result_i32 = rayQueryGetIntersectionFrontFaceEXT(rayQuery, false) ? 1 : 0;\n"
4580                                    "\n"
4581                                    "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
4582                                    "  }\n"
4583                                    "\n"
4584                                    "  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
4585 
4586         return result;
4587     }
4588     else
4589     {
4590         TCU_THROW(InternalError, "Unknown geometry type");
4591     }
4592 }
4593 
getShaderBodyTextCommitted(const TestParams & testParams)4594 const std::string TestConfigurationGetIntersectionFrontFace::getShaderBodyTextCommitted(const TestParams &testParams)
4595 {
4596     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
4597     {
4598         const std::string result =
4599             "  uint        rayFlags = 0;\n"
4600             "  uint        cullMask = 0xFF;\n"
4601             "  float       tmin     = 0.0001;\n"
4602             "  float       tmax     = 9.0;\n"
4603             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
4604             "float(size.y),  0.2);\n"
4605             "  vec3        direct   = vec3(0,   0,    "
4606             "  -1.0);\n"
4607             "  rayQueryEXT rayQuery;\n"
4608             "\n"
4609             "  bool intersection_found = false;\n"
4610             "  int  result_i32         = 0;\n"
4611             "\n"
4612             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
4613             "tmin, direct, tmax);\n"
4614             "\n"
4615             "  while (rayQueryProceedEXT(rayQuery))\n"
4616             "  {\n"
4617             "      intersection_found = true;\n"
4618             "\n"
4619             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
4620             "  }\n"
4621             "\n"
4622             "  result_i32 = (intersection_found) ? (rayQueryGetIntersectionFrontFaceEXT(rayQuery, true) ? 1 : 0)\n"
4623             "                                     : 2;\n"
4624             "\n"
4625             "  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
4626 
4627         return result;
4628     }
4629     else
4630     {
4631         TCU_THROW(InternalError, "Unknown geometry type");
4632     }
4633 }
4634 
4635 class TestConfigurationGetIntersectionGeometryIndex : public TestConfiguration
4636 {
4637 public:
TestConfigurationGetIntersectionGeometryIndex(Context & context)4638     TestConfigurationGetIntersectionGeometryIndex(Context &context) : TestConfiguration(context)
4639     {
4640     }
4641     static const std::string getShaderBodyTextCandidate(const TestParams &testParams);
4642     static const std::string getShaderBodyTextCommitted(const TestParams &testParams);
4643 
4644     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
4645                                                                          VkCommandBuffer cmdBuffer) override;
4646 };
4647 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)4648 const VkAccelerationStructureKHR *TestConfigurationGetIntersectionGeometryIndex::initAccelerationStructures(
4649     TestParams &testParams, VkCommandBuffer cmdBuffer)
4650 {
4651     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
4652     const VkDevice device               = m_testEnvironment->device;
4653     Allocator &allocator                = *m_testEnvironment->allocator;
4654     const uint32_t width                = testParams.width;
4655     const uint32_t height               = testParams.height;
4656     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
4657     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
4658     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
4659     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
4660         makeTopLevelAccelerationStructure();
4661 
4662     DE_ASSERT(instancesGroupCount == 1);
4663     DE_ASSERT(geometriesGroupCount == 1);
4664     DE_ASSERT(squaresGroupCount == width * height);
4665 
4666     m_topAccelerationStructure =
4667         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
4668 
4669     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
4670 
4671     m_expected.resize(width * height);
4672 
4673     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
4674     {
4675         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
4676             makeBottomLevelAccelerationStructure();
4677 
4678         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
4679         {
4680             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
4681             {
4682                 std::vector<tcu::Vec3> geometryData;
4683 
4684                 const auto squareX = (squareNdx % width);
4685                 const auto squareY = (squareNdx / width);
4686 
4687                 const float x0 = float(squareX + 0) / float(width);
4688                 const float y0 = float(squareY + 0) / float(height);
4689                 const float x1 = float(squareX + 1) / float(width);
4690                 const float y1 = float(squareY + 1) / float(height);
4691 
4692                 if ((squareNdx % 2) == 0)
4693                 {
4694                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4695                     geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
4696                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4697 
4698                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4699                     geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
4700                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4701                 }
4702                 else
4703                 {
4704                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4705                     geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
4706                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4707 
4708                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4709                     geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
4710                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4711                 }
4712 
4713                 rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, true /* triangles */);
4714             }
4715         }
4716 
4717         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4718         m_bottomAccelerationStructures.push_back(
4719             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
4720         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4,
4721                                                 instanceNdx + 1);
4722     }
4723 
4724     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4725 
4726     for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
4727     {
4728         m_expected.at(squareNdx) = squareNdx;
4729     }
4730 
4731     return m_topAccelerationStructure.get()->getPtr();
4732 }
4733 
getShaderBodyTextCandidate(const TestParams & testParams)4734 const std::string TestConfigurationGetIntersectionGeometryIndex::getShaderBodyTextCandidate(
4735     const TestParams &testParams)
4736 {
4737     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
4738     {
4739         const std::string result = "  uint        rayFlags = 0;\n"
4740                                    "  uint        cullMask = 0xFF;\n"
4741                                    "  float       tmin     = 0.0001;\n"
4742                                    "  float       tmax     = 9.0;\n"
4743                                    "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) "
4744                                    "+ 0.5f) / float(size.y),  0.2);\n"
4745                                    "  vec3        direct   = vec3(0,   0, "
4746                                    "                             -1.0);\n"
4747                                    "  rayQueryEXT rayQuery;\n"
4748                                    "\n"
4749                                    "  int result_i32 = 123456;\n"
4750                                    "\n"
4751                                    "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, "
4752                                    "cullMask, origin, tmin, direct, tmax);\n"
4753                                    "\n"
4754                                    "  while (rayQueryProceedEXT(rayQuery))\n"
4755                                    "  {\n"
4756                                    "      result_i32 = rayQueryGetIntersectionGeometryIndexEXT(rayQuery, false);\n"
4757                                    "\n"
4758                                    "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
4759                                    "  }\n"
4760                                    "\n"
4761                                    "  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
4762 
4763         return result;
4764     }
4765     else
4766     {
4767         TCU_THROW(InternalError, "Unknown geometry type");
4768     }
4769 }
4770 
getShaderBodyTextCommitted(const TestParams & testParams)4771 const std::string TestConfigurationGetIntersectionGeometryIndex::getShaderBodyTextCommitted(
4772     const TestParams &testParams)
4773 {
4774     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
4775     {
4776         const std::string result =
4777             "  uint        rayFlags = 0;\n"
4778             "  uint        cullMask = 0xFF;\n"
4779             "  float       tmin     = 0.0001;\n"
4780             "  float       tmax     = 9.0;\n"
4781             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
4782             "float(size.y),  0.2);\n"
4783             "  vec3        direct   = vec3(0,   0,    "
4784             "  -1.0);\n"
4785             "  rayQueryEXT rayQuery;\n"
4786             "\n"
4787             "  bool intersection_found = false;\n"
4788             "  int  result_i32         = 0;\n"
4789             "\n"
4790             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
4791             "tmin, direct, tmax);\n"
4792             "\n"
4793             "  while (rayQueryProceedEXT(rayQuery))\n"
4794             "  {\n"
4795             "      intersection_found = true;\n"
4796             "\n"
4797             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
4798             "  }\n"
4799             "\n"
4800             "  result_i32 = (intersection_found) ? (rayQueryGetIntersectionGeometryIndexEXT(rayQuery, true) )\n"
4801             "                                     : 2;\n"
4802             "\n"
4803             "  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
4804 
4805         return result;
4806     }
4807     else
4808     {
4809         TCU_THROW(InternalError, "Unknown geometry type");
4810     }
4811 }
4812 
4813 class TestConfigurationGetIntersectionBarycentrics : public TestConfigurationVector
4814 {
4815 public:
TestConfigurationGetIntersectionBarycentrics(Context & context)4816     TestConfigurationGetIntersectionBarycentrics(Context &context) : TestConfigurationVector(context, false)
4817     {
4818         /* Stub */
4819     }
4820 
4821     static const std::string getShaderBodyTextCandidate(const TestParams &testParams);
4822     static const std::string getShaderBodyTextCommitted(const TestParams &testParams);
4823 
4824     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
4825                                                                          VkCommandBuffer cmdBuffer) override;
4826 };
4827 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)4828 const VkAccelerationStructureKHR *TestConfigurationGetIntersectionBarycentrics::initAccelerationStructures(
4829     TestParams &testParams, VkCommandBuffer cmdBuffer)
4830 {
4831     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
4832     const VkDevice device               = m_testEnvironment->device;
4833     Allocator &allocator                = *m_testEnvironment->allocator;
4834     const uint32_t width                = testParams.width;
4835     const uint32_t height               = testParams.height;
4836     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
4837     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
4838     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
4839     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
4840         makeTopLevelAccelerationStructure();
4841 
4842     DE_ASSERT(instancesGroupCount == 1);
4843     DE_ASSERT(geometriesGroupCount == 1);
4844     DE_ASSERT(squaresGroupCount == width * height);
4845 
4846     m_topAccelerationStructure =
4847         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
4848 
4849     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
4850 
4851     m_expected.resize(width * height * 3);
4852 
4853     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
4854     {
4855         de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
4856             makeBottomLevelAccelerationStructure();
4857 
4858         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
4859         {
4860             for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
4861             {
4862                 std::vector<tcu::Vec3> geometryData;
4863 
4864                 const auto squareX = (squareNdx % width);
4865                 const auto squareY = (squareNdx / width);
4866 
4867                 const float x0 = float(squareX + 0) / float(width);
4868                 const float y0 = float(squareY + 0) / float(height);
4869                 const float x1 = float(squareX + 1) / float(width);
4870                 const float y1 = float(squareY + 1) / float(height);
4871 
4872                 const float x05 = x0 + (x1 - x0) * 0.5f;
4873                 const float y05 = y0 + (y1 - y0) * 0.5f;
4874 
4875                 geometryData.push_back(tcu::Vec3(x05, y0, 0.0));
4876                 geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
4877                 geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4878 
4879                 /* With each cell, ray target moves from (x1, y1) to (x0.5, y0.5). This guarantees a hit and different barycentric coords
4880                  * per each traced ray.
4881                  */
4882                 const float t = float(squareNdx) / float(squaresGroupCount - 1);
4883 
4884                 const float hitX = x0 + 0.125f / float(width) + (x1 - x05) * t;
4885                 const float hitY = y1 - 0.125f / float(height) - (y1 - y05) * t;
4886 
4887                 const float barycentricX = ((0 + (x1 - x0) * (hitY - y1)) / (0 + (x1 - x0) * (y0 - y1)));
4888                 const float barycentricY =
4889                     (((y1 - y0) * (hitX - x1) + (x05 - x1) * (hitY - y1)) / (0 + (x1 - x0) * (y0 - y1)));
4890 
4891                 m_expected.at(squaresGroupCount * 0 + squareNdx) =
4892                     static_cast<int32_t>(FIXED_POINT_DIVISOR * barycentricY);
4893                 m_expected.at(squaresGroupCount * 1 + squareNdx) =
4894                     static_cast<int32_t>(FIXED_POINT_DIVISOR * barycentricX);
4895                 m_expected.at(squaresGroupCount * 2 + squareNdx) =
4896                     static_cast<int32_t>(FIXED_POINT_DIVISOR * (1.0f - barycentricX - barycentricY));
4897 
4898                 rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, true /* triangles */);
4899             }
4900         }
4901 
4902         rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4903         m_bottomAccelerationStructures.push_back(
4904             de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
4905         m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4,
4906                                                 instanceNdx + 1);
4907     }
4908 
4909     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4910 
4911     return m_topAccelerationStructure.get()->getPtr();
4912 }
4913 
getShaderBodyTextCandidate(const TestParams & testParams)4914 const std::string TestConfigurationGetIntersectionBarycentrics::getShaderBodyTextCandidate(const TestParams &testParams)
4915 {
4916     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
4917     {
4918         const std::string result =
4919             "  uint        rayFlags = 0;\n"
4920             "  uint        cullMask = 0xFF;\n"
4921             "  float       tmin     = 0.0001;\n"
4922             "  float       tmax     = 9.0;\n"
4923             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
4924             "float(size.y),  0.2);\n"
4925             "\n"
4926             "  int         nSquare = pos.y * size.x + pos.x;\n"
4927             "  float       t        = float(pos.y * size.x + pos.x) / float(size.x * size.y - 1);\n"
4928             "  float       x0       = float(pos.x)     / float(size.x);\n"
4929             "  float       x1       = float(pos.x + 1) / float(size.x);\n"
4930             "  float       x05      = mix(x0, x1, 0.5);\n"
4931             "  float       y0       = float(pos.y)     / float(size.y);\n"
4932             "  float       y1       = float(pos.y + 1) / float(size.y);\n"
4933             "  float       y05      = mix(y0, y1, 0.5);\n"
4934             "  vec3        target   = vec3(x0 + 0.125 / float(size.x) + (x1 - x05) * t,\n"
4935             "                              y1 - 0.125 / float(size.y) - (y1 - y05) * t,\n"
4936             "                              0.0);\n"
4937             "  vec3        direct   = normalize(target - origin);\n"
4938             "\n"
4939             "  rayQueryEXT rayQuery;\n"
4940             "\n"
4941             "  vec2 result_fp32 = vec2(1234, 5678);\n"
4942             "\n"
4943             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
4944             "tmin, direct, tmax);\n"
4945             "\n"
4946             "  while (rayQueryProceedEXT(rayQuery))\n"
4947             "  {\n"
4948             "      result_fp32 = rayQueryGetIntersectionBarycentricsEXT(rayQuery, false);\n"
4949             "\n"
4950             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
4951             "  }\n"
4952             "\n"
4953             "  imageStore(result, ivec3(pos.xy, 0), ivec4(result_fp32.x * " +
4954             de::toString(FIXED_POINT_DIVISOR) +
4955             ", 0, 0, 0));\n"
4956             "  imageStore(result, ivec3(pos.xy, 1), ivec4(result_fp32.y * " +
4957             de::toString(FIXED_POINT_DIVISOR) +
4958             ", 0, 0, 0));\n"
4959             "  imageStore(result, ivec3(pos.xy, 2), ivec4((1.0 - result_fp32.x - result_fp32.y) * " +
4960             de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0));\n";
4961 
4962         return result;
4963     }
4964     else
4965     {
4966         TCU_THROW(InternalError, "Unknown geometry type");
4967     }
4968 }
4969 
getShaderBodyTextCommitted(const TestParams & testParams)4970 const std::string TestConfigurationGetIntersectionBarycentrics::getShaderBodyTextCommitted(const TestParams &testParams)
4971 {
4972     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
4973     {
4974         const std::string result =
4975             "  uint        rayFlags = 0;\n"
4976             "  uint        cullMask = 0xFF;\n"
4977             "  float       tmin     = 0.0001;\n"
4978             "  float       tmax     = 9.0;\n"
4979             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
4980             "float(size.y),  0.2);\n"
4981             "\n"
4982             "  int         nSquare = pos.y * size.x + pos.x;\n"
4983             "  float       t        = float(pos.y * size.x + pos.x) / float(size.x * size.y - 1);\n"
4984             "  float       x0       = float(pos.x)     / float(size.x);\n"
4985             "  float       x1       = float(pos.x + 1) / float(size.x);\n"
4986             "  float       x05      = mix(x0, x1, 0.5);\n"
4987             "  float       y0       = float(pos.y)     / float(size.y);\n"
4988             "  float       y1       = float(pos.y + 1) / float(size.y);\n"
4989             "  float       y05      = mix(y0, y1, 0.5);\n"
4990             "  vec3        target   = vec3(x0 + 0.125 / float(size.x) + (x1 - x05) * t,\n"
4991             "                              y1 - 0.125 / float(size.y) - (y1 - y05) * t,\n"
4992             "                              0.0);\n"
4993             "  vec3        direct   = normalize(target - origin);\n"
4994             "\n"
4995             "  rayQueryEXT rayQuery;\n"
4996             "\n"
4997             "  bool intersection_found = false;\n"
4998             "  vec2 result_fp32        = vec2(1234, 5678);\n"
4999             "\n"
5000             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
5001             "tmin, direct, tmax);\n"
5002             "\n"
5003             "  while (rayQueryProceedEXT(rayQuery))\n"
5004             "  {\n"
5005             "      intersection_found = true;\n"
5006             "\n"
5007             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
5008             "  }\n"
5009             "\n"
5010             "  if (intersection_found)\n"
5011             "  {\n"
5012             "    result_fp32 = rayQueryGetIntersectionBarycentricsEXT(rayQuery, true);\n"
5013             "  }\n"
5014             "\n"
5015             "  imageStore(result, ivec3(pos.xy, 0), ivec4(result_fp32.x * " +
5016             de::toString(FIXED_POINT_DIVISOR) +
5017             ", 0, 0, 0));\n"
5018             "  imageStore(result, ivec3(pos.xy, 1), ivec4(result_fp32.y * " +
5019             de::toString(FIXED_POINT_DIVISOR) +
5020             ", 0, 0, 0));\n"
5021             "  imageStore(result, ivec3(pos.xy, 2), ivec4((1.0 - result_fp32.x - result_fp32.y) * " +
5022             de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0));\n";
5023 
5024         return result;
5025     }
5026     else
5027     {
5028         TCU_THROW(InternalError, "Unknown geometry type");
5029     }
5030 }
5031 
5032 /// <summary>
5033 class TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset : public TestConfiguration
5034 {
5035 public:
TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset(Context & context)5036     TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset(Context &context)
5037         : TestConfiguration(context)
5038     {
5039     }
5040     static const std::string getShaderBodyTextCandidate(const TestParams &testParams);
5041     static const std::string getShaderBodyTextCommitted(const TestParams &testParams);
5042 
5043     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
5044                                                                          VkCommandBuffer cmdBuffer) override;
5045 };
5046 
5047 const VkAccelerationStructureKHR *TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset::
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)5048     initAccelerationStructures(TestParams &testParams, VkCommandBuffer cmdBuffer)
5049 {
5050     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
5051     const VkDevice device               = m_testEnvironment->device;
5052     Allocator &allocator                = *m_testEnvironment->allocator;
5053     const uint32_t width                = testParams.width;
5054     const uint32_t height               = testParams.height;
5055     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
5056     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
5057     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
5058     uint32_t squareNdx                  = 0;
5059     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
5060         makeTopLevelAccelerationStructure();
5061 
5062     DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
5063 
5064     m_topAccelerationStructure =
5065         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
5066 
5067     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
5068 
5069     m_expected.resize(width * height);
5070 
5071     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
5072     {
5073         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
5074         {
5075             for (uint32_t groupNdx = 0; groupNdx < squaresGroupCount; ++groupNdx, ++squareNdx)
5076             {
5077                 de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
5078                     makeBottomLevelAccelerationStructure();
5079                 std::vector<tcu::Vec3> geometryData;
5080 
5081                 const auto squareX = (squareNdx % width);
5082                 const auto squareY = (squareNdx / width);
5083 
5084                 const float x0 = float(squareX + 0) / float(width);
5085                 const float y0 = float(squareY + 0) / float(height);
5086                 const float x1 = float(squareX + 1) / float(width);
5087                 const float y1 = float(squareY + 1) / float(height);
5088 
5089                 if ((squareNdx % 2) == 0)
5090                 {
5091                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
5092                     geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
5093                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
5094 
5095                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
5096                     geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
5097                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
5098                 }
5099                 else
5100                 {
5101                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
5102                     geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
5103                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
5104 
5105                     geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
5106                     geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
5107                     geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
5108                 }
5109 
5110                 m_expected.at(squareNdx) = ((1 << 24) - 1) / static_cast<uint32_t>(m_expected.size()) * squareNdx;
5111 
5112                 rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, true /* triangles */);
5113 
5114                 rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
5115                 m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(
5116                     rayQueryBottomLevelAccelerationStructure.release()));
5117 
5118                 m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4,
5119                                                         instanceNdx + 1, 255U, m_expected.at(squareNdx));
5120             }
5121         }
5122     }
5123 
5124     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
5125 
5126     return m_topAccelerationStructure.get()->getPtr();
5127 }
5128 
getShaderBodyTextCandidate(const TestParams & testParams)5129 const std::string TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset::getShaderBodyTextCandidate(
5130     const TestParams &testParams)
5131 {
5132     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
5133     {
5134         const std::string result =
5135             "  uint        rayFlags = 0;\n"
5136             "  uint        cullMask = 0xFF;\n"
5137             "  float       tmin     = 0.0001;\n"
5138             "  float       tmax     = 9.0;\n"
5139             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
5140             "float(size.y),  0.2);\n"
5141             "  vec3        direct   = vec3(0,   0,    "
5142             "  -1.0);\n"
5143             "  rayQueryEXT rayQuery;\n"
5144             "\n"
5145             "  int result_i32 = 2;\n"
5146             "\n"
5147             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
5148             "tmin, direct, tmax);\n"
5149             "\n"
5150             "  while (rayQueryProceedEXT(rayQuery))\n"
5151             "  {\n"
5152             "      result_i32 = int(rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT(rayQuery, false) "
5153             ");\n"
5154             "\n"
5155             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
5156             "  }\n"
5157             "\n"
5158             "  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
5159 
5160         return result;
5161     }
5162     else
5163     {
5164         TCU_THROW(InternalError, "Unknown geometry type");
5165     }
5166 }
5167 
getShaderBodyTextCommitted(const TestParams & testParams)5168 const std::string TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset::getShaderBodyTextCommitted(
5169     const TestParams &testParams)
5170 {
5171     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
5172     {
5173         const std::string result =
5174             "  uint        rayFlags = 0;\n"
5175             "  uint        cullMask = 0xFF;\n"
5176             "  float       tmin     = 0.0001;\n"
5177             "  float       tmax     = 9.0;\n"
5178             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
5179             "float(size.y),  0.2);\n"
5180             "  vec3        direct   = vec3(0,   0,    "
5181             "  -1.0);\n"
5182             "  rayQueryEXT rayQuery;\n"
5183             "\n"
5184             "  bool intersection_found = false;\n"
5185             "  int  result_i32         = 0;\n"
5186             "\n"
5187             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
5188             "tmin, direct, tmax);\n"
5189             "\n"
5190             "  while (rayQueryProceedEXT(rayQuery))\n"
5191             "  {\n"
5192             "      intersection_found = true;\n"
5193             "\n"
5194             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
5195             "  }\n"
5196             "\n"
5197             "  result_i32 = (intersection_found) ? "
5198             "int(rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT(rayQuery, true) )\n"
5199             "                                     : 2;\n"
5200             "\n"
5201             "  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
5202 
5203         return result;
5204     }
5205     else
5206     {
5207         TCU_THROW(InternalError, "Unknown geometry type");
5208     }
5209 }
5210 /// </summary>
5211 
5212 class TestConfigurationRayQueryTerminate : public TestConfiguration
5213 {
5214 public:
TestConfigurationRayQueryTerminate(Context & context)5215     TestConfigurationRayQueryTerminate(Context &context) : TestConfiguration(context)
5216     {
5217     }
5218     static const std::string getShaderBodyText(const TestParams &testParams);
5219 
5220     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
5221                                                                          VkCommandBuffer cmdBuffer) override;
5222 
5223 private:
5224     static const uint32_t N_RAY_QUERIES_TO_USE;
5225 };
5226 
5227 const uint32_t TestConfigurationRayQueryTerminate::N_RAY_QUERIES_TO_USE = 8;
5228 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)5229 const VkAccelerationStructureKHR *TestConfigurationRayQueryTerminate::initAccelerationStructures(
5230     TestParams &testParams, VkCommandBuffer cmdBuffer)
5231 {
5232     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
5233     const VkDevice device               = m_testEnvironment->device;
5234     Allocator &allocator                = *m_testEnvironment->allocator;
5235     const uint32_t width                = testParams.width;
5236     const uint32_t height               = testParams.height;
5237     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
5238     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
5239     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
5240     uint32_t squareNdx                  = 0;
5241     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
5242         makeTopLevelAccelerationStructure();
5243 
5244     DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
5245 
5246     m_topAccelerationStructure =
5247         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
5248 
5249     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
5250 
5251     m_expected.resize(width * height);
5252 
5253     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
5254     {
5255         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
5256         {
5257             for (uint32_t groupNdx = 0; groupNdx < squaresGroupCount; ++groupNdx, ++squareNdx)
5258             {
5259                 std::vector<tcu::Vec3> geometryData;
5260                 de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
5261                     makeBottomLevelAccelerationStructure();
5262 
5263                 for (int32_t z = -2; z <= 0; ++z)
5264                 {
5265                     const auto squareX = (squareNdx % width);
5266                     const auto squareY = (squareNdx / width);
5267 
5268                     const float x0 = float(squareX + 0) / float(width);
5269                     const float y0 = float(squareY + 0) / float(height);
5270                     const float x1 = float(squareX + 1) / float(width);
5271                     const float y1 = float(squareY + 1) / float(height);
5272 
5273                     if (testParams.geomType == GeomType::GEOM_TYPE_TRIANGLES)
5274                     {
5275                         if ((squareNdx % 2) == 0)
5276                         {
5277                             geometryData.push_back(tcu::Vec3(x0, y0, static_cast<float>(z)));
5278                             geometryData.push_back(tcu::Vec3(x0, y1, static_cast<float>(z)));
5279                             geometryData.push_back(tcu::Vec3(x1, y1, static_cast<float>(z)));
5280 
5281                             geometryData.push_back(tcu::Vec3(x1, y1, static_cast<float>(z)));
5282                             geometryData.push_back(tcu::Vec3(x1, y0, static_cast<float>(z)));
5283                             geometryData.push_back(tcu::Vec3(x0, y0, static_cast<float>(z)));
5284                         }
5285                         else
5286                         {
5287                             geometryData.push_back(tcu::Vec3(x1, y1, static_cast<float>(z)));
5288                             geometryData.push_back(tcu::Vec3(x0, y1, static_cast<float>(z)));
5289                             geometryData.push_back(tcu::Vec3(x0, y0, static_cast<float>(z)));
5290 
5291                             geometryData.push_back(tcu::Vec3(x0, y0, static_cast<float>(z)));
5292                             geometryData.push_back(tcu::Vec3(x1, y0, static_cast<float>(z)));
5293                             geometryData.push_back(tcu::Vec3(x1, y1, static_cast<float>(z)));
5294                         }
5295                     }
5296                     else
5297                     {
5298                         geometryData.push_back(tcu::Vec3(x0, y0, static_cast<float>(z)));
5299                         geometryData.push_back(tcu::Vec3(x1, y1, static_cast<float>(z)));
5300                     }
5301                 }
5302 
5303                 m_expected.at(squareNdx) = (1 << N_RAY_QUERIES_TO_USE) - 1;
5304 
5305                 rayQueryBottomLevelAccelerationStructure->addGeometry(
5306                     geometryData, (testParams.geomType == GeomType::GEOM_TYPE_TRIANGLES),
5307                     VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR);
5308 
5309                 rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
5310                 m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(
5311                     rayQueryBottomLevelAccelerationStructure.release()));
5312 
5313                 m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4,
5314                                                         instanceNdx + 1, 255U, m_expected.at(squareNdx));
5315             }
5316         }
5317     }
5318 
5319     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
5320 
5321     return m_topAccelerationStructure.get()->getPtr();
5322 }
5323 
getShaderBodyText(const TestParams & testParams)5324 const std::string TestConfigurationRayQueryTerminate::getShaderBodyText(const TestParams &testParams)
5325 {
5326     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
5327     {
5328         std::string result =
5329             "  const int nQueries      = " + de::toString(N_RAY_QUERIES_TO_USE) +
5330             ";\n"
5331             "  const int nPassingQuery = nQueries / 2;\n"
5332             "\n"
5333             "  const uint  rayFlags = 0;\n"
5334             "  const uint  cullMask = 0xFF;\n"
5335             "  const float tmin     = 0.0001;\n"
5336             "  const float tmax     = 9.0;\n"
5337             "\n"
5338             "  rayQueryEXT rayQueries                     [nQueries];\n"
5339             "  int         nSuccessfulRayQueryProceedCalls[nQueries];\n"
5340             "\n"
5341             "  int result_i32 = 0;\n"
5342             "\n"
5343             "  for (int nQuery = nQueries - 1; nQuery >= 0; --nQuery)\n"
5344             "  {\n"
5345             "      vec3 origin = vec3((float(pos.x) + 0.4f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y),  "
5346             "0.2);\n"
5347             "      vec3 direct = vec3(0,                                     0,                                     "
5348             "-1.0);\n"
5349             "\n"
5350             "      rayQueryInitializeEXT(rayQueries[nQuery], rayQueryTopLevelAccelerationStructure, rayFlags, "
5351             "cullMask, origin, tmin, direct, tmax);\n"
5352             "\n"
5353             "      nSuccessfulRayQueryProceedCalls[nQuery] = 0;\n"
5354             "  }\n"
5355             "\n"
5356             "  while (true)\n"
5357             "  {\n"
5358             "    int nQueriesSuccessful = 0;\n"
5359             "\n"
5360             "    for (int nQuery = 0; nQuery < nQueries; ++nQuery)\n"
5361             "    {\n"
5362             "      if (rayQueryProceedEXT(rayQueries[nQuery]) )\n"
5363             "      {\n"
5364             "        nSuccessfulRayQueryProceedCalls[nQuery] ++;\n"
5365             "        nQueriesSuccessful                      ++;\n"
5366             "\n"
5367             "        if (nQuery != nPassingQuery)\n"
5368             "        {\n"
5369             "            rayQueryTerminateEXT(rayQueries[nQuery]);\n"
5370             "        }\n"
5371             "      }\n"
5372             "    }\n"
5373             "\n"
5374             "    if (nQueriesSuccessful == 0)\n"
5375             "    {\n"
5376             "      break;\n"
5377             "    }\n"
5378             "  }\n"
5379             "\n"
5380             "  for (int nQuery = 0; nQuery < nQueries; ++nQuery)\n"
5381             "  {\n"
5382             "    if (nPassingQuery != nQuery)\n"
5383             "    {\n"
5384             "       result_i32 |= (nSuccessfulRayQueryProceedCalls[nQuery] == 1) ? (1 << nQuery) : 0;\n"
5385             "    }\n"
5386             "    else\n"
5387             "    {\n"
5388             "       result_i32 |= (nSuccessfulRayQueryProceedCalls[nQuery] == 3) ? (1 << nQuery) : 0;\n"
5389             "    }\n"
5390             "  }\n"
5391             "\n"
5392             "  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
5393 
5394         return result;
5395     }
5396     else
5397     {
5398         TCU_THROW(InternalError, "Unknown geometry type");
5399     }
5400 }
5401 
5402 class TestConfigurationGetIntersectionType : public TestConfiguration
5403 {
5404 public:
TestConfigurationGetIntersectionType(Context & context)5405     TestConfigurationGetIntersectionType(Context &context) : TestConfiguration(context)
5406     {
5407     }
5408     static const std::string getShaderBodyTextCandidate(const TestParams &testParams);
5409     static const std::string getShaderBodyTextCommitted(const TestParams &testParams);
5410 
5411     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
5412                                                                          VkCommandBuffer cmdBuffer) override;
5413 };
5414 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)5415 const VkAccelerationStructureKHR *TestConfigurationGetIntersectionType::initAccelerationStructures(
5416     TestParams &testParams, VkCommandBuffer cmdBuffer)
5417 {
5418     const DeviceInterface &vkd          = *m_testEnvironment->vkd;
5419     const VkDevice device               = m_testEnvironment->device;
5420     Allocator &allocator                = *m_testEnvironment->allocator;
5421     const uint32_t width                = testParams.width;
5422     const uint32_t height               = testParams.height;
5423     const uint32_t instancesGroupCount  = testParams.instancesGroupCount;
5424     const uint32_t geometriesGroupCount = testParams.geometriesGroupCount;
5425     const uint32_t squaresGroupCount    = testParams.squaresGroupCount;
5426     uint32_t squareNdx                  = 0;
5427     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
5428         makeTopLevelAccelerationStructure();
5429 
5430     DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
5431 
5432     m_topAccelerationStructure =
5433         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
5434 
5435     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
5436 
5437     m_expected.resize(width * height);
5438 
5439     for (uint32_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
5440     {
5441         for (uint32_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
5442         {
5443             for (uint32_t groupNdx = 0; groupNdx < squaresGroupCount; ++groupNdx, ++squareNdx)
5444             {
5445                 de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
5446                     makeBottomLevelAccelerationStructure();
5447                 std::vector<tcu::Vec3> geometryData;
5448 
5449                 const auto squareX = (squareNdx % width);
5450                 const auto squareY = (squareNdx / width);
5451 
5452                 const float x0 = float(squareX + 0) / float(width);
5453                 const float y0 = float(squareY + 0) / float(height);
5454                 const float x1 = float(squareX + 1) / float(width);
5455                 const float y1 = float(squareY + 1) / float(height);
5456 
5457                 if ((squareNdx % 2) == 0)
5458                 {
5459                     if (testParams.geomType == GEOM_TYPE_TRIANGLES)
5460                     {
5461                         geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
5462                         geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
5463                         geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
5464 
5465                         geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
5466                         geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
5467                         geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
5468                     }
5469                     else
5470                     {
5471                         geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
5472                         geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
5473                     }
5474 
5475                     m_expected.at(squareNdx) = (testParams.testType == TEST_TYPE_GET_INTERSECTION_TYPE_CANDIDATE) ?
5476                                                    (testParams.geomType == GEOM_TYPE_TRIANGLES) ?
5477                                                    0 /* gl_RayQueryCandidateIntersectionTriangleEXT  */
5478                                                    :
5479                                                    1 /* gl_RayQueryCandidateIntersectionAABBEXT      */
5480                                                :
5481                                                (testParams.geomType == GEOM_TYPE_TRIANGLES) ?
5482                                                    1 /* gl_RayQueryCommittedIntersectionTriangleEXT  */
5483                                                    :
5484                                                    2; /* gl_RayQueryCommittedIntersectionGeneratedEXT */
5485 
5486                     rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData,
5487                                                                           (testParams.geomType == GEOM_TYPE_TRIANGLES));
5488 
5489                     rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
5490                     m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(
5491                         rayQueryBottomLevelAccelerationStructure.release()));
5492 
5493                     m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4);
5494                 }
5495                 else
5496                 {
5497                     m_expected.at(squareNdx) = (testParams.testType == TEST_TYPE_GET_INTERSECTION_TYPE_CANDIDATE) ?
5498                                                    123 :
5499                                                    0; /* gl_RayQueryCommittedIntersectionNoneEXT */
5500                 }
5501             }
5502         }
5503     }
5504 
5505     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
5506 
5507     return m_topAccelerationStructure.get()->getPtr();
5508 }
5509 
getShaderBodyTextCandidate(const TestParams & testParams)5510 const std::string TestConfigurationGetIntersectionType::getShaderBodyTextCandidate(const TestParams &testParams)
5511 {
5512     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
5513     {
5514         std::string result = "  uint        rayFlags = 0;\n"
5515                              "  uint        cullMask = 0xFF;\n"
5516                              "  float       tmin     = 0.0001;\n"
5517                              "  float       tmax     = 9.0;\n"
5518                              "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + "
5519                              "0.5f) / float(size.y),  0.2);\n"
5520                              "  vec3        direct   = vec3(0,   0, "
5521                              "                     -1.0);\n"
5522                              "  rayQueryEXT rayQuery;\n"
5523                              "\n"
5524                              "  int result_i32 = 123;\n"
5525                              "\n"
5526                              "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, "
5527                              "cullMask, origin, tmin, direct, tmax);\n"
5528                              "\n"
5529                              "  while (rayQueryProceedEXT(rayQuery))\n"
5530                              "  {\n"
5531                              "      result_i32 = int(rayQueryGetIntersectionTypeEXT(rayQuery, false) );\n"
5532                              "\n";
5533 
5534         if (testParams.geomType == GEOM_TYPE_AABBS)
5535         {
5536             result += "      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n";
5537         }
5538         else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
5539         {
5540             result += "      rayQueryConfirmIntersectionEXT(rayQuery);\n";
5541         }
5542 
5543         result += "  }\n"
5544                   "\n"
5545                   "  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
5546 
5547         return result;
5548     }
5549     else
5550     {
5551         TCU_THROW(InternalError, "Unknown geometry type");
5552     }
5553 }
5554 
getShaderBodyTextCommitted(const TestParams & testParams)5555 const std::string TestConfigurationGetIntersectionType::getShaderBodyTextCommitted(const TestParams &testParams)
5556 {
5557     if (testParams.geomType == GEOM_TYPE_AABBS || testParams.geomType == GEOM_TYPE_TRIANGLES)
5558     {
5559         std::string result = "  uint        rayFlags = 0;\n"
5560                              "  uint        cullMask = 0xFF;\n"
5561                              "  float       tmin     = 0.0001;\n"
5562                              "  float       tmax     = 9.0;\n"
5563                              "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + "
5564                              "0.5f) / float(size.y),  0.2);\n"
5565                              "  vec3        direct   = vec3(0,   0, "
5566                              "                     -1.0);\n"
5567                              "  rayQueryEXT rayQuery;\n"
5568                              "\n"
5569                              "  uint result_i32 = 123u;\n"
5570                              "\n"
5571                              "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, "
5572                              "cullMask, origin, tmin, direct, tmax);\n"
5573                              "\n"
5574                              "  while (rayQueryProceedEXT(rayQuery))\n"
5575                              "  {\n";
5576 
5577         if (testParams.geomType == GEOM_TYPE_AABBS)
5578         {
5579             result += "      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n";
5580         }
5581         else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
5582         {
5583             result += "      rayQueryConfirmIntersectionEXT(rayQuery);\n";
5584         }
5585 
5586         result += "  }\n"
5587                   "\n"
5588                   "  result_i32 = rayQueryGetIntersectionTypeEXT(rayQuery, true);\n"
5589                   "\n"
5590                   "  imageStore(result, pos, ivec4(int(result_i32), 0, 0, 0));\n";
5591 
5592         return result;
5593     }
5594     else
5595     {
5596         TCU_THROW(InternalError, "Unknown geometry type");
5597     }
5598 }
5599 
5600 class TestConfigurationUsingWrapperFunction : public TestConfiguration
5601 {
5602 public:
TestConfigurationUsingWrapperFunction(Context & context)5603     TestConfigurationUsingWrapperFunction(Context &context) : TestConfiguration(context)
5604     {
5605     }
5606     virtual const VkAccelerationStructureKHR *initAccelerationStructures(TestParams &testParams,
5607                                                                          VkCommandBuffer cmdBuffer) override;
5608 
5609     static const std::string getShaderBodyText(const TestParams &testParams);
5610 };
5611 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)5612 const VkAccelerationStructureKHR *TestConfigurationUsingWrapperFunction::initAccelerationStructures(
5613     TestParams &testParams, VkCommandBuffer cmdBuffer)
5614 {
5615     const DeviceInterface &vkd         = *m_testEnvironment->vkd;
5616     const VkDevice device              = m_testEnvironment->device;
5617     Allocator &allocator               = *m_testEnvironment->allocator;
5618     const uint32_t width               = testParams.width;
5619     const uint32_t height              = testParams.height;
5620     const uint32_t instancesGroupCount = testParams.instancesGroupCount;
5621     const uint32_t squaresGroupCount   = testParams.squaresGroupCount;
5622     const bool usesTriangles           = (testParams.geomType == GEOM_TYPE_TRIANGLES);
5623 
5624     DE_ASSERT(instancesGroupCount == 1);
5625     DE_ASSERT(squaresGroupCount == width * height);
5626 
5627     m_topAccelerationStructure =
5628         de::SharedPtr<TopLevelAccelerationStructure>(makeTopLevelAccelerationStructure().release());
5629     m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
5630 
5631     m_expected = std::vector<int32_t>(width * height, 1);
5632 
5633     de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
5634         makeBottomLevelAccelerationStructure();
5635 
5636     for (uint32_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
5637     {
5638         std::vector<tcu::Vec3> geometryData;
5639 
5640         const auto squareX = (squareNdx % width);
5641         const auto squareY = (squareNdx / width);
5642 
5643         const float x0 = float(squareX + 0) / float(width);
5644         const float y0 = float(squareY + 0) / float(height);
5645         const float x1 = float(squareX + 1) / float(width);
5646         const float y1 = float(squareY + 1) / float(height);
5647 
5648         if (usesTriangles)
5649         {
5650             geometryData.emplace_back(x0, y0, 0.0f);
5651             geometryData.emplace_back(x0, y1, 0.0f);
5652             geometryData.emplace_back(x1, y1, 0.0f);
5653 
5654             geometryData.emplace_back(x1, y1, 0.0f);
5655             geometryData.emplace_back(x1, y0, 0.0f);
5656             geometryData.emplace_back(x0, y0, 0.0f);
5657         }
5658         else
5659         {
5660             geometryData.emplace_back(x0, y0, 0.0f);
5661             geometryData.emplace_back(x1, y1, 0.0f);
5662         }
5663 
5664         rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, usesTriangles);
5665     }
5666 
5667     rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
5668     m_bottomAccelerationStructures.push_back(
5669         de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
5670     m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4, 1);
5671     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
5672 
5673     return m_topAccelerationStructure.get()->getPtr();
5674 }
5675 
getShaderBodyText(const TestParams & testParams)5676 const std::string TestConfigurationUsingWrapperFunction::getShaderBodyText(const TestParams &testParams)
5677 {
5678     DE_UNREF(testParams);
5679     DE_ASSERT(testParams.isSPIRV);
5680 
5681     // glslang is compiling rayQueryEXT function parameters to OpTypePointer Function to OpTypeRayQueryKHR
5682     // To test bare rayQueryEXT object passed as function parameter we need to use SPIR-V assembly.
5683     // In it, rayQueryWrapper has been modified to take a bare rayQueryEXT as the third argument, instead of a pointer.
5684     // The SPIR-V assembly shader below is based on the following GLSL code:
5685 
5686     // int rayQueryWrapper(rayQueryEXT rq1, int value, rayQueryEXT rq2)
5687     // {
5688     //    int result = value;
5689     //    while (rayQueryProceedEXT(rq1))
5690     //    {
5691     //       result = 1;
5692     //       rayQueryConfirmIntersectionEXT(rq2);
5693     //    }
5694     //    return result;
5695     // }
5696     // void main()
5697     // {
5698     //    ivec3       pos = ivec3(gl_WorkGroupID);
5699     //    ivec3       size = ivec3(gl_NumWorkGroups);
5700     //    uint        rayFlags = 0;
5701     //    uint        cullMask = 0xFF;
5702     //    float       tmin = 0.0001;
5703     //    float       tmax = 9.0;
5704     //    vec3        origin = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.2);
5705     //    vec3        direct = vec3(0.0, 0.0, -1.0);
5706     //    rayQueryEXT rayQuery;
5707     //    rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);
5708     //    imageStore(result, pos, ivec4(rayQueryWrapper(rayQuery, 0, rayQuery), 0, 0, 0));
5709     // }
5710 
5711     return "OpCapability Shader\n"
5712            "OpCapability RayQueryKHR\n"
5713            "OpExtension \"SPV_KHR_ray_query\"\n"
5714            "%1 = OpExtInstImport \"GLSL.std.450\"\n"
5715            "OpMemoryModel Logical GLSL450\n"
5716            "OpEntryPoint GLCompute %4 \"main\" %35 %39 %83 %93\n"
5717            "OpExecutionMode %4 LocalSize 1 1 1\n"
5718            "OpDecorate %35 BuiltIn WorkgroupId\n"
5719            "OpDecorate %39 BuiltIn NumWorkgroups\n"
5720            "OpDecorate %83 DescriptorSet 0\n"
5721            "OpDecorate %83 Binding 1\n"
5722            "OpDecorate %93 DescriptorSet 0\n"
5723            "OpDecorate %93 Binding 0\n"
5724 
5725            // types and constants
5726            "%2 = OpTypeVoid\n"
5727            "%3 = OpTypeFunction %2\n"
5728            "%bare_query_type = OpTypeRayQueryKHR\n"
5729            "%pointer_to_query_type = OpTypePointer Function %bare_query_type\n"
5730            "%8 = OpTypeInt 32 1\n"
5731            "%9 = OpTypePointer Function %8\n"
5732 
5733            // this function was modified to take also bare rayQueryEXT type
5734            "%ray_query_wrapper_fun = OpTypeFunction %8 %pointer_to_query_type %9 %bare_query_type\n"
5735 
5736            "%23 = OpTypeBool\n"
5737            "%25 = OpConstant %8 1\n"
5738            "%29 = OpTypeVector %8 3\n"
5739            "%30 = OpTypePointer Function %29\n"
5740            "%32 = OpTypeInt 32 0\n"
5741            "%33 = OpTypeVector %32 3\n"
5742            "%34 = OpTypePointer Input %33\n"
5743            "%35 = OpVariable %34 Input\n"
5744            "%39 = OpVariable %34 Input\n"
5745            "%42 = OpTypePointer Function %32\n"
5746            "%44 = OpConstant %32 0\n"
5747            "%46 = OpConstant %32 255\n"
5748            "%47 = OpTypeFloat 32\n"
5749            "%48 = OpTypePointer Function %47\n"
5750            "%50 = OpConstant %47 9.99999975e-05\n"
5751            "%52 = OpConstant %47 9\n"
5752            "%53 = OpTypeVector %47 3\n"
5753            "%54 = OpTypePointer Function %53\n"
5754            "%59 = OpConstant %47 0.5\n"
5755            "%65 = OpConstant %32 1\n"
5756            "%74 = OpConstant %47 0.200000003\n"
5757            "%77 = OpConstant %47 0\n"
5758            "%78 = OpConstant %47 -1\n"
5759            "%79 = OpConstantComposite %53 %77 %77 %78\n"
5760            "%81 = OpTypeAccelerationStructureKHR\n"
5761            "%82 = OpTypePointer UniformConstant %81\n"
5762            "%83 = OpVariable %82 UniformConstant\n"
5763            "%91 = OpTypeImage %8 3D 0 0 0 2 R32i\n"
5764            "%92 = OpTypePointer UniformConstant %91\n"
5765            "%93 = OpVariable %92 UniformConstant\n"
5766            "%96 = OpConstant %8 0\n"
5767            "%99 = OpTypeVector %8 4\n"
5768 
5769            // void main()
5770            "%4 = OpFunction %2 None %3\n"
5771            "%5 = OpLabel\n"
5772            "%31 = OpVariable %30 Function\n"
5773            "%38 = OpVariable %30 Function\n"
5774            "%43 = OpVariable %42 Function\n"
5775            "%45 = OpVariable %42 Function\n"
5776            "%49 = OpVariable %48 Function\n"
5777            "%51 = OpVariable %48 Function\n"
5778            "%55 = OpVariable %54 Function\n"
5779            "%76 = OpVariable %54 Function\n"
5780            "%var_ray_query_ptr = OpVariable %pointer_to_query_type Function\n"
5781            "%97 = OpVariable %9 Function\n"
5782            "%36 = OpLoad %33 %35\n"
5783            "%37 = OpBitcast %29 %36\n"
5784            "OpStore %31 %37\n"
5785            "%40 = OpLoad %33 %39\n"
5786            "%41 = OpBitcast %29 %40\n"
5787            "OpStore %38 %41\n"
5788            "OpStore %43 %44\n"
5789            "OpStore %45 %46\n"
5790            "OpStore %49 %50\n"
5791            "OpStore %51 %52\n"
5792            "%56 = OpAccessChain %9 %31 %44\n"
5793            "%57 = OpLoad %8 %56\n"
5794            "%58 = OpConvertSToF %47 %57\n"
5795            "%60 = OpFAdd %47 %58 %59\n"
5796            "%61 = OpAccessChain %9 %38 %44\n"
5797            "%62 = OpLoad %8 %61\n"
5798            "%63 = OpConvertSToF %47 %62\n"
5799            "%64 = OpFDiv %47 %60 %63\n"
5800            "%66 = OpAccessChain %9 %31 %65\n"
5801            "%67 = OpLoad %8 %66\n"
5802            "%68 = OpConvertSToF %47 %67\n"
5803            "%69 = OpFAdd %47 %68 %59\n"
5804            "%70 = OpAccessChain %9 %38 %65\n"
5805            "%71 = OpLoad %8 %70\n"
5806            "%72 = OpConvertSToF %47 %71\n"
5807            "%73 = OpFDiv %47 %69 %72\n"
5808            "%75 = OpCompositeConstruct %53 %64 %73 %74\n"
5809            "OpStore %55 %75\n"
5810            "OpStore %76 %79\n"
5811            "%84 = OpLoad %81 %83\n"
5812            "%85 = OpLoad %32 %43\n"
5813            "%86 = OpLoad %32 %45\n"
5814            "%87 = OpLoad %53 %55\n"
5815            "%88 = OpLoad %47 %49\n"
5816            "%89 = OpLoad %53 %76\n"
5817            "%90 = OpLoad %47 %51\n"
5818            "OpRayQueryInitializeKHR %var_ray_query_ptr %84 %85 %86 %87 %88 %89 %90\n"
5819            "%94 = OpLoad %91 %93\n"
5820            "%95 = OpLoad %29 %31\n"
5821            "OpStore %97 %96\n"
5822            "%var_ray_query_bare = OpLoad %bare_query_type %var_ray_query_ptr\n"
5823            "%98 = OpFunctionCall %8 %14 %var_ray_query_ptr %97 %var_ray_query_bare\n"
5824            "%100 = OpCompositeConstruct %99 %98 %96 %96 %96\n"
5825            "OpImageWrite %94 %95 %100 SignExtend\n"
5826            "OpReturn\n"
5827            "OpFunctionEnd\n"
5828 
5829            // int rayQueryWrapper(rayQueryEXT rq1, int value, rayQueryEXT rq2)
5830            // where in SPIRV rq1 is pointer and rq2 is bare type
5831            "%14 = OpFunction %8 None %ray_query_wrapper_fun\n"
5832            "%11 = OpFunctionParameter %pointer_to_query_type\n"
5833            "%12 = OpFunctionParameter %9\n"
5834            "%13 = OpFunctionParameter %bare_query_type\n"
5835            "%15 = OpLabel\n"
5836            "%16 = OpVariable %9 Function\n"
5837            "%local_var_ray_query_ptr = OpVariable %pointer_to_query_type Function\n"
5838            "%17 = OpLoad %8 %12\n"
5839            "OpStore %16 %17\n"
5840            "OpBranch %18\n"
5841            "%18 = OpLabel\n"
5842            "OpLoopMerge %20 %21 None\n"
5843            "OpBranch %22\n"
5844            "%22 = OpLabel\n"
5845            "%24 = OpRayQueryProceedKHR %23 %11\n"
5846            "OpBranchConditional %24 %19 %20\n"
5847            "%19 = OpLabel\n"
5848            "OpStore %16 %25\n"
5849            "OpStore %local_var_ray_query_ptr %13\n"
5850            "OpRayQueryConfirmIntersectionKHR %local_var_ray_query_ptr\n"
5851            "OpBranch %21\n"
5852            "%21 = OpLabel\n"
5853            "OpBranch %18\n"
5854            "%20 = OpLabel\n"
5855            "%26 = OpLoad %8 %16\n"
5856            "OpReturnValue %26\n"
5857            "OpFunctionEnd\n";
5858 }
5859 
5860 class RayQueryBuiltinTestInstance : public TestInstance
5861 {
5862 public:
5863     RayQueryBuiltinTestInstance(Context &context, const TestParams &data);
5864     virtual ~RayQueryBuiltinTestInstance(void);
5865     tcu::TestStatus iterate(void);
5866 
5867 private:
5868     TestParams m_data;
5869     de::MovePtr<TestConfiguration> m_testConfig;
5870     de::MovePtr<PipelineConfiguration> m_pipelineConfig;
5871 };
5872 
RayQueryBuiltinTestInstance(Context & context,const TestParams & data)5873 RayQueryBuiltinTestInstance::RayQueryBuiltinTestInstance(Context &context, const TestParams &data)
5874     : vkt::TestInstance(context)
5875     , m_data(data)
5876 {
5877     switch (m_data.testType)
5878     {
5879     case TEST_TYPE_FLOW:
5880         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationFlow(context));
5881         break;
5882     case TEST_TYPE_PRIMITIVE_ID:
5883         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationPrimitiveId(context));
5884         break;
5885     case TEST_TYPE_INSTANCE_ID:
5886         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationInstanceId(context));
5887         break;
5888     case TEST_TYPE_INSTANCE_CUSTOM_INDEX:
5889         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationInstanceCustomIndex(context));
5890         break;
5891     case TEST_TYPE_INTERSECTION_T_KHR:
5892         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationIntersectionT(context));
5893         break;
5894     case TEST_TYPE_OBJECT_RAY_ORIGIN_KHR:
5895         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationObjectRayOrigin(context));
5896         break;
5897     case TEST_TYPE_OBJECT_RAY_DIRECTION_KHR:
5898         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationObjectRayDirection(context));
5899         break;
5900     case TEST_TYPE_OBJECT_TO_WORLD_KHR:
5901         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationObjectToWorld(context));
5902         break;
5903     case TEST_TYPE_WORLD_TO_OBJECT_KHR:
5904         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationWorldToObject(context));
5905         break;
5906     case TEST_TYPE_NULL_ACCELERATION_STRUCTURE:
5907         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationNullASStruct(context));
5908         break;
5909     case TEST_TYPE_USING_WRAPPER_FUNCTION:
5910         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationUsingWrapperFunction(context));
5911         break;
5912     case TEST_TYPE_GET_RAY_TMIN:
5913         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetRayTMin(context));
5914         break;
5915     case TEST_TYPE_GET_WORLD_RAY_ORIGIN:
5916         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetWorldRayOrigin(context));
5917         break;
5918     case TEST_TYPE_GET_WORLD_RAY_DIRECTION:
5919         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetWorldRayDirection(context));
5920         break;
5921     case TEST_TYPE_GET_INTERSECTION_CANDIDATE_AABB_OPAQUE:
5922         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionCandidateAABBOpaque(context));
5923         break;
5924     case TEST_TYPE_GET_INTERSECTION_FRONT_FACE_CANDIDATE:
5925         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionFrontFace(context));
5926         break;
5927     case TEST_TYPE_GET_INTERSECTION_FRONT_FACE_COMMITTED:
5928         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionFrontFace(context));
5929         break;
5930     case TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_CANDIDATE:
5931         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionGeometryIndex(context));
5932         break;
5933     case TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_COMMITTED:
5934         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionGeometryIndex(context));
5935         break;
5936     case TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_CANDIDATE:
5937         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionBarycentrics(context));
5938         break;
5939     case TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_COMMITTED:
5940         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionBarycentrics(context));
5941         break;
5942     case TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_CANDIDATE:
5943         m_testConfig = de::MovePtr<TestConfiguration>(
5944             new TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset(context));
5945         break;
5946     case TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_COMMITTED:
5947         m_testConfig = de::MovePtr<TestConfiguration>(
5948             new TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset(context));
5949         break;
5950     case TEST_TYPE_RAY_QUERY_TERMINATE:
5951         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationRayQueryTerminate(context));
5952         break;
5953     case TEST_TYPE_GET_INTERSECTION_TYPE_CANDIDATE:
5954         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionType(context));
5955         break;
5956     case TEST_TYPE_GET_INTERSECTION_TYPE_COMMITTED:
5957         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionType(context));
5958         break;
5959 
5960     default:
5961         TCU_THROW(InternalError, "Unknown test type");
5962     }
5963 
5964     switch (m_data.stage)
5965     {
5966     case VK_SHADER_STAGE_VERTEX_BIT:
5967     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
5968     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
5969     case VK_SHADER_STAGE_GEOMETRY_BIT:
5970     case VK_SHADER_STAGE_FRAGMENT_BIT:
5971     {
5972         m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new GraphicsConfiguration());
5973         break;
5974     }
5975 
5976     case VK_SHADER_STAGE_COMPUTE_BIT:
5977     {
5978         m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new ComputeConfiguration());
5979         break;
5980     }
5981 
5982     case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
5983     case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
5984     case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
5985     case VK_SHADER_STAGE_MISS_BIT_KHR:
5986     case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
5987     case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
5988     {
5989         m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new RayTracingConfiguration());
5990         break;
5991     }
5992 
5993     default:
5994         TCU_THROW(InternalError, "Unknown shader stage");
5995     }
5996 }
5997 
~RayQueryBuiltinTestInstance(void)5998 RayQueryBuiltinTestInstance::~RayQueryBuiltinTestInstance(void)
5999 {
6000 }
6001 
iterate(void)6002 tcu::TestStatus RayQueryBuiltinTestInstance::iterate(void)
6003 {
6004     const TestEnvironment &testEnv  = m_testConfig->getTestEnvironment();
6005     const DeviceInterface &vkd      = *testEnv.vkd;
6006     const VkDevice device           = testEnv.device;
6007     const VkQueue queue             = testEnv.queue;
6008     Allocator &allocator            = *testEnv.allocator;
6009     const uint32_t queueFamilyIndex = testEnv.queueFamilyIndex;
6010 
6011     const uint32_t width                    = m_data.width;
6012     const uint32_t height                   = m_data.height;
6013     const uint32_t depth                    = m_data.depth;
6014     const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_data.format, width, height, depth);
6015     const VkImageSubresourceRange imageSubresourceRange =
6016         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
6017     const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(
6018         new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
6019     const Move<VkImageView> imageView =
6020         makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, m_data.format, imageSubresourceRange);
6021 
6022     const uint32_t pixelSize = mapVkFormat(m_data.format).getPixelSize();
6023     const VkBufferCreateInfo resultBufferCreateInfo =
6024         makeBufferCreateInfo(width * height * depth * pixelSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
6025     const VkImageSubresourceLayers resultBufferImageSubresourceLayers =
6026         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
6027     const VkBufferImageCopy resultBufferImageRegion =
6028         makeBufferImageCopy(makeExtent3D(width, height, depth), resultBufferImageSubresourceLayers);
6029     de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(
6030         new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
6031 
6032     const VkDescriptorImageInfo resultImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
6033 
6034     const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
6035     const Move<VkCommandBuffer> cmdBuffer =
6036         allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6037     const VkAccelerationStructureKHR *topAccelerationStructurePtr = DE_NULL;
6038 
6039     m_pipelineConfig->initConfiguration(testEnv, m_data);
6040 
6041     beginCommandBuffer(vkd, *cmdBuffer, 0u);
6042     {
6043         const VkImageMemoryBarrier preImageBarrier =
6044             makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
6045                                    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, **image, imageSubresourceRange);
6046         const VkClearValue clearValue               = makeClearValueColorU32(0u, 0u, 0u, 0u);
6047         const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(
6048             VK_ACCESS_TRANSFER_WRITE_BIT,
6049             VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
6050             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, **image, imageSubresourceRange);
6051         const VkMemoryBarrier postTestMemoryBarrier =
6052             makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
6053         const VkMemoryBarrier postCopyMemoryBarrier =
6054             makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
6055 
6056         cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
6057                                       VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
6058         vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1,
6059                                &imageSubresourceRange);
6060         cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
6061                                       VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
6062 
6063         topAccelerationStructurePtr = m_testConfig->initAccelerationStructures(m_data, *cmdBuffer);
6064 
6065         m_pipelineConfig->fillCommandBuffer(testEnv, m_data, *cmdBuffer, topAccelerationStructurePtr, resultImageInfo);
6066 
6067         cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
6068                                  &postTestMemoryBarrier);
6069 
6070         vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u,
6071                                  &resultBufferImageRegion);
6072 
6073         cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
6074                                  &postCopyMemoryBarrier);
6075     }
6076     endCommandBuffer(vkd, *cmdBuffer);
6077 
6078     submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
6079 
6080     invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(),
6081                                 resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
6082 
6083     if (m_testConfig->verify(resultBuffer.get(), m_data))
6084         return tcu::TestStatus::pass("Pass");
6085     else
6086         return tcu::TestStatus::fail("Fail");
6087 }
6088 
6089 class RayQueryBuiltinTestCase : public TestCase
6090 {
6091 public:
6092     RayQueryBuiltinTestCase(tcu::TestContext &context, const char *name, const TestParams data);
6093     ~RayQueryBuiltinTestCase(void);
6094 
6095     virtual void checkSupport(Context &context) const;
6096     virtual void initPrograms(SourceCollections &programCollection) const;
6097     virtual TestInstance *createInstance(Context &context) const;
6098 
6099 private:
6100     TestParams m_data;
6101 };
6102 
RayQueryBuiltinTestCase(tcu::TestContext & context,const char * name,const TestParams data)6103 RayQueryBuiltinTestCase::RayQueryBuiltinTestCase(tcu::TestContext &context, const char *name, const TestParams data)
6104     : vkt::TestCase(context, name)
6105     , m_data(data)
6106 {
6107 }
6108 
~RayQueryBuiltinTestCase(void)6109 RayQueryBuiltinTestCase::~RayQueryBuiltinTestCase(void)
6110 {
6111 }
6112 
checkSupport(Context & context) const6113 void RayQueryBuiltinTestCase::checkSupport(Context &context) const
6114 {
6115     context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
6116     context.requireDeviceFunctionality("VK_KHR_ray_query");
6117 
6118     const VkPhysicalDeviceRayQueryFeaturesKHR &rayQueryFeaturesKHR = context.getRayQueryFeatures();
6119     if (rayQueryFeaturesKHR.rayQuery == false)
6120         TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");
6121 
6122     const VkPhysicalDeviceAccelerationStructureFeaturesKHR &accelerationStructureFeaturesKHR =
6123         context.getAccelerationStructureFeatures();
6124     if (accelerationStructureFeaturesKHR.accelerationStructure == false)
6125         TCU_THROW(TestError,
6126                   "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
6127 
6128     m_data.pipelineCheckSupport(context, m_data);
6129 
6130     if (m_data.testConfigCheckSupport != DE_NULL)
6131         m_data.testConfigCheckSupport(context, m_data);
6132 }
6133 
createInstance(Context & context) const6134 TestInstance *RayQueryBuiltinTestCase::createInstance(Context &context) const
6135 {
6136     return new RayQueryBuiltinTestInstance(context, m_data);
6137 }
6138 
initPrograms(SourceCollections & programCollection) const6139 void RayQueryBuiltinTestCase::initPrograms(SourceCollections &programCollection) const
6140 {
6141     m_data.pipelineInitPrograms(programCollection, m_data);
6142 }
6143 
getPipelineCheckSupport(const VkShaderStageFlagBits stage)6144 static inline CheckSupportFunc getPipelineCheckSupport(const VkShaderStageFlagBits stage)
6145 {
6146     switch (stage)
6147     {
6148     case VK_SHADER_STAGE_VERTEX_BIT:
6149     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
6150     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
6151     case VK_SHADER_STAGE_GEOMETRY_BIT:
6152     case VK_SHADER_STAGE_FRAGMENT_BIT:
6153         return GraphicsConfiguration::checkSupport;
6154 
6155     case VK_SHADER_STAGE_COMPUTE_BIT:
6156         return ComputeConfiguration::checkSupport;
6157 
6158     case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
6159     case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
6160     case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
6161     case VK_SHADER_STAGE_MISS_BIT_KHR:
6162     case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
6163     case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
6164         return RayTracingConfiguration::checkSupport;
6165 
6166     default:
6167         TCU_THROW(InternalError, "Unknown shader stage");
6168     }
6169 }
6170 
getPipelineInitPrograms(const VkShaderStageFlagBits stage)6171 static inline InitProgramsFunc getPipelineInitPrograms(const VkShaderStageFlagBits stage)
6172 {
6173     switch (stage)
6174     {
6175     case VK_SHADER_STAGE_VERTEX_BIT:
6176     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
6177     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
6178     case VK_SHADER_STAGE_GEOMETRY_BIT:
6179     case VK_SHADER_STAGE_FRAGMENT_BIT:
6180         return GraphicsConfiguration::initPrograms;
6181 
6182     case VK_SHADER_STAGE_COMPUTE_BIT:
6183         return ComputeConfiguration::initPrograms;
6184 
6185     case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
6186     case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
6187     case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
6188     case VK_SHADER_STAGE_MISS_BIT_KHR:
6189     case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
6190     case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
6191         return RayTracingConfiguration::initPrograms;
6192 
6193     default:
6194         TCU_THROW(InternalError, "Unknown shader stage");
6195     }
6196 }
6197 
getShaderBodyTextFunc(const TestType testType)6198 static inline ShaderBodyTextFunc getShaderBodyTextFunc(const TestType testType)
6199 {
6200     switch (testType)
6201     {
6202     case TEST_TYPE_FLOW:
6203         return TestConfigurationFlow::getShaderBodyText;
6204     case TEST_TYPE_PRIMITIVE_ID:
6205         return TestConfigurationPrimitiveId::getShaderBodyText;
6206     case TEST_TYPE_INSTANCE_ID:
6207         return TestConfigurationInstanceId::getShaderBodyText;
6208     case TEST_TYPE_INSTANCE_CUSTOM_INDEX:
6209         return TestConfigurationInstanceCustomIndex::getShaderBodyText;
6210     case TEST_TYPE_INTERSECTION_T_KHR:
6211         return TestConfigurationIntersectionT::getShaderBodyText;
6212     case TEST_TYPE_OBJECT_RAY_ORIGIN_KHR:
6213         return TestConfigurationObjectRayOrigin::getShaderBodyText;
6214     case TEST_TYPE_OBJECT_RAY_DIRECTION_KHR:
6215         return TestConfigurationObjectRayDirection::getShaderBodyText;
6216     case TEST_TYPE_OBJECT_TO_WORLD_KHR:
6217         return TestConfigurationObjectToWorld::getShaderBodyText;
6218     case TEST_TYPE_WORLD_TO_OBJECT_KHR:
6219         return TestConfigurationWorldToObject::getShaderBodyText;
6220     case TEST_TYPE_NULL_ACCELERATION_STRUCTURE:
6221         return TestConfigurationNullASStruct::getShaderBodyText;
6222     case TEST_TYPE_USING_WRAPPER_FUNCTION:
6223         return TestConfigurationUsingWrapperFunction::getShaderBodyText;
6224     case TEST_TYPE_GET_RAY_TMIN:
6225         return TestConfigurationGetRayTMin::getShaderBodyText;
6226     case TEST_TYPE_GET_WORLD_RAY_ORIGIN:
6227         return TestConfigurationGetWorldRayOrigin::getShaderBodyText;
6228     case TEST_TYPE_GET_WORLD_RAY_DIRECTION:
6229         return TestConfigurationGetWorldRayDirection::getShaderBodyText;
6230         ;
6231     case TEST_TYPE_GET_INTERSECTION_CANDIDATE_AABB_OPAQUE:
6232         return TestConfigurationGetIntersectionCandidateAABBOpaque::getShaderBodyText;
6233     case TEST_TYPE_GET_INTERSECTION_FRONT_FACE_CANDIDATE:
6234         return TestConfigurationGetIntersectionFrontFace::getShaderBodyTextCandidate;
6235     case TEST_TYPE_GET_INTERSECTION_FRONT_FACE_COMMITTED:
6236         return TestConfigurationGetIntersectionFrontFace::getShaderBodyTextCommitted;
6237     case TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_CANDIDATE:
6238         return TestConfigurationGetIntersectionGeometryIndex::getShaderBodyTextCandidate;
6239     case TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_COMMITTED:
6240         return TestConfigurationGetIntersectionGeometryIndex::getShaderBodyTextCommitted;
6241     case TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_CANDIDATE:
6242         return TestConfigurationGetIntersectionBarycentrics::getShaderBodyTextCandidate;
6243     case TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_COMMITTED:
6244         return TestConfigurationGetIntersectionBarycentrics::getShaderBodyTextCommitted;
6245     case TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_CANDIDATE:
6246         return TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset::getShaderBodyTextCandidate;
6247     case TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_COMMITTED:
6248         return TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset::getShaderBodyTextCommitted;
6249     case TEST_TYPE_RAY_QUERY_TERMINATE:
6250         return TestConfigurationRayQueryTerminate::getShaderBodyText;
6251     case TEST_TYPE_GET_INTERSECTION_TYPE_CANDIDATE:
6252         return TestConfigurationGetIntersectionType::getShaderBodyTextCandidate;
6253     case TEST_TYPE_GET_INTERSECTION_TYPE_COMMITTED:
6254         return TestConfigurationGetIntersectionType::getShaderBodyTextCommitted;
6255 
6256     default:
6257         TCU_THROW(InternalError, "Unknown test type");
6258     }
6259 }
6260 
getTestConfigCheckSupport(const TestType testType)6261 static inline CheckSupportFunc getTestConfigCheckSupport(const TestType testType)
6262 {
6263     if (testType >= TEST_TYPE_LAST)
6264         TCU_THROW(InternalError, "Unknown test type");
6265 
6266     switch (testType)
6267     {
6268     case TEST_TYPE_NULL_ACCELERATION_STRUCTURE:
6269         return TestConfigurationNullASStruct::checkSupport;
6270     default:
6271         return DE_NULL;
6272     }
6273 }
6274 
6275 } // namespace
6276 
6277 const struct PipelineStages
6278 {
6279     VkShaderStageFlagBits stage;
6280     const char *name;
6281 } pipelineStages[] = {
6282     {VK_SHADER_STAGE_VERTEX_BIT, "vert"},
6283     {VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "tesc"},
6284     {VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "tese"},
6285     {VK_SHADER_STAGE_GEOMETRY_BIT, "geom"},
6286     {VK_SHADER_STAGE_FRAGMENT_BIT, "frag"},
6287     {VK_SHADER_STAGE_COMPUTE_BIT, "comp"},
6288     {VK_SHADER_STAGE_RAYGEN_BIT_KHR, "rgen"},
6289     {VK_SHADER_STAGE_ANY_HIT_BIT_KHR, "ahit"},
6290     {VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, "chit"},
6291     {VK_SHADER_STAGE_MISS_BIT_KHR, "miss"},
6292     {VK_SHADER_STAGE_INTERSECTION_BIT_KHR, "sect"},
6293     {VK_SHADER_STAGE_CALLABLE_BIT_KHR, "call"},
6294 };
6295 
6296 const struct GeomTypes
6297 {
6298     GeomType geomType;
6299     const char *name;
6300 } geomTypes[] = {
6301     {GEOM_TYPE_TRIANGLES, "triangles"},
6302     {GEOM_TYPE_AABBS, "aabbs"},
6303 };
6304 
createBuiltinTests(tcu::TestContext & testCtx)6305 tcu::TestCaseGroup *createBuiltinTests(tcu::TestContext &testCtx)
6306 {
6307     // Tests verifying builtins provided by ray query
6308     de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "builtin"));
6309 
6310     const struct TestTypes
6311     {
6312         TestType testType;
6313         const char *name;
6314     } testTypes[] = {
6315         {TEST_TYPE_FLOW, "flow"},
6316         {TEST_TYPE_PRIMITIVE_ID, "primitiveid"},
6317         {TEST_TYPE_INSTANCE_ID, "instanceid"},
6318         {TEST_TYPE_INSTANCE_CUSTOM_INDEX, "instancecustomindex"},
6319         {TEST_TYPE_INTERSECTION_T_KHR, "intersectiont"},
6320         {TEST_TYPE_OBJECT_RAY_ORIGIN_KHR, "objectrayorigin"},
6321         {TEST_TYPE_OBJECT_RAY_DIRECTION_KHR, "objectraydirection"},
6322         {TEST_TYPE_OBJECT_TO_WORLD_KHR, "objecttoworld"},
6323         {TEST_TYPE_WORLD_TO_OBJECT_KHR, "worldtoobject"},
6324         {TEST_TYPE_GET_RAY_TMIN, "getraytmin"},
6325         {TEST_TYPE_GET_WORLD_RAY_ORIGIN, "getworldrayorigin"},
6326         {TEST_TYPE_GET_WORLD_RAY_DIRECTION, "getworldraydirection"},
6327         {TEST_TYPE_GET_INTERSECTION_CANDIDATE_AABB_OPAQUE, "getintersectioncandidateaabbopaque"},
6328         {TEST_TYPE_GET_INTERSECTION_FRONT_FACE_CANDIDATE, "getintersectionfrontfaceCandidate"},
6329         {TEST_TYPE_GET_INTERSECTION_FRONT_FACE_COMMITTED, "getintersectionfrontfaceCommitted"},
6330         {TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_CANDIDATE, "getintersectiongeometryindexCandidate"},
6331         {TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_COMMITTED, "getintersectiongeometryindexCommitted"},
6332         {TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_CANDIDATE, "getintersectionbarycentricsCandidate"},
6333         {TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_COMMITTED, "getintersectionbarycentricsCommitted"},
6334         {TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_CANDIDATE,
6335          "getintersectioninstanceshaderbindingtablerecordoffsetCandidate"},
6336         {TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_COMMITTED,
6337          "getintersectioninstanceshaderbindingtablerecordoffsetCommitted"},
6338         {TEST_TYPE_RAY_QUERY_TERMINATE, "rayqueryterminate"},
6339         {TEST_TYPE_GET_INTERSECTION_TYPE_CANDIDATE, "getintersectiontypeCandidate"},
6340         {TEST_TYPE_GET_INTERSECTION_TYPE_COMMITTED, "getintersectiontypeCommitted"},
6341 
6342     };
6343 
6344     for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
6345     {
6346         de::MovePtr<tcu::TestCaseGroup> testTypeGroup(
6347             new tcu::TestCaseGroup(group->getTestContext(), testTypes[testTypeNdx].name));
6348         const TestType testType                               = testTypes[testTypeNdx].testType;
6349         const ShaderBodyTextFunc testConfigShaderBodyTextFunc = getShaderBodyTextFunc(testType);
6350         const bool fixedPointVectorOutput =
6351             testType == TEST_TYPE_OBJECT_RAY_ORIGIN_KHR || testType == TEST_TYPE_OBJECT_RAY_DIRECTION_KHR ||
6352             testType == TEST_TYPE_GET_WORLD_RAY_ORIGIN || testType == TEST_TYPE_GET_WORLD_RAY_DIRECTION ||
6353             testType == TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_CANDIDATE ||
6354             testType == TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_COMMITTED ||
6355             testType == TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_CANDIDATE ||
6356             testType == TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_COMMITTED;
6357         const bool fixedPointMatrixOutput =
6358             testType == TEST_TYPE_OBJECT_TO_WORLD_KHR || testType == TEST_TYPE_WORLD_TO_OBJECT_KHR;
6359         const bool single =
6360             testTypeNdx == TEST_TYPE_FLOW || testType == TEST_TYPE_OBJECT_RAY_ORIGIN_KHR ||
6361             testType == TEST_TYPE_OBJECT_RAY_DIRECTION_KHR || testType == TEST_TYPE_OBJECT_TO_WORLD_KHR ||
6362             testType == TEST_TYPE_WORLD_TO_OBJECT_KHR || testType == TEST_TYPE_GET_RAY_TMIN ||
6363             testType == TEST_TYPE_GET_WORLD_RAY_ORIGIN || testType == TEST_TYPE_GET_WORLD_RAY_DIRECTION ||
6364             testType == TEST_TYPE_GET_INTERSECTION_CANDIDATE_AABB_OPAQUE ||
6365             testType == TEST_TYPE_GET_INTERSECTION_FRONT_FACE_CANDIDATE ||
6366             testType == TEST_TYPE_GET_INTERSECTION_FRONT_FACE_COMMITTED ||
6367             testType == TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_CANDIDATE ||
6368             testType == TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_COMMITTED ||
6369             testType == TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_CANDIDATE ||
6370             testType == TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_COMMITTED || testType == TEST_TYPE_RAY_QUERY_TERMINATE;
6371         const uint32_t imageDepth = fixedPointMatrixOutput ? 4 * 4 : fixedPointVectorOutput ? 4 : 1;
6372 
6373         for (size_t pipelineStageNdx = 0; pipelineStageNdx < DE_LENGTH_OF_ARRAY(pipelineStages); ++pipelineStageNdx)
6374         {
6375             de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(
6376                 new tcu::TestCaseGroup(group->getTestContext(), pipelineStages[pipelineStageNdx].name));
6377             const VkShaderStageFlagBits stage           = pipelineStages[pipelineStageNdx].stage;
6378             const CheckSupportFunc pipelineCheckSupport = getPipelineCheckSupport(stage);
6379             const InitProgramsFunc pipelineInitPrograms = getPipelineInitPrograms(stage);
6380             const uint32_t instancesGroupCount          = single ? 1 : 2;
6381             const uint32_t geometriesGroupCount         = single ? 1 : 8;
6382             const uint32_t squaresGroupCount = (TEST_WIDTH * TEST_HEIGHT) / geometriesGroupCount / instancesGroupCount;
6383 
6384             DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == TEST_WIDTH * TEST_HEIGHT);
6385 
6386             for (size_t geomTypeNdx = 0; geomTypeNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypeNdx)
6387             {
6388                 const GeomType geomType     = geomTypes[geomTypeNdx].geomType;
6389                 const TestParams testParams = {
6390                     TEST_WIDTH,                   //  uint32_t width;
6391                     TEST_HEIGHT,                  //  uint32_t height;
6392                     imageDepth,                   //  uint32_t depth;
6393                     testType,                     //  TestType testType;
6394                     stage,                        //  VkShaderStageFlagBits stage;
6395                     geomType,                     //  GeomType geomType;
6396                     squaresGroupCount,            //  uint32_t squaresGroupCount;
6397                     geometriesGroupCount,         //  uint32_t geometriesGroupCount;
6398                     instancesGroupCount,          //  uint32_t instancesGroupCount;
6399                     VK_FORMAT_R32_SINT,           //  VkFormat format;
6400                     pipelineCheckSupport,         //  CheckSupportFunc pipelineCheckSupport;
6401                     pipelineInitPrograms,         //  InitProgramsFunc pipelineInitPrograms;
6402                     testConfigShaderBodyTextFunc, //  ShaderTestTextFunc testConfigShaderBodyText;
6403                     false,                        //  bool isSPIRV;
6404                     DE_NULL,                      //  CheckSupportFunc testConfigCheckSupport;
6405                 };
6406 
6407                 if (geomType != GEOM_TYPE_AABBS && testType == TEST_TYPE_GET_INTERSECTION_CANDIDATE_AABB_OPAQUE)
6408                 {
6409                     continue;
6410                 }
6411 
6412                 if (geomType != GEOM_TYPE_TRIANGLES && (testType == TEST_TYPE_GET_INTERSECTION_FRONT_FACE_CANDIDATE ||
6413                                                         testType == TEST_TYPE_GET_INTERSECTION_FRONT_FACE_COMMITTED ||
6414                                                         testType == TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_CANDIDATE ||
6415                                                         testType == TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_COMMITTED))
6416                 {
6417                     continue;
6418                 }
6419 
6420                 sourceTypeGroup->addChild(
6421                     new RayQueryBuiltinTestCase(group->getTestContext(), geomTypes[geomTypeNdx].name, testParams));
6422             }
6423 
6424             testTypeGroup->addChild(sourceTypeGroup.release());
6425         }
6426 
6427         group->addChild(testTypeGroup.release());
6428     }
6429 
6430     return group.release();
6431 }
6432 
createAdvancedTests(tcu::TestContext & testCtx)6433 tcu::TestCaseGroup *createAdvancedTests(tcu::TestContext &testCtx)
6434 {
6435     de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "advanced"));
6436 
6437     const struct TestTypes
6438     {
6439         TestType testType;
6440         const char *name;
6441     } testTypes[] = {{TEST_TYPE_NULL_ACCELERATION_STRUCTURE, "null_as"},
6442                      {TEST_TYPE_USING_WRAPPER_FUNCTION, "using_wrapper_function"}};
6443 
6444     for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
6445     {
6446         de::MovePtr<tcu::TestCaseGroup> testTypeGroup(
6447             new tcu::TestCaseGroup(group->getTestContext(), testTypes[testTypeNdx].name));
6448         const TestType testType                               = testTypes[testTypeNdx].testType;
6449         const ShaderBodyTextFunc testConfigShaderBodyTextFunc = getShaderBodyTextFunc(testType);
6450         const CheckSupportFunc testConfigCheckSupport         = getTestConfigCheckSupport(testType);
6451         const uint32_t imageDepth                             = 1;
6452         bool useSPIRV                                         = false;
6453 
6454         for (size_t pipelineStageNdx = 0; pipelineStageNdx < DE_LENGTH_OF_ARRAY(pipelineStages); ++pipelineStageNdx)
6455         {
6456             const VkShaderStageFlagBits stage = pipelineStages[pipelineStageNdx].stage;
6457 
6458             // tests that are implemented using spirv are limit to compute stage
6459             if (testType == TEST_TYPE_USING_WRAPPER_FUNCTION)
6460             {
6461                 if (stage != VK_SHADER_STAGE_COMPUTE_BIT)
6462                     continue;
6463                 useSPIRV = true;
6464             }
6465 
6466             de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(
6467                 new tcu::TestCaseGroup(group->getTestContext(), pipelineStages[pipelineStageNdx].name));
6468             const CheckSupportFunc pipelineCheckSupport = getPipelineCheckSupport(stage);
6469             const InitProgramsFunc pipelineInitPrograms = getPipelineInitPrograms(stage);
6470             const uint32_t instancesGroupCount          = 1;
6471             const uint32_t geometriesGroupCount         = 1;
6472             const uint32_t squaresGroupCount = (TEST_WIDTH * TEST_HEIGHT) / geometriesGroupCount / instancesGroupCount;
6473 
6474             DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == TEST_WIDTH * TEST_HEIGHT);
6475 
6476             for (size_t geomTypeNdx = 0; geomTypeNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypeNdx)
6477             {
6478                 const GeomType geomType     = geomTypes[geomTypeNdx].geomType;
6479                 const TestParams testParams = {
6480                     TEST_WIDTH,                   //  uint32_t width;
6481                     TEST_HEIGHT,                  //  uint32_t height;
6482                     imageDepth,                   //  uint32_t depth;
6483                     testType,                     //  TestType testType;
6484                     stage,                        //  VkShaderStageFlagBits stage;
6485                     geomType,                     //  GeomType geomType;
6486                     squaresGroupCount,            //  uint32_t squaresGroupCount;
6487                     geometriesGroupCount,         //  uint32_t geometriesGroupCount;
6488                     instancesGroupCount,          //  uint32_t instancesGroupCount;
6489                     VK_FORMAT_R32_SINT,           //  VkFormat format;
6490                     pipelineCheckSupport,         //  CheckSupportFunc pipelineCheckSupport;
6491                     pipelineInitPrograms,         //  InitProgramsFunc pipelineInitPrograms;
6492                     testConfigShaderBodyTextFunc, //  ShaderTestTextFunc testConfigShaderBodyText;
6493                     useSPIRV,                     //  bool isSPIRV;
6494                     testConfigCheckSupport,       //  CheckSupportFunc testConfigCheckSupport;
6495                 };
6496 
6497                 sourceTypeGroup->addChild(
6498                     new RayQueryBuiltinTestCase(group->getTestContext(), geomTypes[geomTypeNdx].name, testParams));
6499             }
6500 
6501             testTypeGroup->addChild(sourceTypeGroup.release());
6502         }
6503 
6504         group->addChild(testTypeGroup.release());
6505     }
6506 
6507     return group.release();
6508 }
6509 
6510 } // namespace RayQuery
6511 } // namespace vkt
6512