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 "vktRayQueryWatertightnessTests.hpp"
25 
26 #include "vkDefs.hpp"
27 
28 #include "vktTestCase.hpp"
29 #include "vktTestGroupUtil.hpp"
30 #include "vkCmdUtil.hpp"
31 #include "vkObjUtil.hpp"
32 #include "vkBuilderUtil.hpp"
33 #include "vkBarrierUtil.hpp"
34 #include "vkBufferWithMemory.hpp"
35 #include "vkImageWithMemory.hpp"
36 #include "vkTypeUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "deRandom.hpp"
39 #include "tcuTexture.hpp"
40 #include "tcuTextureUtil.hpp"
41 #include "tcuTestLog.hpp"
42 #include "tcuImageCompare.hpp"
43 #include "tcuCommandLine.hpp"
44 
45 #include "vkRayTracingUtil.hpp"
46 
47 namespace vkt
48 {
49 namespace RayQuery
50 {
51 namespace
52 {
53 using namespace vk;
54 using namespace vkt;
55 
56 static const VkFlags ALL_RAY_TRACING_STAGES = VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
57                                               VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR |
58                                               VK_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
59 
60 enum TestType
61 {
62     TEST_TYPE_NO_MISS = 0,
63     TEST_TYPE_SINGLE_HIT,
64 };
65 
66 enum GeomType
67 {
68     GEOM_TYPE_TRIANGLES,
69     GEOM_TYPE_AABBS,
70     GEOM_TYPE_LAST,
71 };
72 
73 const uint32_t TEST_WIDTH            = 256u;
74 const uint32_t TEST_HEIGHT           = 256u;
75 const float MIN_AABB_SIDE_LENGTH     = 1e-6f;
76 const float MIN_TRIANGLE_EDGE_LENGTH = 1.0f / float(10 * TEST_WIDTH * TEST_HEIGHT);
77 const float MIN_TRIANGLE_AREA_SIZE   = 1.0f / float(10 * TEST_WIDTH * TEST_HEIGHT);
78 
79 struct TestParams;
80 
81 typedef void (*CheckSupportFunc)(Context &context, const TestParams &testParams);
82 typedef void (*InitProgramsFunc)(SourceCollections &programCollection, const TestParams &testParams);
83 typedef const std::string (*ShaderBodyTextFunc)(const TestParams &testParams);
84 
85 class PipelineConfiguration
86 {
87 public:
PipelineConfiguration()88     PipelineConfiguration()
89     {
90     }
~PipelineConfiguration()91     virtual ~PipelineConfiguration()
92     {
93     }
94 
95     virtual void initConfiguration(Context &context, TestParams &testParams)     = 0;
96     virtual void fillCommandBuffer(Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
97                                    const VkAccelerationStructureKHR *rayQueryTopAccelerationStructurePtr,
98                                    const VkDescriptorImageInfo &resultImageInfo) = 0;
99 };
100 
101 class TestConfiguration
102 {
103 public:
TestConfiguration()104     TestConfiguration() : m_bottomAccelerationStructures(), m_topAccelerationStructure(), m_expected()
105     {
106     }
~TestConfiguration()107     virtual ~TestConfiguration()
108     {
109     }
110 
111     virtual const VkAccelerationStructureKHR *initAccelerationStructures(Context &context, TestParams &testParams,
112                                                                          VkCommandBuffer cmdBuffer) = 0;
113     virtual bool verify(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams)   = 0;
114 
115 protected:
116     std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> m_bottomAccelerationStructures;
117     de::SharedPtr<TopLevelAccelerationStructure> m_topAccelerationStructure;
118     std::vector<int32_t> m_expected;
119 };
120 
121 struct TestParams
122 {
123     uint32_t width;
124     uint32_t height;
125     uint32_t depth;
126     uint32_t randomSeed;
127     TestType testType;
128     VkShaderStageFlagBits stage;
129     GeomType geomType;
130     uint32_t squaresGroupCount;
131     uint32_t geometriesGroupCount;
132     uint32_t instancesGroupCount;
133     VkFormat format;
134     CheckSupportFunc pipelineCheckSupport;
135     InitProgramsFunc pipelineInitPrograms;
136     ShaderBodyTextFunc testConfigShaderBodyText;
137 };
138 
getShaderGroupHandleSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)139 uint32_t getShaderGroupHandleSize(const InstanceInterface &vki, const VkPhysicalDevice physicalDevice)
140 {
141     de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
142 
143     rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
144 
145     return rayTracingPropertiesKHR->getShaderGroupHandleSize();
146 }
147 
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)148 uint32_t getShaderGroupBaseAlignment(const InstanceInterface &vki, const VkPhysicalDevice physicalDevice)
149 {
150     de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
151 
152     rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
153 
154     return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
155 }
156 
getVkBuffer(const de::MovePtr<BufferWithMemory> & buffer)157 VkBuffer getVkBuffer(const de::MovePtr<BufferWithMemory> &buffer)
158 {
159     VkBuffer result = (buffer.get() == DE_NULL) ? DE_NULL : buffer->get();
160 
161     return result;
162 }
163 
makeStridedDeviceAddressRegion(const DeviceInterface & vkd,const VkDevice device,VkBuffer buffer,VkDeviceSize size)164 VkStridedDeviceAddressRegionKHR makeStridedDeviceAddressRegion(const DeviceInterface &vkd, const VkDevice device,
165                                                                VkBuffer buffer, VkDeviceSize size)
166 {
167     const VkDeviceSize sizeFixed = ((buffer == DE_NULL) ? 0ull : size);
168 
169     return makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, buffer, 0), sizeFixed, sizeFixed);
170 }
171 
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)172 VkImageCreateInfo makeImageCreateInfo(VkFormat format, uint32_t width, uint32_t height, uint32_t depth,
173                                       VkImageType imageType        = VK_IMAGE_TYPE_3D,
174                                       VkImageUsageFlags usageFlags = VK_IMAGE_USAGE_STORAGE_BIT |
175                                                                      VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
176                                                                      VK_IMAGE_USAGE_TRANSFER_DST_BIT)
177 {
178     const VkImageCreateInfo imageCreateInfo = {
179         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
180         DE_NULL,                             // const void* pNext;
181         (VkImageCreateFlags)0u,              // VkImageCreateFlags flags;
182         imageType,                           // VkImageType imageType;
183         format,                              // VkFormat format;
184         makeExtent3D(width, height, depth),  // VkExtent3D extent;
185         1u,                                  // uint32_t mipLevels;
186         1u,                                  // uint32_t arrayLayers;
187         VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits samples;
188         VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling tiling;
189         usageFlags,                          // VkImageUsageFlags usage;
190         VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode sharingMode;
191         0u,                                  // uint32_t queueFamilyIndexCount;
192         DE_NULL,                             // const uint32_t* pQueueFamilyIndices;
193         VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout initialLayout;
194     };
195 
196     return imageCreateInfo;
197 }
198 
getMissPassthrough(void)199 static const std::string getMissPassthrough(void)
200 {
201     const std::string missPassthrough = "#version 460 core\n"
202                                         "#extension GL_EXT_ray_tracing : require\n"
203                                         "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
204                                         "\n"
205                                         "void main()\n"
206                                         "{\n"
207                                         "}\n";
208 
209     return missPassthrough;
210 }
211 
getHitPassthrough(void)212 static const std::string getHitPassthrough(void)
213 {
214     const std::string hitPassthrough = "#version 460 core\n"
215                                        "#extension GL_EXT_ray_tracing : require\n"
216                                        "hitAttributeEXT vec3 attribs;\n"
217                                        "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
218                                        "\n"
219                                        "void main()\n"
220                                        "{\n"
221                                        "}\n";
222 
223     return hitPassthrough;
224 }
225 
getGraphicsPassthrough(void)226 static const std::string getGraphicsPassthrough(void)
227 {
228     std::ostringstream src;
229 
230     src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
231         << "\n"
232         << "void main(void)\n"
233         << "{\n"
234         << "}\n";
235 
236     return src.str();
237 }
238 
getVertexPassthrough(void)239 static const std::string getVertexPassthrough(void)
240 {
241     std::ostringstream src;
242 
243     src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
244         << "\n"
245         << "layout(location = 0) in vec4 in_position;\n"
246         << "\n"
247         << "void main(void)\n"
248         << "{\n"
249         << "  gl_Position = in_position;\n"
250         << "}\n";
251 
252     return src.str();
253 }
254 
mixVec2(const tcu::Vec2 & a,const tcu::Vec2 & b,const float alpha)255 static inline tcu::Vec2 mixVec2(const tcu::Vec2 &a, const tcu::Vec2 &b, const float alpha)
256 {
257     const tcu::Vec2 result = a * alpha + b * (1.0f - alpha);
258 
259     return result;
260 }
261 
mixCoordsVec2(const tcu::Vec2 & a,const tcu::Vec2 & b,const float alpha,const float beta)262 static inline tcu::Vec2 mixCoordsVec2(const tcu::Vec2 &a, const tcu::Vec2 &b, const float alpha, const float beta)
263 {
264     const tcu::Vec2 result = tcu::Vec2(deFloatMix(a.x(), b.x(), alpha), deFloatMix(a.y(), b.y(), beta));
265 
266     return result;
267 }
268 
triangleEdgeLength(const tcu::Vec2 & vertexA,const tcu::Vec2 & vertexB)269 inline float triangleEdgeLength(const tcu::Vec2 &vertexA, const tcu::Vec2 &vertexB)
270 {
271     const float abx = vertexA.x() - vertexB.x();
272     const float aby = vertexA.y() - vertexB.y();
273     const float abq = abx * abx + aby * aby;
274     const float ab  = deFloatSqrt(abq);
275 
276     return ab;
277 }
278 
triangleArea(const float edgeALen,const float edgeBLen,const float edgeCLen)279 inline float triangleArea(const float edgeALen, const float edgeBLen, const float edgeCLen)
280 {
281     const float s = (edgeALen + edgeBLen + edgeCLen) / 2.0f;
282     const float q = s * (s - edgeALen) * (s - edgeBLen) * (s - edgeCLen);
283 
284     if (q <= 0.0f)
285         return 0.0f;
286 
287     return deFloatSqrt(q);
288 }
289 
getGeomName(bool writePointSize)290 static const std::string getGeomName(bool writePointSize)
291 {
292     std::ostringstream str;
293     str << "geom" << (writePointSize ? "_point_size" : "");
294     return str.str();
295 }
296 
297 class GraphicsConfiguration : public PipelineConfiguration
298 {
299 public:
300     static void checkSupport(Context &context, const TestParams &testParams);
301     static void initPrograms(SourceCollections &programCollection, const TestParams &testParams);
302 
303     GraphicsConfiguration();
~GraphicsConfiguration()304     virtual ~GraphicsConfiguration()
305     {
306     }
307 
308     void initVertexBuffer(Context &context, TestParams &testParams);
309     Move<VkPipeline> makeGraphicsPipeline(Context &context, TestParams &testParams);
310     virtual void initConfiguration(Context &context, TestParams &testParams) override;
311     virtual void fillCommandBuffer(Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
312                                    const VkAccelerationStructureKHR *rayQueryTopAccelerationStructurePtr,
313                                    const VkDescriptorImageInfo &resultImageInfo) override;
314 
315 private:
316     Move<VkDescriptorSetLayout> m_descriptorSetLayout;
317     Move<VkDescriptorPool> m_descriptorPool;
318     Move<VkDescriptorSet> m_descriptorSet;
319 
320     VkFormat m_framebufferFormat;
321     Move<VkImage> m_framebufferImage;
322     de::MovePtr<Allocation> m_framebufferImageAlloc;
323     Move<VkImageView> m_framebufferAttachment;
324 
325     Move<VkShaderModule> m_vertShaderModule;
326     Move<VkShaderModule> m_geomShaderModule;
327     Move<VkShaderModule> m_tescShaderModule;
328     Move<VkShaderModule> m_teseShaderModule;
329     Move<VkShaderModule> m_fragShaderModule;
330 
331     Move<VkRenderPass> m_renderPass;
332     Move<VkFramebuffer> m_framebuffer;
333     Move<VkPipelineLayout> m_pipelineLayout;
334     Move<VkPipeline> m_pipeline;
335 
336     uint32_t m_vertexCount;
337     Move<VkBuffer> m_vertexBuffer;
338     de::MovePtr<Allocation> m_vertexBufferAlloc;
339 };
340 
GraphicsConfiguration()341 GraphicsConfiguration::GraphicsConfiguration()
342     : PipelineConfiguration()
343     , m_descriptorSetLayout()
344     , m_descriptorPool()
345     , m_descriptorSet()
346     , m_framebufferFormat(VK_FORMAT_R8G8B8A8_UNORM)
347     , m_framebufferImage()
348     , m_framebufferImageAlloc()
349     , m_framebufferAttachment()
350     , m_vertShaderModule()
351     , m_geomShaderModule()
352     , m_tescShaderModule()
353     , m_teseShaderModule()
354     , m_fragShaderModule()
355     , m_renderPass()
356     , m_framebuffer()
357     , m_pipelineLayout()
358     , m_pipeline()
359     , m_vertexCount(0)
360     , m_vertexBuffer()
361     , m_vertexBufferAlloc()
362 {
363 }
364 
checkSupport(Context & context,const TestParams & testParams)365 void GraphicsConfiguration::checkSupport(Context &context, const TestParams &testParams)
366 {
367     switch (testParams.stage)
368     {
369     case VK_SHADER_STAGE_VERTEX_BIT:
370     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
371     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
372     case VK_SHADER_STAGE_GEOMETRY_BIT:
373         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
374         break;
375     default:
376         break;
377     }
378 
379     switch (testParams.stage)
380     {
381     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
382     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
383         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
384         break;
385     case VK_SHADER_STAGE_GEOMETRY_BIT:
386         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
387         break;
388     default:
389         break;
390     }
391 }
392 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)393 void GraphicsConfiguration::initPrograms(SourceCollections &programCollection, const TestParams &testParams)
394 {
395     const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
396     const std::string testShaderBody = testParams.testConfigShaderBodyText(testParams);
397 
398     switch (testParams.stage)
399     {
400     case VK_SHADER_STAGE_VERTEX_BIT:
401     {
402         {
403             std::ostringstream src;
404             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
405                 << "#extension GL_EXT_ray_query : require\n"
406                 << "#extension GL_EXT_ray_tracing : require\n"
407                 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
408                 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT "
409                    "rayQueryTopLevelAccelerationStructure;\n"
410                 << "\n"
411                 << "void testFunc(ivec3 pos, ivec3 size)\n"
412                 << "{\n"
413                 << testShaderBody << "}\n"
414                 << "\n"
415                 << "void main(void)\n"
416                 << "{\n"
417                 << "  const int   posId    = int(gl_VertexIndex / 3);\n"
418                 << "  const int   vertId   = int(gl_VertexIndex % 3);\n"
419                 << "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
420                 << "  const ivec3 pos      = ivec3(posId % size.x, posId / size.x, 0);\n"
421                 << "\n"
422                 << "  if (vertId == 0)\n"
423                 << "  {\n"
424                 << "    testFunc(pos, size);\n"
425                 << "  }\n"
426                 << "}\n";
427 
428             programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
429         }
430 
431         programCollection.glslSources.add("frag") << glu::FragmentSource(getGraphicsPassthrough()) << buildOptions;
432 
433         break;
434     }
435 
436     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
437     {
438         {
439             std::ostringstream src;
440             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
441                 << "\n"
442                 << "layout(location = 0) in vec4 in_position;\n"
443                 << "out gl_PerVertex\n"
444                 << "{\n"
445                 << "  vec4 gl_Position;\n"
446                 << "};\n"
447                 << "\n"
448                 << "void main(void)\n"
449                 << "{\n"
450                 << "  gl_Position = in_position;\n"
451                 << "}\n";
452 
453             programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
454         }
455 
456         {
457             std::ostringstream src;
458             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
459                 << "#extension GL_EXT_tessellation_shader : require\n"
460                 << "#extension GL_EXT_ray_query : require\n"
461                 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
462                 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT "
463                    "rayQueryTopLevelAccelerationStructure;\n"
464                 << "in gl_PerVertex\n"
465                 << "{\n"
466                 << "  vec4 gl_Position;\n"
467                 << "} gl_in[];\n"
468                 << "layout(vertices = 3) out;\n"
469                 << "out gl_PerVertex\n"
470                 << "{\n"
471                 << "  vec4 gl_Position;\n"
472                 << "} gl_out[];\n"
473                 << "\n"
474                 << "void testFunc(ivec3 pos, ivec3 size)\n"
475                 << "{\n"
476                 << testShaderBody << "}\n"
477                 << "\n"
478                 << "void main(void)\n"
479                 << "{\n"
480                 << "\n"
481                 << "  if (gl_InvocationID == 0)\n"
482                 << "  {\n"
483                 << "    const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
484                 << "    int index = int(gl_in[gl_InvocationID].gl_Position.z);\n"
485                 << "    int x = index % size.x;\n"
486                 << "    int y = index / size.y;\n"
487                 << "    const ivec3 pos = ivec3(x, y, 0);\n"
488                 << "    testFunc(pos, size);\n"
489                 << "  }\n"
490                 << "\n"
491                 << "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
492                 << "  gl_TessLevelInner[0] = 1;\n"
493                 << "  gl_TessLevelInner[1] = 1;\n"
494                 << "  gl_TessLevelOuter[gl_InvocationID] = 1;\n"
495                 << "}\n";
496 
497             programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions;
498         }
499 
500         {
501             std::ostringstream src;
502             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
503                 << "#extension GL_EXT_tessellation_shader : require\n"
504                 << "layout(triangles, equal_spacing, ccw) in;\n"
505                 << "in gl_PerVertex\n"
506                 << "{\n"
507                 << "  vec4 gl_Position;\n"
508                 << "} gl_in[];\n"
509                 << "\n"
510                 << "void main(void)\n"
511                 << "{\n"
512                 << "  gl_Position = gl_in[0].gl_Position;\n"
513                 << "}\n";
514 
515             programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions;
516         }
517 
518         break;
519     }
520 
521     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
522     {
523         {
524             std::ostringstream src;
525             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
526                 << "\n"
527                 << "layout(location = 0) in vec4 in_position;\n"
528                 << "out gl_PerVertex"
529                 << "{\n"
530                 << "  vec4 gl_Position;\n"
531                 << "};\n"
532                 << "\n"
533                 << "void main(void)\n"
534                 << "{\n"
535                 << "  gl_Position = in_position;\n"
536                 << "}\n";
537 
538             programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
539         }
540 
541         {
542             std::ostringstream src;
543             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
544                 << "#extension GL_EXT_tessellation_shader : require\n"
545                 << "in gl_PerVertex\n"
546                 << "{\n"
547                 << "  vec4 gl_Position;\n"
548                 << "} gl_in[];\n"
549                 << "layout(vertices = 3) out;\n"
550                 << "out gl_PerVertex\n"
551                 << "{\n"
552                 << "  vec4 gl_Position;\n"
553                 << "} gl_out[];\n"
554                 << "\n"
555                 << "void main(void)\n"
556                 << "{\n"
557                 << "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
558                 << "  gl_TessLevelInner[0] = 1;\n"
559                 << "  gl_TessLevelInner[1] = 1;\n"
560                 << "  gl_TessLevelOuter[gl_InvocationID] = 1;\n"
561                 << "}\n";
562 
563             programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions;
564         }
565 
566         {
567             std::ostringstream src;
568             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
569                 << "#extension GL_EXT_tessellation_shader : require\n"
570                 << "#extension GL_EXT_ray_query : require\n"
571                 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
572                 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT "
573                    "rayQueryTopLevelAccelerationStructure;\n"
574                 << "layout(triangles, equal_spacing, ccw) in;\n"
575                 << "in gl_PerVertex\n"
576                 << "{\n"
577                 << "  vec4 gl_Position;\n"
578                 << "} gl_in[];\n"
579                 << "\n"
580                 << "void testFunc(ivec3 pos, ivec3 size)\n"
581                 << "{\n"
582                 << testShaderBody << "}\n"
583                 << "\n"
584                 << "void main(void)\n"
585                 << "{\n"
586                 << "    const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
587                 << "    int index = int(gl_in[0].gl_Position.z);\n"
588                 << "    int x = index % size.x;\n"
589                 << "    int y = index / size.y;\n"
590                 << "    const ivec3 pos = ivec3(x, y, 0);\n"
591                 << "    testFunc(pos, size);\n"
592                 << "    gl_Position = gl_in[0].gl_Position;\n"
593                 << "}\n";
594 
595             programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions;
596         }
597 
598         break;
599     }
600 
601     case VK_SHADER_STAGE_GEOMETRY_BIT:
602     {
603         programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions;
604 
605         for (uint32_t i = 0; i < 2; ++i)
606         {
607             const bool writePointSize = i == 1;
608             std::string pointSize     = writePointSize ? "    gl_PointSize = 1.0f;\n" : "";
609 
610             std::ostringstream src;
611             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
612                 << "#extension GL_EXT_ray_query : require\n"
613                 << "layout(triangles) in;\n"
614                 << "layout(points, max_vertices = 1) out;\n"
615                 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
616                 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT "
617                    "rayQueryTopLevelAccelerationStructure;\n"
618                 << "\n"
619                 << "void testFunc(ivec3 pos, ivec3 size)\n"
620                 << "{\n"
621                 << testShaderBody << "}\n"
622                 << "\n"
623                 << "void main(void)\n"
624                 << "{\n"
625                 << "  const int   posId    = int(gl_PrimitiveIDIn);\n"
626                 << "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
627                 << "  const ivec3 pos      = ivec3(posId % size.x, posId / size.x, 0);\n"
628                 << "\n"
629                 << "  testFunc(pos, size);\n"
630                 << pointSize << "}\n";
631 
632             programCollection.glslSources.add(getGeomName(writePointSize))
633                 << glu::GeometrySource(src.str()) << buildOptions;
634         }
635 
636         break;
637     }
638 
639     case VK_SHADER_STAGE_FRAGMENT_BIT:
640     {
641         programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions;
642 
643         {
644             std::ostringstream src;
645             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
646                 << "#extension GL_EXT_ray_query : require\n"
647                 << "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
648                 << "layout(set = 0, binding = 1) uniform accelerationStructureEXT "
649                    "rayQueryTopLevelAccelerationStructure;\n"
650                 << "\n"
651                 << "void testFunc(ivec3 pos, ivec3 size)\n"
652                 << "{\n"
653                 << testShaderBody << "}\n"
654                 << "\n"
655                 << "void main(void)\n"
656                 << "{\n"
657                 << "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
658                 << "  const ivec3 pos      = ivec3(int(gl_FragCoord.x - 0.5f), int(gl_FragCoord.y - 0.5f), 0);\n"
659                 << "\n"
660                 << "  testFunc(pos, size);\n"
661                 << "}\n";
662 
663             programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()) << buildOptions;
664         }
665 
666         break;
667     }
668 
669     default:
670         TCU_THROW(InternalError, "Unknown stage");
671     }
672 }
673 
initVertexBuffer(Context & context,TestParams & testParams)674 void GraphicsConfiguration::initVertexBuffer(Context &context, TestParams &testParams)
675 {
676     const DeviceInterface &vkd = context.getDeviceInterface();
677     const VkDevice device      = context.getDevice();
678     const uint32_t width       = testParams.width;
679     const uint32_t height      = testParams.height;
680     Allocator &allocator       = context.getDefaultAllocator();
681     std::vector<tcu::Vec4> vertices;
682 
683     switch (testParams.stage)
684     {
685     case VK_SHADER_STAGE_VERTEX_BIT:
686     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
687     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
688     {
689         float z       = 0.0f;
690         const float w = 1.0f;
691 
692         vertices.reserve(3 * height * width);
693 
694         for (uint32_t y = 0; y < height; ++y)
695             for (uint32_t x = 0; x < width; ++x)
696             {
697                 const float x0 = float(x + 0) / float(width);
698                 const float y0 = float(y + 0) / float(height);
699                 const float x1 = float(x + 1) / float(width);
700                 const float y1 = float(y + 1) / float(height);
701                 const float xm = (x0 + x1) / 2.0f;
702                 const float ym = (y0 + y1) / 2.0f;
703 
704                 vertices.push_back(tcu::Vec4(x0, y0, z, w));
705                 vertices.push_back(tcu::Vec4(xm, y1, z, w));
706                 vertices.push_back(tcu::Vec4(x1, ym, z, w));
707 
708                 z += 1.f;
709             }
710 
711         break;
712     }
713 
714     case VK_SHADER_STAGE_GEOMETRY_BIT:
715     {
716         const float z = 0.0f;
717         const float w = 1.0f;
718 
719         vertices.reserve(3 * height * width);
720 
721         for (uint32_t y = 0; y < height; ++y)
722             for (uint32_t x = 0; x < width; ++x)
723             {
724                 const float x0 = float(x + 0) / float(width);
725                 const float y0 = float(y + 0) / float(height);
726                 const float x1 = float(x + 1) / float(width);
727                 const float y1 = float(y + 1) / float(height);
728                 const float xm = (x0 + x1) / 2.0f;
729                 const float ym = (y0 + y1) / 2.0f;
730 
731                 vertices.push_back(tcu::Vec4(x0, y0, z, w));
732                 vertices.push_back(tcu::Vec4(xm, y1, z, w));
733                 vertices.push_back(tcu::Vec4(x1, ym, z, w));
734             }
735 
736         break;
737     }
738 
739     case VK_SHADER_STAGE_FRAGMENT_BIT:
740     {
741         const float z     = 1.0f;
742         const float w     = 1.0f;
743         const tcu::Vec4 a = tcu::Vec4(-1.0f, -1.0f, z, w);
744         const tcu::Vec4 b = tcu::Vec4(+1.0f, -1.0f, z, w);
745         const tcu::Vec4 c = tcu::Vec4(-1.0f, +1.0f, z, w);
746         const tcu::Vec4 d = tcu::Vec4(+1.0f, +1.0f, z, w);
747 
748         vertices.push_back(a);
749         vertices.push_back(b);
750         vertices.push_back(c);
751 
752         vertices.push_back(b);
753         vertices.push_back(c);
754         vertices.push_back(d);
755 
756         break;
757     }
758 
759     default:
760         TCU_THROW(InternalError, "Unknown stage");
761     }
762 
763     // Initialize vertex buffer
764     {
765         const VkDeviceSize vertexBufferSize = sizeof(vertices[0][0]) * vertices[0].SIZE * vertices.size();
766         const VkBufferCreateInfo vertexBufferCreateInfo =
767             makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
768 
769         m_vertexCount       = static_cast<uint32_t>(vertices.size());
770         m_vertexBuffer      = createBuffer(vkd, device, &vertexBufferCreateInfo);
771         m_vertexBufferAlloc = bindBuffer(vkd, device, allocator, *m_vertexBuffer, vk::MemoryRequirement::HostVisible);
772 
773         deMemcpy(m_vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexBufferSize);
774         flushAlloc(vkd, device, *m_vertexBufferAlloc);
775     }
776 }
777 
makeGraphicsPipeline(Context & context,TestParams & testParams)778 Move<VkPipeline> GraphicsConfiguration::makeGraphicsPipeline(Context &context, TestParams &testParams)
779 {
780     const DeviceInterface &vkd = context.getDeviceInterface();
781     const VkDevice device      = context.getDevice();
782     const bool tessStageTest   = (testParams.stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
783                                 testParams.stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
784     const VkPrimitiveTopology topology =
785         tessStageTest ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
786     const uint32_t patchControlPoints = tessStageTest ? 3 : 0;
787     const std::vector<VkViewport> viewports(1, makeViewport(testParams.width, testParams.height));
788     const std::vector<VkRect2D> scissors(1, makeRect2D(testParams.width, testParams.height));
789 
790     return vk::makeGraphicsPipeline(vkd, device, *m_pipelineLayout, *m_vertShaderModule, *m_tescShaderModule,
791                                     *m_teseShaderModule, *m_geomShaderModule, *m_fragShaderModule, *m_renderPass,
792                                     viewports, scissors, topology, 0, patchControlPoints);
793 }
794 
initConfiguration(Context & context,TestParams & testParams)795 void GraphicsConfiguration::initConfiguration(Context &context, TestParams &testParams)
796 {
797     const InstanceInterface &vki          = context.getInstanceInterface();
798     const DeviceInterface &vkd            = context.getDeviceInterface();
799     const VkDevice device                 = context.getDevice();
800     const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
801     Allocator &allocator                  = context.getDefaultAllocator();
802     vk::BinaryCollection &collection      = context.getBinaryCollection();
803     VkShaderStageFlags shaders            = static_cast<VkShaderStageFlags>(0);
804     uint32_t shaderCount                  = 0;
805 
806     VkPhysicalDeviceFeatures features;
807     vki.getPhysicalDeviceFeatures(physicalDevice, &features);
808     const bool pointSizeRequired = features.shaderTessellationAndGeometryPointSize;
809 
810     if (collection.contains("vert"))
811         shaders |= VK_SHADER_STAGE_VERTEX_BIT;
812     if (collection.contains(getGeomName(pointSizeRequired)))
813         shaders |= VK_SHADER_STAGE_GEOMETRY_BIT;
814     if (collection.contains("tesc"))
815         shaders |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
816     if (collection.contains("tese"))
817         shaders |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
818     if (collection.contains("frag"))
819         shaders |= VK_SHADER_STAGE_FRAGMENT_BIT;
820 
821     for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
822         shaderCount++;
823 
824     if (collection.contains(getGeomName(!pointSizeRequired)))
825         --shaderCount;
826 
827     if (shaderCount != (uint32_t)dePop32(shaders))
828         TCU_THROW(InternalError, "Unused shaders detected in the collection");
829 
830     if (0 != (shaders & VK_SHADER_STAGE_VERTEX_BIT))
831         m_vertShaderModule = createShaderModule(vkd, device, collection.get("vert"), 0);
832     if (0 != (shaders & VK_SHADER_STAGE_GEOMETRY_BIT))
833         m_geomShaderModule = createShaderModule(vkd, device, collection.get(getGeomName(pointSizeRequired)), 0);
834     if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT))
835         m_tescShaderModule = createShaderModule(vkd, device, collection.get("tesc"), 0);
836     if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
837         m_teseShaderModule = createShaderModule(vkd, device, collection.get("tese"), 0);
838     if (0 != (shaders & VK_SHADER_STAGE_FRAGMENT_BIT))
839         m_fragShaderModule = createShaderModule(vkd, device, collection.get("frag"), 0);
840 
841     m_descriptorSetLayout =
842         DescriptorSetLayoutBuilder()
843             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL_GRAPHICS)
844             .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL_GRAPHICS)
845             .build(vkd, device);
846     m_descriptorPool = DescriptorPoolBuilder()
847                            .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
848                            .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
849                            .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
850     m_descriptorSet         = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
851     m_framebufferImage      = makeImage(vkd, device,
852                                         makeImageCreateInfo(m_framebufferFormat, testParams.width, testParams.height, 1u,
853                                                             VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
854     m_framebufferImageAlloc = bindImage(vkd, device, allocator, *m_framebufferImage, MemoryRequirement::Any);
855     m_framebufferAttachment =
856         makeImageView(vkd, device, *m_framebufferImage, VK_IMAGE_VIEW_TYPE_2D, m_framebufferFormat,
857                       makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
858     m_renderPass = makeRenderPass(vkd, device, m_framebufferFormat);
859     m_framebuffer =
860         makeFramebuffer(vkd, device, *m_renderPass, *m_framebufferAttachment, testParams.width, testParams.height);
861     m_pipelineLayout = makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
862     m_pipeline       = makeGraphicsPipeline(context, testParams);
863 
864     initVertexBuffer(context, testParams);
865 }
866 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer cmdBuffer,const VkAccelerationStructureKHR * rayQueryTopAccelerationStructurePtr,const VkDescriptorImageInfo & resultImageInfo)867 void GraphicsConfiguration::fillCommandBuffer(Context &context, TestParams &testParams, VkCommandBuffer cmdBuffer,
868                                               const VkAccelerationStructureKHR *rayQueryTopAccelerationStructurePtr,
869                                               const VkDescriptorImageInfo &resultImageInfo)
870 {
871     const DeviceInterface &vkd            = context.getDeviceInterface();
872     const VkDevice device                 = context.getDevice();
873     const VkDeviceSize vertexBufferOffset = 0;
874     const VkWriteDescriptorSetAccelerationStructureKHR rayQueryAccelerationStructureWriteDescriptorSet = {
875         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, //  VkStructureType sType;
876         DE_NULL,                                                           //  const void* pNext;
877         1u,                                                                //  uint32_t accelerationStructureCount;
878         rayQueryTopAccelerationStructurePtr, //  const VkAccelerationStructureKHR* pAccelerationStructures;
879     };
880 
881     DescriptorSetUpdateBuilder()
882         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
883                      VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
884         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
885                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
886         .update(vkd, device);
887 
888     vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1,
889                               &m_descriptorSet.get(), 0, DE_NULL);
890     vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
891     vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
892 
893     beginRenderPass(vkd, cmdBuffer, *m_renderPass, *m_framebuffer,
894                     makeRect2D(0, 0, testParams.width, testParams.height), tcu::UVec4());
895 
896     vkd.cmdDraw(cmdBuffer, m_vertexCount, 1u, 0u, 0u);
897 
898     endRenderPass(vkd, cmdBuffer);
899 }
900 
901 class ComputeConfiguration : public PipelineConfiguration
902 {
903 public:
904     ComputeConfiguration();
~ComputeConfiguration()905     virtual ~ComputeConfiguration()
906     {
907     }
908 
909     static void checkSupport(Context &context, const TestParams &testParams);
910     static void initPrograms(SourceCollections &programCollection, const TestParams &testParams);
911 
912     virtual void initConfiguration(Context &context, TestParams &testParams) override;
913     virtual void fillCommandBuffer(Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
914                                    const VkAccelerationStructureKHR *rayQueryTopAccelerationStructurePtr,
915                                    const VkDescriptorImageInfo &resultImageInfo) override;
916 
917 protected:
918     Move<VkDescriptorSetLayout> m_descriptorSetLayout;
919     Move<VkDescriptorPool> m_descriptorPool;
920     Move<VkDescriptorSet> m_descriptorSet;
921     Move<VkPipelineLayout> m_pipelineLayout;
922 
923     Move<VkShaderModule> m_shaderModule;
924 
925     Move<VkPipeline> m_pipeline;
926 };
927 
ComputeConfiguration()928 ComputeConfiguration::ComputeConfiguration()
929     : PipelineConfiguration()
930     , m_descriptorSetLayout()
931     , m_descriptorPool()
932     , m_descriptorSet()
933     , m_pipelineLayout()
934 
935     , m_shaderModule()
936 
937     , m_pipeline()
938 {
939 }
940 
checkSupport(Context & context,const TestParams & testParams)941 void ComputeConfiguration::checkSupport(Context &context, const TestParams &testParams)
942 {
943     DE_UNREF(context);
944     DE_UNREF(testParams);
945 }
946 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)947 void ComputeConfiguration::initPrograms(SourceCollections &programCollection, const TestParams &testParams)
948 {
949     const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
950     const std::string testShaderBody = testParams.testConfigShaderBodyText(testParams);
951     const std::string testBody       = "  ivec3       pos      = ivec3(gl_WorkGroupID);\n"
952                                        "  ivec3       size     = ivec3(gl_NumWorkGroups);\n" +
953                                  testShaderBody;
954 
955     switch (testParams.stage)
956     {
957     case VK_SHADER_STAGE_COMPUTE_BIT:
958     {
959         std::stringstream css;
960         css << "#version 460 core\n"
961                "#extension GL_EXT_ray_query : require\n"
962                "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
963                "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
964                "\n"
965                "void main()\n"
966                "{\n"
967             << testBody << "}\n";
968 
969         programCollection.glslSources.add("comp")
970             << glu::ComputeSource(updateRayTracingGLSL(css.str())) << buildOptions;
971 
972         break;
973     }
974 
975     default:
976         TCU_THROW(InternalError, "Unknown stage");
977     }
978 }
979 
initConfiguration(Context & context,TestParams & testParams)980 void ComputeConfiguration::initConfiguration(Context &context, TestParams &testParams)
981 {
982     DE_UNREF(testParams);
983 
984     const DeviceInterface &vkd       = context.getDeviceInterface();
985     const VkDevice device            = context.getDevice();
986     vk::BinaryCollection &collection = context.getBinaryCollection();
987 
988     m_descriptorSetLayout =
989         DescriptorSetLayoutBuilder()
990             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
991             .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_COMPUTE_BIT)
992             .build(vkd, device);
993     m_descriptorPool = DescriptorPoolBuilder()
994                            .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
995                            .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
996                            .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
997     m_descriptorSet  = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
998     m_pipelineLayout = makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
999     m_shaderModule   = createShaderModule(vkd, device, collection.get("comp"), 0);
1000     m_pipeline       = makeComputePipeline(vkd, device, *m_pipelineLayout, *m_shaderModule);
1001 }
1002 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer cmdBuffer,const VkAccelerationStructureKHR * rayQueryTopAccelerationStructurePtr,const VkDescriptorImageInfo & resultImageInfo)1003 void ComputeConfiguration::fillCommandBuffer(Context &context, TestParams &testParams, VkCommandBuffer cmdBuffer,
1004                                              const VkAccelerationStructureKHR *rayQueryTopAccelerationStructurePtr,
1005                                              const VkDescriptorImageInfo &resultImageInfo)
1006 {
1007     const DeviceInterface &vkd = context.getDeviceInterface();
1008     const VkDevice device      = context.getDevice();
1009     const VkWriteDescriptorSetAccelerationStructureKHR rayQueryAccelerationStructureWriteDescriptorSet = {
1010         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, //  VkStructureType sType;
1011         DE_NULL,                                                           //  const void* pNext;
1012         1u,                                                                //  uint32_t accelerationStructureCount;
1013         rayQueryTopAccelerationStructurePtr, //  const VkAccelerationStructureKHR* pAccelerationStructures;
1014     };
1015 
1016     DescriptorSetUpdateBuilder()
1017         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
1018                      VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
1019         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
1020                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
1021         .update(vkd, device);
1022 
1023     vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1,
1024                               &m_descriptorSet.get(), 0, DE_NULL);
1025 
1026     vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline.get());
1027 
1028     vkd.cmdDispatch(cmdBuffer, testParams.width, testParams.height, 1);
1029 }
1030 
1031 class RayTracingConfiguration : public PipelineConfiguration
1032 {
1033 public:
1034     RayTracingConfiguration();
~RayTracingConfiguration()1035     virtual ~RayTracingConfiguration()
1036     {
1037     }
1038 
1039     static void checkSupport(Context &context, const TestParams &testParams);
1040     static void initPrograms(SourceCollections &programCollection, const TestParams &testParams);
1041 
1042     virtual void initConfiguration(Context &context, TestParams &testParams) override;
1043     virtual void fillCommandBuffer(Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
1044                                    const VkAccelerationStructureKHR *rayQueryTopAccelerationStructurePtr,
1045                                    const VkDescriptorImageInfo &resultImageInfo) override;
1046 
1047 protected:
1048     de::MovePtr<BufferWithMemory> createShaderBindingTable(const InstanceInterface &vki, const DeviceInterface &vkd,
1049                                                            const VkDevice device, const VkPhysicalDevice physicalDevice,
1050                                                            const VkPipeline pipeline, Allocator &allocator,
1051                                                            de::MovePtr<RayTracingPipeline> &rayTracingPipeline,
1052                                                            const uint32_t group);
1053 
1054 protected:
1055     uint32_t m_shaders;
1056     uint32_t m_raygenShaderGroup;
1057     uint32_t m_missShaderGroup;
1058     uint32_t m_hitShaderGroup;
1059     uint32_t m_callableShaderGroup;
1060     uint32_t m_shaderGroupCount;
1061 
1062     Move<VkDescriptorSetLayout> m_descriptorSetLayout;
1063     Move<VkDescriptorPool> m_descriptorPool;
1064     Move<VkDescriptorSet> m_descriptorSet;
1065     Move<VkPipelineLayout> m_pipelineLayout;
1066 
1067     de::MovePtr<RayTracingPipeline> m_rayTracingPipeline;
1068     Move<VkPipeline> m_pipeline;
1069 
1070     de::MovePtr<BufferWithMemory> m_raygenShaderBindingTable;
1071     de::MovePtr<BufferWithMemory> m_hitShaderBindingTable;
1072     de::MovePtr<BufferWithMemory> m_missShaderBindingTable;
1073     de::MovePtr<BufferWithMemory> m_callableShaderBindingTable;
1074 
1075     VkStridedDeviceAddressRegionKHR m_raygenShaderBindingTableRegion;
1076     VkStridedDeviceAddressRegionKHR m_missShaderBindingTableRegion;
1077     VkStridedDeviceAddressRegionKHR m_hitShaderBindingTableRegion;
1078     VkStridedDeviceAddressRegionKHR m_callableShaderBindingTableRegion;
1079 
1080     de::SharedPtr<BottomLevelAccelerationStructure> m_bottomLevelAccelerationStructure;
1081     de::SharedPtr<TopLevelAccelerationStructure> m_topLevelAccelerationStructure;
1082 };
1083 
RayTracingConfiguration()1084 RayTracingConfiguration::RayTracingConfiguration()
1085     : m_shaders(0)
1086     , m_raygenShaderGroup(~0u)
1087     , m_missShaderGroup(~0u)
1088     , m_hitShaderGroup(~0u)
1089     , m_callableShaderGroup(~0u)
1090     , m_shaderGroupCount(0)
1091 
1092     , m_descriptorSetLayout()
1093     , m_descriptorPool()
1094     , m_descriptorSet()
1095     , m_pipelineLayout()
1096 
1097     , m_rayTracingPipeline()
1098     , m_pipeline()
1099 
1100     , m_raygenShaderBindingTable()
1101     , m_hitShaderBindingTable()
1102     , m_missShaderBindingTable()
1103     , m_callableShaderBindingTable()
1104 
1105     , m_raygenShaderBindingTableRegion()
1106     , m_missShaderBindingTableRegion()
1107     , m_hitShaderBindingTableRegion()
1108     , m_callableShaderBindingTableRegion()
1109 
1110     , m_bottomLevelAccelerationStructure()
1111     , m_topLevelAccelerationStructure()
1112 {
1113 }
1114 
checkSupport(Context & context,const TestParams & testParams)1115 void RayTracingConfiguration::checkSupport(Context &context, const TestParams &testParams)
1116 {
1117     DE_UNREF(testParams);
1118 
1119     context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1120     const VkPhysicalDeviceRayTracingPipelineFeaturesKHR &rayTracingPipelineFeaturesKHR =
1121         context.getRayTracingPipelineFeatures();
1122     if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == false)
1123         TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1124 }
1125 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)1126 void RayTracingConfiguration::initPrograms(SourceCollections &programCollection, const TestParams &testParams)
1127 {
1128     const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1129 
1130     const std::string testShaderBody = testParams.testConfigShaderBodyText(testParams);
1131     const std::string testBody       = "  ivec3       pos      = ivec3(gl_LaunchIDEXT);\n"
1132                                        "  ivec3       size     = ivec3(gl_LaunchSizeEXT);\n" +
1133                                  testShaderBody;
1134 
1135     switch (testParams.stage)
1136     {
1137     case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
1138     {
1139         std::stringstream css;
1140         css << "#version 460 core\n"
1141                "#extension GL_EXT_ray_tracing : require\n"
1142                "#extension GL_EXT_ray_query : require\n"
1143                "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1144                "layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1145                "\n"
1146                "void main()\n"
1147                "{\n"
1148             << testBody << "}\n";
1149 
1150         programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1151 
1152         break;
1153     }
1154 
1155     case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
1156     {
1157         programCollection.glslSources.add("rgen")
1158             << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1159 
1160         {
1161             std::stringstream css;
1162             css << "#version 460 core\n"
1163                    "#extension GL_EXT_ray_tracing : require\n"
1164                    "#extension GL_EXT_ray_query : require\n"
1165                    "hitAttributeEXT vec3 attribs;\n"
1166                    "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1167                    "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1168                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT "
1169                    "rayQueryTopLevelAccelerationStructure;\n"
1170                    "\n"
1171                    "void main()\n"
1172                    "{\n"
1173                 << testBody << "}\n";
1174 
1175             programCollection.glslSources.add("ahit")
1176                 << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1177         }
1178 
1179         programCollection.glslSources.add("chit")
1180             << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1181         programCollection.glslSources.add("miss")
1182             << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1183 
1184         break;
1185     }
1186 
1187     case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
1188     {
1189         programCollection.glslSources.add("rgen")
1190             << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1191 
1192         {
1193             std::stringstream css;
1194             css << "#version 460 core\n"
1195                    "#extension GL_EXT_ray_tracing : require\n"
1196                    "#extension GL_EXT_ray_query : require\n"
1197                    "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1198                    "hitAttributeEXT vec3 attribs;\n"
1199                    "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1200                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT "
1201                    "rayQueryTopLevelAccelerationStructure;\n"
1202                    "\n"
1203                    "void main()\n"
1204                    "{\n"
1205                 << testBody << "}\n";
1206 
1207             programCollection.glslSources.add("chit")
1208                 << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1209         }
1210 
1211         programCollection.glslSources.add("ahit")
1212             << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1213         programCollection.glslSources.add("miss")
1214             << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1215 
1216         break;
1217     }
1218 
1219     case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
1220     {
1221         programCollection.glslSources.add("rgen")
1222             << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1223 
1224         {
1225             std::stringstream css;
1226             css << "#version 460 core\n"
1227                    "#extension GL_EXT_ray_tracing : require\n"
1228                    "#extension GL_EXT_ray_query : require\n"
1229                    "hitAttributeEXT vec3 hitAttribute;\n"
1230                    "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1231                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT "
1232                    "rayQueryTopLevelAccelerationStructure;\n"
1233                    "\n"
1234                    "void main()\n"
1235                    "{\n"
1236                 << testBody
1237                 << "  hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n"
1238                    "  reportIntersectionEXT(1.0f, 0);\n"
1239                    "}\n";
1240 
1241             programCollection.glslSources.add("sect")
1242                 << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1243         }
1244 
1245         programCollection.glslSources.add("ahit")
1246             << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1247         programCollection.glslSources.add("chit")
1248             << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1249         programCollection.glslSources.add("miss")
1250             << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1251 
1252         break;
1253     }
1254 
1255     case VK_SHADER_STAGE_MISS_BIT_KHR:
1256     {
1257         programCollection.glslSources.add("rgen")
1258             << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1259 
1260         {
1261             std::stringstream css;
1262             css << "#version 460 core\n"
1263                    "#extension GL_EXT_ray_tracing : require\n"
1264                    "#extension GL_EXT_ray_query : require\n"
1265                    "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1266                    "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1267                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT "
1268                    "rayQueryTopLevelAccelerationStructure;\n"
1269                    "\n"
1270                    "void main()\n"
1271                    "{\n"
1272                 << testBody << "}\n";
1273 
1274             programCollection.glslSources.add("miss")
1275                 << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1276         }
1277 
1278         programCollection.glslSources.add("ahit")
1279             << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1280         programCollection.glslSources.add("chit")
1281             << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1282 
1283         break;
1284     }
1285 
1286     case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
1287     {
1288         {
1289             std::stringstream css;
1290             css << "#version 460 core\n"
1291                    "#extension GL_EXT_ray_tracing : require\n"
1292                    "#extension GL_EXT_ray_query : require\n"
1293                    "layout(location = 0) callableDataEXT float dummy;"
1294                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1295                    "\n"
1296                    "void main()\n"
1297                    "{\n"
1298                    "  executeCallableEXT(0, 0);\n"
1299                    "}\n";
1300 
1301             programCollection.glslSources.add("rgen")
1302                 << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1303         }
1304 
1305         {
1306             std::stringstream css;
1307             css << "#version 460 core\n"
1308                    "#extension GL_EXT_ray_tracing : require\n"
1309                    "#extension GL_EXT_ray_query : require\n"
1310                    "layout(location = 0) callableDataInEXT float dummy;"
1311                    "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1312                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT "
1313                    "rayQueryTopLevelAccelerationStructure;\n"
1314                    "\n"
1315                    "void main()\n"
1316                    "{\n"
1317                 << testBody << "}\n";
1318 
1319             programCollection.glslSources.add("call")
1320                 << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
1321         }
1322 
1323         programCollection.glslSources.add("ahit")
1324             << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1325         programCollection.glslSources.add("chit")
1326             << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1327         programCollection.glslSources.add("miss")
1328             << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1329 
1330         break;
1331     }
1332 
1333     default:
1334         TCU_THROW(InternalError, "Unknown stage");
1335     }
1336 }
1337 
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)1338 de::MovePtr<BufferWithMemory> RayTracingConfiguration::createShaderBindingTable(
1339     const InstanceInterface &vki, const DeviceInterface &vkd, const VkDevice device,
1340     const VkPhysicalDevice physicalDevice, const VkPipeline pipeline, Allocator &allocator,
1341     de::MovePtr<RayTracingPipeline> &rayTracingPipeline, const uint32_t group)
1342 {
1343     de::MovePtr<BufferWithMemory> shaderBindingTable;
1344 
1345     if (group < m_shaderGroupCount)
1346     {
1347         const uint32_t shaderGroupHandleSize    = getShaderGroupHandleSize(vki, physicalDevice);
1348         const uint32_t shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice);
1349 
1350         shaderBindingTable = rayTracingPipeline->createShaderBindingTable(
1351             vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, group, 1u);
1352     }
1353 
1354     return shaderBindingTable;
1355 }
1356 
initConfiguration(Context & context,TestParams & testParams)1357 void RayTracingConfiguration::initConfiguration(Context &context, TestParams &testParams)
1358 {
1359     DE_UNREF(testParams);
1360 
1361     const InstanceInterface &vki          = context.getInstanceInterface();
1362     const DeviceInterface &vkd            = context.getDeviceInterface();
1363     const VkDevice device                 = context.getDevice();
1364     const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1365     vk::BinaryCollection &collection      = context.getBinaryCollection();
1366     Allocator &allocator                  = context.getDefaultAllocator();
1367     const uint32_t shaderGroupHandleSize  = getShaderGroupHandleSize(vki, physicalDevice);
1368     const VkShaderStageFlags hitStages =
1369         VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
1370     uint32_t shaderCount = 0;
1371 
1372     m_shaderGroupCount = 0;
1373 
1374     if (collection.contains("rgen"))
1375         m_shaders |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
1376     if (collection.contains("ahit"))
1377         m_shaders |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
1378     if (collection.contains("chit"))
1379         m_shaders |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
1380     if (collection.contains("miss"))
1381         m_shaders |= VK_SHADER_STAGE_MISS_BIT_KHR;
1382     if (collection.contains("sect"))
1383         m_shaders |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
1384     if (collection.contains("call"))
1385         m_shaders |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
1386 
1387     for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
1388         shaderCount++;
1389 
1390     if (shaderCount != (uint32_t)dePop32(m_shaders))
1391         TCU_THROW(InternalError, "Unused shaders detected in the collection");
1392 
1393     if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))
1394         m_raygenShaderGroup = m_shaderGroupCount++;
1395 
1396     if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))
1397         m_missShaderGroup = m_shaderGroupCount++;
1398 
1399     if (0 != (m_shaders & hitStages))
1400         m_hitShaderGroup = m_shaderGroupCount++;
1401 
1402     if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))
1403         m_callableShaderGroup = m_shaderGroupCount++;
1404 
1405     m_rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
1406 
1407     m_descriptorSetLayout = DescriptorSetLayoutBuilder()
1408                                 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
1409                                 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1410                                 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1411                                 .build(vkd, device);
1412     m_descriptorPool = DescriptorPoolBuilder()
1413                            .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1414                            .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1415                            .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1416                            .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1417     m_descriptorSet = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
1418 
1419     if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))
1420         m_rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR,
1421                                         createShaderModule(vkd, device, collection.get("rgen"), 0),
1422                                         m_raygenShaderGroup);
1423     if (0 != (m_shaders & VK_SHADER_STAGE_ANY_HIT_BIT_KHR))
1424         m_rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR,
1425                                         createShaderModule(vkd, device, collection.get("ahit"), 0), m_hitShaderGroup);
1426     if (0 != (m_shaders & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR))
1427         m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,
1428                                         createShaderModule(vkd, device, collection.get("chit"), 0), m_hitShaderGroup);
1429     if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))
1430         m_rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR,
1431                                         createShaderModule(vkd, device, collection.get("miss"), 0), m_missShaderGroup);
1432     if (0 != (m_shaders & VK_SHADER_STAGE_INTERSECTION_BIT_KHR))
1433         m_rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR,
1434                                         createShaderModule(vkd, device, collection.get("sect"), 0), m_hitShaderGroup);
1435     if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))
1436         m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR,
1437                                         createShaderModule(vkd, device, collection.get("call"), 0),
1438                                         m_callableShaderGroup);
1439 
1440     m_pipelineLayout = makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
1441     m_pipeline       = m_rayTracingPipeline->createPipeline(vkd, device, *m_pipelineLayout);
1442 
1443     m_raygenShaderBindingTable   = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator,
1444                                                             m_rayTracingPipeline, m_raygenShaderGroup);
1445     m_missShaderBindingTable     = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator,
1446                                                             m_rayTracingPipeline, m_missShaderGroup);
1447     m_hitShaderBindingTable      = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator,
1448                                                             m_rayTracingPipeline, m_hitShaderGroup);
1449     m_callableShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator,
1450                                                             m_rayTracingPipeline, m_callableShaderGroup);
1451 
1452     m_raygenShaderBindingTableRegion =
1453         makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_raygenShaderBindingTable), shaderGroupHandleSize);
1454     m_missShaderBindingTableRegion =
1455         makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_missShaderBindingTable), shaderGroupHandleSize);
1456     m_hitShaderBindingTableRegion =
1457         makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_hitShaderBindingTable), shaderGroupHandleSize);
1458     m_callableShaderBindingTableRegion =
1459         makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_callableShaderBindingTable), shaderGroupHandleSize);
1460 }
1461 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkAccelerationStructureKHR * rayQueryTopAccelerationStructurePtr,const VkDescriptorImageInfo & resultImageInfo)1462 void RayTracingConfiguration::fillCommandBuffer(Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
1463                                                 const VkAccelerationStructureKHR *rayQueryTopAccelerationStructurePtr,
1464                                                 const VkDescriptorImageInfo &resultImageInfo)
1465 {
1466     const DeviceInterface &vkd = context.getDeviceInterface();
1467     const VkDevice device      = context.getDevice();
1468     Allocator &allocator       = context.getDefaultAllocator();
1469     de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure =
1470         makeBottomLevelAccelerationStructure();
1471     de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1472 
1473     m_bottomLevelAccelerationStructure =
1474         de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release());
1475     m_bottomLevelAccelerationStructure->setDefaultGeometryData(testParams.stage);
1476     m_bottomLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1477 
1478     m_topLevelAccelerationStructure =
1479         de::SharedPtr<TopLevelAccelerationStructure>(topLevelAccelerationStructure.release());
1480     m_topLevelAccelerationStructure->setInstanceCount(1);
1481     m_topLevelAccelerationStructure->addInstance(m_bottomLevelAccelerationStructure);
1482     m_topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1483 
1484     const TopLevelAccelerationStructure *topLevelAccelerationStructurePtr = m_topLevelAccelerationStructure.get();
1485     const VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = {
1486         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, //  VkStructureType sType;
1487         DE_NULL,                                                           //  const void* pNext;
1488         1u,                                                                //  uint32_t accelerationStructureCount;
1489         topLevelAccelerationStructurePtr->getPtr(), //  const VkAccelerationStructureKHR* pAccelerationStructures;
1490     };
1491     const VkWriteDescriptorSetAccelerationStructureKHR rayQueryAccelerationStructureWriteDescriptorSet = {
1492         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, //  VkStructureType sType;
1493         DE_NULL,                                                           //  const void* pNext;
1494         1u,                                                                //  uint32_t accelerationStructureCount;
1495         rayQueryTopAccelerationStructurePtr, //  const VkAccelerationStructureKHR* pAccelerationStructures;
1496     };
1497 
1498     DescriptorSetUpdateBuilder()
1499         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
1500                      VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
1501         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
1502                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1503         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u),
1504                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
1505         .update(vkd, device);
1506 
1507     vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *m_pipelineLayout, 0, 1,
1508                               &m_descriptorSet.get(), 0, DE_NULL);
1509 
1510     vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, m_pipeline.get());
1511 
1512     cmdTraceRays(vkd, commandBuffer, &m_raygenShaderBindingTableRegion, &m_missShaderBindingTableRegion,
1513                  &m_hitShaderBindingTableRegion, &m_callableShaderBindingTableRegion, testParams.width,
1514                  testParams.height, 1);
1515 }
1516 
getShaderBodyText(const TestParams & testParams)1517 const std::string getShaderBodyText(const TestParams &testParams)
1518 {
1519     if (testParams.geomType == GEOM_TYPE_AABBS)
1520     {
1521         const std::string result =
1522             "  uint        rayFlags = 0;\n"
1523             "  uint        cullMask = 0xFF;\n"
1524             "  float       tmin     = 0.0;\n"
1525             "  float       tmax     = 9.0;\n"
1526             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
1527             "float(size.y), 0.0);\n"
1528             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
1529             "  uint        count    = 0;\n"
1530             "  rayQueryEXT rayQuery;\n"
1531             "\n"
1532             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
1533             "tmin, direct, tmax);\n"
1534             "\n"
1535             "  while(rayQueryProceedEXT(rayQuery))\n"
1536             "  {\n"
1537             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
1538             "    {\n"
1539             "      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n"
1540             "      count++;\n"
1541             "    }\n"
1542             "  }\n"
1543             "  imageStore(result, pos, ivec4(count, 0, 0, 0));\n"
1544             "\n";
1545 
1546         return result;
1547     }
1548     else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
1549     {
1550         const std::string result =
1551             "  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
1552             "  uint        cullMask = 0xFF;\n"
1553             "  float       tmin     = 0.0;\n"
1554             "  float       tmax     = 9.0;\n"
1555             "  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / "
1556             "float(size.y), 0.0);\n"
1557             "  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
1558             "  uint        count    = 0;\n"
1559             "  rayQueryEXT rayQuery;\n"
1560             "\n"
1561             "  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, "
1562             "tmin, direct, tmax);\n"
1563             "\n"
1564             "  while(rayQueryProceedEXT(rayQuery))\n"
1565             "  {\n"
1566             "    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
1567             "    {\n"
1568             "      rayQueryConfirmIntersectionEXT(rayQuery);\n"
1569             "      count++;\n"
1570             "    }\n"
1571             "  }\n"
1572             "  imageStore(result, pos, ivec4(count, 0, 0, 0));\n"
1573             "\n";
1574 
1575         return result;
1576     }
1577     else
1578     {
1579         TCU_THROW(InternalError, "Unknown geometry type");
1580     }
1581 }
1582 
1583 class TestConfigurationNoMiss : public TestConfiguration
1584 {
1585 public:
1586     virtual const VkAccelerationStructureKHR *initAccelerationStructures(Context &context, TestParams &testParams,
1587                                                                          VkCommandBuffer cmdBuffer) override;
1588 
1589     virtual bool verify(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams) override;
1590 
1591 private:
1592     uint32_t chooseAABB(de::Random &rng, const std::vector<tcu::Vec2> &vertices, const std::vector<tcu::UVec2> &aabbs);
1593     uint32_t chooseTriangle(de::Random &rng, const std::vector<tcu::Vec2> &vertices,
1594                             const std::vector<tcu::UVec3> &triangles);
1595 };
1596 
chooseAABB(de::Random & rng,const std::vector<tcu::Vec2> & vertices,const std::vector<tcu::UVec2> & aabbs)1597 uint32_t TestConfigurationNoMiss::chooseAABB(de::Random &rng, const std::vector<tcu::Vec2> &vertices,
1598                                              const std::vector<tcu::UVec2> &aabbs)
1599 {
1600     while (true)
1601     {
1602         const uint32_t n    = (uint32_t)rng.getInt(0, (uint32_t)aabbs.size() - 1);
1603         const tcu::UVec2 &t = aabbs[n];
1604         const tcu::Vec2 &a  = vertices[t.x()];
1605         const tcu::Vec2 &b  = vertices[t.y()];
1606 
1607         if (deFloatAbs(a.x() - b.x()) < MIN_AABB_SIDE_LENGTH || deFloatAbs(a.y() - b.y()) < MIN_AABB_SIDE_LENGTH)
1608             continue;
1609 
1610         return n;
1611     }
1612 }
1613 
chooseTriangle(de::Random & rng,const std::vector<tcu::Vec2> & vertices,const std::vector<tcu::UVec3> & triangles)1614 uint32_t TestConfigurationNoMiss::chooseTriangle(de::Random &rng, const std::vector<tcu::Vec2> &vertices,
1615                                                  const std::vector<tcu::UVec3> &triangles)
1616 {
1617     while (true)
1618     {
1619         const uint32_t n    = (uint32_t)rng.getInt(0, (uint32_t)triangles.size() - 1);
1620         const tcu::UVec3 &t = triangles[n];
1621         const tcu::Vec2 &a  = vertices[t.x()];
1622         const tcu::Vec2 &b  = vertices[t.y()];
1623         const tcu::Vec2 &c  = vertices[t.z()];
1624         const float ab      = triangleEdgeLength(a, b);
1625         const float bc      = triangleEdgeLength(b, c);
1626         const float ca      = triangleEdgeLength(c, a);
1627 
1628         if (ab < MIN_TRIANGLE_EDGE_LENGTH || bc < MIN_TRIANGLE_EDGE_LENGTH || ca < MIN_TRIANGLE_EDGE_LENGTH ||
1629             triangleArea(ab, bc, ca) < MIN_TRIANGLE_AREA_SIZE)
1630             continue;
1631 
1632         return n;
1633     }
1634 }
1635 
initAccelerationStructures(Context & context,TestParams & testParams,VkCommandBuffer cmdBuffer)1636 const VkAccelerationStructureKHR *TestConfigurationNoMiss::initAccelerationStructures(Context &context,
1637                                                                                       TestParams &testParams,
1638                                                                                       VkCommandBuffer cmdBuffer)
1639 {
1640     const DeviceInterface &vkd = context.getDeviceInterface();
1641     const VkDevice device      = context.getDevice();
1642     Allocator &allocator       = context.getDefaultAllocator();
1643     const tcu::Vec2 centerPixelCenter =
1644         tcu::Vec2(0.5f - 0.5f / float(testParams.width), 0.5f - 0.5f / float(testParams.height));
1645     de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure =
1646         makeBottomLevelAccelerationStructure();
1647     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure =
1648         makeTopLevelAccelerationStructure();
1649     de::Random rng(testParams.randomSeed);
1650     std::vector<tcu::Vec3> geometryData;
1651 
1652     if (testParams.geomType == GEOM_TYPE_AABBS)
1653     {
1654         std::vector<tcu::UVec2> aabbs;
1655         std::vector<tcu::Vec2> vertices;
1656 
1657         vertices.reserve(2u * testParams.squaresGroupCount);
1658         aabbs.reserve(testParams.squaresGroupCount);
1659 
1660         {
1661             // a---g---+
1662             // |   |   |
1663             // e---d---h
1664             // |   |   |
1665             // +---f---b
1666             //
1667             // a-d, d-b, e-f, g-h
1668 
1669             const tcu::Vec2 d = centerPixelCenter;
1670             const tcu::Vec2 a = tcu::Vec2(0.0f, 0.0f);
1671             const tcu::Vec2 b = tcu::Vec2(1.0f, 1.0f);
1672             const tcu::Vec2 e = tcu::Vec2(a.x(), d.y());
1673             const tcu::Vec2 f = tcu::Vec2(d.x(), b.y());
1674             const tcu::Vec2 g = tcu::Vec2(d.x(), a.y());
1675             const tcu::Vec2 h = tcu::Vec2(b.x(), d.y());
1676             const uint32_t A  = 0;
1677             const uint32_t B  = 1;
1678             const uint32_t D  = 2;
1679             const uint32_t E  = 3;
1680             const uint32_t F  = 4;
1681             const uint32_t G  = 5;
1682             const uint32_t H  = 6;
1683 
1684             vertices.push_back(a);
1685             vertices.push_back(b);
1686             vertices.push_back(d);
1687             vertices.push_back(e);
1688             vertices.push_back(f);
1689             vertices.push_back(g);
1690             vertices.push_back(h);
1691 
1692             aabbs.push_back(tcu::UVec2(A, D));
1693             aabbs.push_back(tcu::UVec2(D, B));
1694             aabbs.push_back(tcu::UVec2(E, F));
1695             aabbs.push_back(tcu::UVec2(G, H));
1696         }
1697 
1698         while (aabbs.size() < testParams.squaresGroupCount)
1699         {
1700             // a-------+      a---g---+
1701             // |       |      |   |   |
1702             // |       |  ->  e---d---h
1703             // |       |      |   |   |
1704             // +-------b      +---f---b
1705             //
1706             // a-b        ->  a-d, d-b, e-f, g-h
1707 
1708             const uint32_t n   = chooseAABB(rng, vertices, aabbs);
1709             tcu::UVec2 &t      = aabbs[n];
1710             const tcu::Vec2 &a = vertices[t.x()];
1711             const tcu::Vec2 &b = vertices[t.y()];
1712             const float alfa   = rng.getFloat(0.2f, 0.8f);
1713             const float beta   = rng.getFloat(0.2f, 0.8f);
1714             const tcu::Vec2 d  = mixCoordsVec2(a, b, alfa, beta);
1715             const tcu::Vec2 e  = tcu::Vec2(a.x(), d.y());
1716             const tcu::Vec2 f  = tcu::Vec2(d.x(), b.y());
1717             const tcu::Vec2 g  = tcu::Vec2(d.x(), a.y());
1718             const tcu::Vec2 h  = tcu::Vec2(b.x(), d.y());
1719             const uint32_t B   = t.y();
1720             const uint32_t D   = (uint32_t)vertices.size();
1721             const uint32_t E   = D + 1;
1722             const uint32_t F   = D + 2;
1723             const uint32_t G   = D + 3;
1724             const uint32_t H   = D + 4;
1725 
1726             if (d.x() <= a.x() || d.x() >= b.x() || d.y() <= a.y() || d.y() >= b.y())
1727                 continue;
1728 
1729             vertices.push_back(d);
1730             vertices.push_back(e);
1731             vertices.push_back(f);
1732             vertices.push_back(g);
1733             vertices.push_back(h);
1734 
1735             t.y() = D;
1736             aabbs.push_back(tcu::UVec2(D, B));
1737             aabbs.push_back(tcu::UVec2(E, F));
1738             aabbs.push_back(tcu::UVec2(G, H));
1739         }
1740 
1741         geometryData.reserve(2u * aabbs.size());
1742 
1743         for (size_t i = 0; i < aabbs.size(); ++i)
1744         {
1745             const tcu::Vec2 &a = vertices[aabbs[i].x()];
1746             const tcu::Vec2 &b = vertices[aabbs[i].y()];
1747             const float az     = -rng.getFloat(0.1f, 0.5f);
1748             const float bz     = az + 0.01f;
1749             const tcu::Vec3 A  = tcu::Vec3(a.x(), a.y(), az);
1750             const tcu::Vec3 B  = tcu::Vec3(b.x(), b.y(), bz);
1751 
1752             geometryData.push_back(A);
1753             geometryData.push_back(B);
1754         }
1755     }
1756     else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
1757     {
1758         std::vector<tcu::UVec3> triangles;
1759         std::vector<tcu::Vec2> vertices;
1760         std::vector<float> verticesZ;
1761 
1762         vertices.reserve(3u * testParams.squaresGroupCount);
1763         triangles.reserve(testParams.squaresGroupCount);
1764 
1765         {
1766             // Initial triangle set: aeb, bec, cef, fei, ieh, heg, ged, dea
1767             // e - is not math middle, but centrum of one of the pixels
1768             // a---b---c
1769             // | \ | / |
1770             // d---e---f
1771             // | / | \ |
1772             // g---h---i
1773 
1774             const tcu::Vec2 e = centerPixelCenter;
1775             const tcu::Vec2 a = tcu::Vec2(0.0f, 0.0f);
1776             const tcu::Vec2 i = tcu::Vec2(1.0f, 1.0f);
1777             const tcu::Vec2 c = tcu::Vec2(i.x(), a.y());
1778             const tcu::Vec2 g = tcu::Vec2(a.x(), i.y());
1779             const tcu::Vec2 b = tcu::Vec2(e.x(), a.y());
1780             const tcu::Vec2 d = tcu::Vec2(a.x(), e.y());
1781             const tcu::Vec2 f = tcu::Vec2(i.x(), e.y());
1782             const tcu::Vec2 h = tcu::Vec2(e.x(), i.y());
1783             const uint32_t A  = 0;
1784             const uint32_t B  = 1;
1785             const uint32_t C  = 2;
1786             const uint32_t D  = 3;
1787             const uint32_t E  = 4;
1788             const uint32_t F  = 5;
1789             const uint32_t G  = 6;
1790             const uint32_t H  = 7;
1791             const uint32_t I  = 8;
1792 
1793             vertices.push_back(a);
1794             vertices.push_back(b);
1795             vertices.push_back(c);
1796             vertices.push_back(d);
1797             vertices.push_back(e);
1798             vertices.push_back(f);
1799             vertices.push_back(g);
1800             vertices.push_back(h);
1801             vertices.push_back(i);
1802 
1803             triangles.push_back(tcu::UVec3(A, E, B));
1804             triangles.push_back(tcu::UVec3(B, E, C));
1805             triangles.push_back(tcu::UVec3(C, E, F));
1806             triangles.push_back(tcu::UVec3(F, E, I));
1807             triangles.push_back(tcu::UVec3(I, E, H));
1808             triangles.push_back(tcu::UVec3(H, E, G));
1809             triangles.push_back(tcu::UVec3(G, E, D));
1810             triangles.push_back(tcu::UVec3(D, E, A));
1811         }
1812 
1813         while (triangles.size() < testParams.squaresGroupCount)
1814         {
1815             const uint32_t n   = chooseTriangle(rng, vertices, triangles);
1816             tcu::UVec3 &t      = triangles[n];
1817             const tcu::Vec2 &a = vertices[t.x()];
1818             const tcu::Vec2 &b = vertices[t.y()];
1819             const tcu::Vec2 &c = vertices[t.z()];
1820             const float alfa   = rng.getFloat(0.2f, 0.8f);
1821             const float beta   = rng.getFloat(0.2f, 0.8f);
1822             const tcu::Vec2 d  = mixVec2(mixVec2(a, b, alfa), c, beta);
1823             const uint32_t &p  = t.x();
1824             const uint32_t &q  = t.y();
1825             uint32_t &r        = t.z();
1826             const uint32_t R   = (uint32_t)vertices.size();
1827 
1828             vertices.push_back(d);
1829 
1830             triangles.push_back(tcu::UVec3(q, r, R));
1831             triangles.push_back(tcu::UVec3(p, r, R));
1832             r = R;
1833         }
1834 
1835         verticesZ.reserve(vertices.size());
1836         for (size_t i = 0; i < vertices.size(); ++i)
1837             verticesZ.push_back(-rng.getFloat(0.01f, 0.99f));
1838 
1839         geometryData.reserve(3u * triangles.size());
1840 
1841         for (size_t i = 0; i < triangles.size(); ++i)
1842         {
1843             const uint32_t a = triangles[i].x();
1844             const uint32_t b = triangles[i].y();
1845             const uint32_t c = triangles[i].z();
1846 
1847             geometryData.push_back(tcu::Vec3(vertices[a].x(), vertices[a].y(), verticesZ[a]));
1848             geometryData.push_back(tcu::Vec3(vertices[b].x(), vertices[b].y(), verticesZ[b]));
1849             geometryData.push_back(tcu::Vec3(vertices[c].x(), vertices[c].y(), verticesZ[c]));
1850         }
1851     }
1852     else
1853     {
1854         TCU_THROW(InternalError, "Unknown geometry type");
1855     }
1856 
1857     rayQueryBottomLevelAccelerationStructure->setGeometryCount(1u);
1858     rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, testParams.geomType == GEOM_TYPE_TRIANGLES);
1859     rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
1860     m_bottomAccelerationStructures.push_back(
1861         de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
1862     m_topAccelerationStructure =
1863         de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
1864     m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back());
1865     m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
1866 
1867     return m_topAccelerationStructure.get()->getPtr();
1868 }
1869 
verify(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)1870 bool TestConfigurationNoMiss::verify(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams)
1871 {
1872     tcu::TestLog &log        = context.getTestContext().getLog();
1873     const uint32_t width     = testParams.width;
1874     const uint32_t height    = testParams.height;
1875     const int32_t *resultPtr = (int32_t *)resultBuffer->getAllocation().getHostPtr();
1876     uint32_t failures        = 0;
1877     uint32_t pos             = 0;
1878 
1879     for (uint32_t y = 0; y < height; ++y)
1880         for (uint32_t x = 0; x < width; ++x)
1881         {
1882             if (resultPtr[pos] <= 0)
1883                 failures++;
1884 
1885             pos++;
1886         }
1887 
1888     if (failures != 0)
1889     {
1890         std::stringstream css;
1891 
1892         pos = 0;
1893 
1894         for (uint32_t y = 0; y < height; ++y)
1895         {
1896             for (uint32_t x = 0; x < width; ++x)
1897             {
1898                 if (resultPtr[pos] <= 0)
1899                     css << std::setw(3) << resultPtr[pos] << ",";
1900                 else
1901                     css << "___,";
1902 
1903                 pos++;
1904             }
1905 
1906             css << std::endl;
1907         }
1908 
1909         log << tcu::TestLog::Message << "Retrieved:" << tcu::TestLog::EndMessage;
1910         log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
1911     }
1912 
1913     return (failures == 0);
1914 }
1915 
1916 class TestConfigurationSingleHit : public TestConfigurationNoMiss
1917 {
1918 public:
1919     virtual bool verify(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams) override;
1920 };
1921 
verify(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)1922 bool TestConfigurationSingleHit::verify(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams)
1923 {
1924     tcu::TestLog &log           = context.getTestContext().getLog();
1925     const uint32_t width        = testParams.width;
1926     const uint32_t height       = testParams.height;
1927     const int32_t *resultPtr    = (int32_t *)resultBuffer->getAllocation().getHostPtr();
1928     const int32_t expectedValue = 1;
1929     uint32_t failures           = 0;
1930     uint32_t pos                = 0;
1931 
1932     for (uint32_t y = 0; y < height; ++y)
1933         for (uint32_t x = 0; x < width; ++x)
1934         {
1935             if (resultPtr[pos] != expectedValue)
1936                 failures++;
1937 
1938             pos++;
1939         }
1940 
1941     if (failures != 0)
1942     {
1943         std::stringstream css;
1944 
1945         pos = 0;
1946 
1947         for (uint32_t y = 0; y < height; ++y)
1948         {
1949             for (uint32_t x = 0; x < width; ++x)
1950             {
1951                 if (resultPtr[pos] != expectedValue)
1952                     css << std::setw(3) << resultPtr[pos] << ",";
1953                 else
1954                     css << "___,";
1955 
1956                 pos++;
1957             }
1958 
1959             css << std::endl;
1960         }
1961 
1962         log << tcu::TestLog::Message << "Retrieved:" << tcu::TestLog::EndMessage;
1963         log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
1964     }
1965 
1966     return (failures == 0);
1967 }
1968 
1969 class RayQueryBuiltinTestInstance : public TestInstance
1970 {
1971 public:
1972     RayQueryBuiltinTestInstance(Context &context, const TestParams &data);
1973     virtual ~RayQueryBuiltinTestInstance(void);
1974     tcu::TestStatus iterate(void);
1975 
1976 private:
1977     TestParams m_data;
1978     de::MovePtr<TestConfiguration> m_testConfig;
1979     de::MovePtr<PipelineConfiguration> m_pipelineConfig;
1980 };
1981 
RayQueryBuiltinTestInstance(Context & context,const TestParams & data)1982 RayQueryBuiltinTestInstance::RayQueryBuiltinTestInstance(Context &context, const TestParams &data)
1983     : vkt::TestInstance(context)
1984     , m_data(data)
1985 {
1986     switch (m_data.testType)
1987     {
1988     case TEST_TYPE_NO_MISS:
1989         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationNoMiss());
1990         break;
1991     case TEST_TYPE_SINGLE_HIT:
1992         m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationSingleHit());
1993         break;
1994     default:
1995         TCU_THROW(InternalError, "Unknown test type");
1996     }
1997 
1998     switch (m_data.stage)
1999     {
2000     case VK_SHADER_STAGE_VERTEX_BIT:
2001     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
2002     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
2003     case VK_SHADER_STAGE_GEOMETRY_BIT:
2004     case VK_SHADER_STAGE_FRAGMENT_BIT:
2005     {
2006         m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new GraphicsConfiguration());
2007         break;
2008     }
2009 
2010     case VK_SHADER_STAGE_COMPUTE_BIT:
2011     {
2012         m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new ComputeConfiguration());
2013         break;
2014     }
2015 
2016     case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2017     case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2018     case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2019     case VK_SHADER_STAGE_MISS_BIT_KHR:
2020     case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2021     case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2022     {
2023         m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new RayTracingConfiguration());
2024         break;
2025     }
2026 
2027     default:
2028         TCU_THROW(InternalError, "Unknown shader stage");
2029     }
2030 }
2031 
~RayQueryBuiltinTestInstance(void)2032 RayQueryBuiltinTestInstance::~RayQueryBuiltinTestInstance(void)
2033 {
2034 }
2035 
iterate(void)2036 tcu::TestStatus RayQueryBuiltinTestInstance::iterate(void)
2037 {
2038     const DeviceInterface &vkd      = m_context.getDeviceInterface();
2039     const VkDevice device           = m_context.getDevice();
2040     const VkQueue queue             = m_context.getUniversalQueue();
2041     Allocator &allocator            = m_context.getDefaultAllocator();
2042     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2043 
2044     const uint32_t width                    = m_data.width;
2045     const uint32_t height                   = m_data.height;
2046     const uint32_t depth                    = m_data.depth;
2047     const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_data.format, width, height, depth);
2048     const VkImageSubresourceRange imageSubresourceRange =
2049         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2050     const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(
2051         new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
2052     const Move<VkImageView> imageView =
2053         makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, m_data.format, imageSubresourceRange);
2054 
2055     const uint32_t pixelSize = mapVkFormat(m_data.format).getPixelSize();
2056     const VkBufferCreateInfo resultBufferCreateInfo =
2057         makeBufferCreateInfo(width * height * depth * pixelSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
2058     const VkImageSubresourceLayers resultBufferImageSubresourceLayers =
2059         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2060     const VkBufferImageCopy resultBufferImageRegion =
2061         makeBufferImageCopy(makeExtent3D(width, height, depth), resultBufferImageSubresourceLayers);
2062     de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(
2063         new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
2064 
2065     const VkDescriptorImageInfo resultImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
2066 
2067     const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
2068     const Move<VkCommandBuffer> cmdBuffer =
2069         allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2070     const VkAccelerationStructureKHR *topAccelerationStructurePtr = DE_NULL;
2071 
2072     m_pipelineConfig->initConfiguration(m_context, m_data);
2073 
2074     beginCommandBuffer(vkd, *cmdBuffer, 0u);
2075     {
2076         const VkImageMemoryBarrier preImageBarrier =
2077             makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
2078                                    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, **image, imageSubresourceRange);
2079         const VkClearValue clearValue               = makeClearValueColorU32(0u, 0u, 0u, 0u);
2080         const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(
2081             VK_ACCESS_TRANSFER_WRITE_BIT,
2082             VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
2083             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, **image, imageSubresourceRange);
2084         const VkMemoryBarrier postTestMemoryBarrier =
2085             makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
2086         const VkMemoryBarrier postCopyMemoryBarrier =
2087             makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
2088 
2089         cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2090                                       VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
2091         vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1,
2092                                &imageSubresourceRange);
2093         cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2094                                       VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
2095 
2096         topAccelerationStructurePtr = m_testConfig->initAccelerationStructures(m_context, m_data, *cmdBuffer);
2097 
2098         m_pipelineConfig->fillCommandBuffer(m_context, m_data, *cmdBuffer, topAccelerationStructurePtr,
2099                                             resultImageInfo);
2100 
2101         cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2102                                  &postTestMemoryBarrier);
2103 
2104         vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u,
2105                                  &resultBufferImageRegion);
2106 
2107         cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2108                                  &postCopyMemoryBarrier);
2109     }
2110     endCommandBuffer(vkd, *cmdBuffer);
2111 
2112     submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2113 
2114     invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(),
2115                                 resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
2116 
2117     if (m_testConfig->verify(resultBuffer.get(), m_context, m_data))
2118         return tcu::TestStatus::pass("Pass");
2119     else
2120         return tcu::TestStatus::fail("Fail");
2121 }
2122 
2123 class RayQueryBuiltinTestCase : public TestCase
2124 {
2125 public:
2126     RayQueryBuiltinTestCase(tcu::TestContext &context, const char *name, const TestParams data);
2127     ~RayQueryBuiltinTestCase(void);
2128 
2129     virtual void checkSupport(Context &context) const;
2130     virtual void initPrograms(SourceCollections &programCollection) const;
2131     virtual TestInstance *createInstance(Context &context) const;
2132 
2133 private:
2134     TestParams m_data;
2135 };
2136 
RayQueryBuiltinTestCase(tcu::TestContext & context,const char * name,const TestParams data)2137 RayQueryBuiltinTestCase::RayQueryBuiltinTestCase(tcu::TestContext &context, const char *name, const TestParams data)
2138     : vkt::TestCase(context, name)
2139     , m_data(data)
2140 {
2141 }
2142 
~RayQueryBuiltinTestCase(void)2143 RayQueryBuiltinTestCase::~RayQueryBuiltinTestCase(void)
2144 {
2145 }
2146 
checkSupport(Context & context) const2147 void RayQueryBuiltinTestCase::checkSupport(Context &context) const
2148 {
2149     context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
2150     context.requireDeviceFunctionality("VK_KHR_ray_query");
2151 
2152     const VkPhysicalDeviceRayQueryFeaturesKHR &rayQueryFeaturesKHR = context.getRayQueryFeatures();
2153     if (rayQueryFeaturesKHR.rayQuery == false)
2154         TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");
2155 
2156     const VkPhysicalDeviceAccelerationStructureFeaturesKHR &accelerationStructureFeaturesKHR =
2157         context.getAccelerationStructureFeatures();
2158     if (accelerationStructureFeaturesKHR.accelerationStructure == false)
2159         TCU_THROW(TestError,
2160                   "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
2161 
2162     m_data.pipelineCheckSupport(context, m_data);
2163 }
2164 
createInstance(Context & context) const2165 TestInstance *RayQueryBuiltinTestCase::createInstance(Context &context) const
2166 {
2167     return new RayQueryBuiltinTestInstance(context, m_data);
2168 }
2169 
initPrograms(SourceCollections & programCollection) const2170 void RayQueryBuiltinTestCase::initPrograms(SourceCollections &programCollection) const
2171 {
2172     m_data.pipelineInitPrograms(programCollection, m_data);
2173 }
2174 
getPipelineCheckSupport(const VkShaderStageFlagBits stage)2175 static inline CheckSupportFunc getPipelineCheckSupport(const VkShaderStageFlagBits stage)
2176 {
2177     switch (stage)
2178     {
2179     case VK_SHADER_STAGE_VERTEX_BIT:
2180     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
2181     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
2182     case VK_SHADER_STAGE_GEOMETRY_BIT:
2183     case VK_SHADER_STAGE_FRAGMENT_BIT:
2184         return GraphicsConfiguration::checkSupport;
2185 
2186     case VK_SHADER_STAGE_COMPUTE_BIT:
2187         return ComputeConfiguration::checkSupport;
2188 
2189     case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2190     case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2191     case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2192     case VK_SHADER_STAGE_MISS_BIT_KHR:
2193     case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2194     case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2195         return RayTracingConfiguration::checkSupport;
2196 
2197     default:
2198         TCU_THROW(InternalError, "Unknown shader stage");
2199     }
2200 }
2201 
getPipelineInitPrograms(const VkShaderStageFlagBits stage)2202 static inline InitProgramsFunc getPipelineInitPrograms(const VkShaderStageFlagBits stage)
2203 {
2204     switch (stage)
2205     {
2206     case VK_SHADER_STAGE_VERTEX_BIT:
2207     case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
2208     case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
2209     case VK_SHADER_STAGE_GEOMETRY_BIT:
2210     case VK_SHADER_STAGE_FRAGMENT_BIT:
2211         return GraphicsConfiguration::initPrograms;
2212 
2213     case VK_SHADER_STAGE_COMPUTE_BIT:
2214         return ComputeConfiguration::initPrograms;
2215 
2216     case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2217     case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2218     case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2219     case VK_SHADER_STAGE_MISS_BIT_KHR:
2220     case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2221     case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2222         return RayTracingConfiguration::initPrograms;
2223 
2224     default:
2225         TCU_THROW(InternalError, "Unknown shader stage");
2226     }
2227 }
2228 
getShaderBodyTextFunc(const TestType testType)2229 static inline ShaderBodyTextFunc getShaderBodyTextFunc(const TestType testType)
2230 {
2231     switch (testType)
2232     {
2233     case TEST_TYPE_NO_MISS:
2234         return getShaderBodyText;
2235     case TEST_TYPE_SINGLE_HIT:
2236         return getShaderBodyText;
2237     default:
2238         TCU_THROW(InternalError, "Unknown test type");
2239     }
2240 }
2241 
2242 } // namespace
2243 
createWatertightnessTests(tcu::TestContext & testCtx)2244 tcu::TestCaseGroup *createWatertightnessTests(tcu::TestContext &testCtx)
2245 {
2246     const uint32_t seed = (uint32_t)(testCtx.getCommandLine().getBaseSeed());
2247     // Tests watertightness of ray query
2248     de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "watertightness"));
2249 
2250     const struct PipelineStages
2251     {
2252         VkShaderStageFlagBits stage;
2253         const char *name;
2254     } pipelineStages[] = {
2255         {VK_SHADER_STAGE_VERTEX_BIT, "vert"},
2256         {VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, "tesc"},
2257         {VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, "tese"},
2258         {VK_SHADER_STAGE_GEOMETRY_BIT, "geom"},
2259         {VK_SHADER_STAGE_FRAGMENT_BIT, "frag"},
2260         {VK_SHADER_STAGE_COMPUTE_BIT, "comp"},
2261         {VK_SHADER_STAGE_RAYGEN_BIT_KHR, "rgen"},
2262         {VK_SHADER_STAGE_ANY_HIT_BIT_KHR, "ahit"},
2263         {VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, "chit"},
2264         {VK_SHADER_STAGE_MISS_BIT_KHR, "miss"},
2265         {VK_SHADER_STAGE_INTERSECTION_BIT_KHR, "sect"},
2266         {VK_SHADER_STAGE_CALLABLE_BIT_KHR, "call"},
2267     };
2268     const struct TestTypes
2269     {
2270         TestType testType;
2271         const char *name;
2272     } testTypes[] = {
2273         {TEST_TYPE_NO_MISS, "nomiss"},
2274         {TEST_TYPE_SINGLE_HIT, "singlehit"},
2275     };
2276     const struct GeomTypes
2277     {
2278         GeomType geomType;
2279         const char *name;
2280     } geomTypes[] = {
2281         {GEOM_TYPE_TRIANGLES, "triangles"},
2282         {GEOM_TYPE_AABBS, "aabbs"},
2283     };
2284 
2285     for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
2286     {
2287         de::MovePtr<tcu::TestCaseGroup> testTypeGroup(
2288             new tcu::TestCaseGroup(group->getTestContext(), testTypes[testTypeNdx].name));
2289         const TestType testType                     = testTypes[testTypeNdx].testType;
2290         const ShaderBodyTextFunc shaderBodyTextFunc = getShaderBodyTextFunc(testType);
2291         const uint32_t imageDepth                   = 1;
2292 
2293         for (size_t pipelineStageNdx = 0; pipelineStageNdx < DE_LENGTH_OF_ARRAY(pipelineStages); ++pipelineStageNdx)
2294         {
2295             de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(
2296                 new tcu::TestCaseGroup(group->getTestContext(), pipelineStages[pipelineStageNdx].name));
2297             const VkShaderStageFlagBits stage           = pipelineStages[pipelineStageNdx].stage;
2298             const CheckSupportFunc pipelineCheckSupport = getPipelineCheckSupport(stage);
2299             const InitProgramsFunc pipelineInitPrograms = getPipelineInitPrograms(stage);
2300             const uint32_t instancesGroupCount          = 1;
2301             const uint32_t geometriesGroupCount         = 1;
2302             const uint32_t squaresGroupCount = (TEST_WIDTH * TEST_HEIGHT) / geometriesGroupCount / instancesGroupCount;
2303 
2304             DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == TEST_WIDTH * TEST_HEIGHT);
2305 
2306             for (size_t geomTypeNdx = 0; geomTypeNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypeNdx)
2307             {
2308                 const GeomType geomType     = geomTypes[geomTypeNdx].geomType;
2309                 const TestParams testParams = {
2310                     TEST_WIDTH,           //  uint32_t width;
2311                     TEST_HEIGHT,          //  uint32_t height;
2312                     imageDepth,           //  uint32_t depth;
2313                     seed,                 //  uint32_t randomSeed;
2314                     testType,             //  TestType testType;
2315                     stage,                //  VkShaderStageFlagBits stage;
2316                     geomType,             //  GeomType geomType;
2317                     squaresGroupCount,    //  uint32_t squaresGroupCount;
2318                     geometriesGroupCount, //  uint32_t geometriesGroupCount;
2319                     instancesGroupCount,  //  uint32_t instancesGroupCount;
2320                     VK_FORMAT_R32_SINT,   //  VkFormat format;
2321                     pipelineCheckSupport, //  CheckSupportFunc pipelineCheckSupport;
2322                     pipelineInitPrograms, //  InitProgramsFunc pipelineInitPrograms;
2323                     shaderBodyTextFunc,   //  ShaderTestTextFunc testConfigShaderBodyText;
2324                 };
2325 
2326                 if (testType == TEST_TYPE_SINGLE_HIT && geomType == GEOM_TYPE_AABBS)
2327                     continue;
2328 
2329                 sourceTypeGroup->addChild(
2330                     new RayQueryBuiltinTestCase(group->getTestContext(), geomTypes[geomTypeNdx].name, testParams));
2331             }
2332 
2333             testTypeGroup->addChild(sourceTypeGroup.release());
2334         }
2335 
2336         group->addChild(testTypeGroup.release());
2337     }
2338 
2339     return group.release();
2340 }
2341 
2342 } // namespace RayQuery
2343 } // namespace vkt
2344