• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Testing acceleration structures in ray query extension
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktRayQueryAccelerationStructuresTests.hpp"
25 
26 #include <array>
27 #include <set>
28 #include <limits>
29 
30 #include "vkDefs.hpp"
31 #include "deClock.h"
32 #include "vktTestCase.hpp"
33 #include "vktTestGroupUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkObjUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkBarrierUtil.hpp"
38 #include "vkBufferWithMemory.hpp"
39 #include "vkImageWithMemory.hpp"
40 #include "vkTypeUtil.hpp"
41 #include "vkImageUtil.hpp"
42 #include "vkRayTracingUtil.hpp"
43 #include "deRandom.hpp"
44 #include "tcuTexture.hpp"
45 #include "tcuTextureUtil.hpp"
46 #include "tcuTestLog.hpp"
47 #include "tcuImageCompare.hpp"
48 #include "tcuFloat.hpp"
49 #include "deModularCounter.hpp"
50 
51 namespace vkt
52 {
53 namespace RayQuery
54 {
55 namespace
56 {
57 using namespace vk;
58 using namespace vkt;
59 
60 static const VkFlags ALL_RAY_TRACING_STAGES = VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
61                                               VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR |
62                                               VK_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
63 
64 enum ShaderSourcePipeline
65 {
66     SSP_GRAPHICS_PIPELINE,
67     SSP_COMPUTE_PIPELINE,
68     SSP_RAY_TRACING_PIPELINE
69 };
70 
71 enum ShaderSourceType
72 {
73     SST_VERTEX_SHADER,
74     SST_TESSELATION_CONTROL_SHADER,
75     SST_TESSELATION_EVALUATION_SHADER,
76     SST_GEOMETRY_SHADER,
77     SST_FRAGMENT_SHADER,
78     SST_COMPUTE_SHADER,
79     SST_RAY_GENERATION_SHADER,
80     SST_INTERSECTION_SHADER,
81     SST_ANY_HIT_SHADER,
82     SST_CLOSEST_HIT_SHADER,
83     SST_MISS_SHADER,
84     SST_CALLABLE_SHADER,
85 };
86 
87 enum ShaderTestType
88 {
89     STT_GENERATE_INTERSECTION = 0,
90     STT_SKIP_INTERSECTION     = 1,
91 };
92 
93 enum class BottomTestType
94 {
95     TRIANGLES = 0,
96     AABBS     = 1,
97 };
98 
99 enum class TopTestType
100 {
101     IDENTICAL_INSTANCES,
102     DIFFERENT_INSTANCES,
103     UPDATED_INSTANCES
104 };
105 
106 enum OperationTarget
107 {
108     OT_NONE,
109     OT_TOP_ACCELERATION,
110     OT_BOTTOM_ACCELERATION
111 };
112 
113 enum OperationType
114 {
115     OP_NONE,
116     OP_COPY,
117     OP_COMPACT,
118     OP_SERIALIZE,
119     OP_UPDATE,
120     OP_UPDATE_IN_PLACE
121 };
122 
123 enum class InstanceCullFlags
124 {
125     NONE,
126     CULL_DISABLE,
127     COUNTERCLOCKWISE,
128     ALL,
129 };
130 
131 enum class EmptyAccelerationStructureCase
132 {
133     NOT_EMPTY            = 0,
134     INACTIVE_TRIANGLES   = 1,
135     INACTIVE_INSTANCES   = 2,
136     NO_GEOMETRIES_BOTTOM = 3, // geometryCount zero when building.
137     NO_PRIMITIVES_BOTTOM = 4, // primitiveCount zero when building.
138     NO_PRIMITIVES_TOP    = 5, // primitiveCount zero when building.
139 };
140 
141 const uint32_t TEST_WIDTH  = 8;
142 const uint32_t TEST_HEIGHT = 8;
143 
144 struct TestParams;
145 
146 class TestConfiguration
147 {
148 public:
149     virtual ~TestConfiguration();
150     virtual void initConfiguration(Context &context, TestParams &testParams) = 0;
151     virtual void fillCommandBuffer(
152         Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
153         const VkWriteDescriptorSetAccelerationStructureKHR &rayQueryAccelerationStructureWriteDescriptorSet,
154         const VkDescriptorImageInfo &resultImageInfo)                                                  = 0;
155     virtual bool verifyImage(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams) = 0;
156     virtual VkFormat getResultImageFormat()                                                            = 0;
157     virtual size_t getResultImageFormatSize()                                                          = 0;
158     virtual VkClearValue getClearValue()                                                               = 0;
159 };
160 
~TestConfiguration()161 TestConfiguration::~TestConfiguration()
162 {
163 }
164 
165 class SceneBuilder
166 {
167 public:
~SceneBuilder()168     virtual ~SceneBuilder()
169     {
170     }
171 
172     virtual std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> initBottomAccelerationStructures(
173         Context &context, TestParams &testParams) = 0;
174     virtual de::MovePtr<TopLevelAccelerationStructure> initTopAccelerationStructure(
175         Context &context, TestParams &testParams,
176         std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> &bottomLevelAccelerationStructures) = 0;
177 };
178 
179 struct TestParams
180 {
181     ShaderSourceType shaderSourceType;
182     ShaderSourcePipeline shaderSourcePipeline;
183     vk::VkAccelerationStructureBuildTypeKHR buildType; // are we making AS on CPU or GPU
184     VkFormat vertexFormat;
185     bool padVertices;
186     VkIndexType indexType;
187     BottomTestType bottomTestType; // what kind of geometry is stored in bottom AS
188     InstanceCullFlags cullFlags;   // Flags for instances, if needed.
189     bool bottomUsesAOP;            // does bottom AS use arrays, or arrays of pointers
190     bool bottomGeneric;            // Bottom created as generic AS type.
191     bool bottomUnboundedCreation;  // Bottom created with unbounded buffer memory.
192     TopTestType topTestType;   // If instances are identical then bottom geometries must have different vertices/aabbs
193     bool topUsesAOP;           // does top AS use arrays, or arrays of pointers
194     bool topGeneric;           // Top created as generic AS type.
195     bool topUnboundedCreation; // Top created with unbounded buffer memory.
196     VkBuildAccelerationStructureFlagsKHR buildFlags;
197     OperationTarget operationTarget;
198     OperationType operationType;
199     uint32_t width;
200     uint32_t height;
201     uint32_t workerThreadsCount;
202     EmptyAccelerationStructureCase emptyASCase;
203 };
204 
getShaderGroupHandleSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)205 uint32_t getShaderGroupHandleSize(const InstanceInterface &vki, const VkPhysicalDevice physicalDevice)
206 {
207     de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
208 
209     rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
210     return rayTracingPropertiesKHR->getShaderGroupHandleSize();
211 }
212 
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)213 uint32_t getShaderGroupBaseAlignment(const InstanceInterface &vki, const VkPhysicalDevice physicalDevice)
214 {
215     de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
216 
217     rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
218     return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
219 }
220 
makeImageCreateInfo(uint32_t width,uint32_t height,uint32_t depth,VkFormat format)221 VkImageCreateInfo makeImageCreateInfo(uint32_t width, uint32_t height, uint32_t depth, VkFormat format)
222 {
223     const VkImageCreateInfo imageCreateInfo = {
224         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
225         DE_NULL,                             // const void* pNext;
226         (VkImageCreateFlags)0u,              // VkImageCreateFlags flags;
227         VK_IMAGE_TYPE_3D,                    // VkImageType imageType;
228         format,                              // VkFormat format;
229         makeExtent3D(width, height, depth),  // VkExtent3D extent;
230         1u,                                  // uint32_t mipLevels;
231         1u,                                  // uint32_t arrayLayers;
232         VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits samples;
233         VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling tiling;
234         VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
235             VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
236         VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode sharingMode;
237         0u,                                  // uint32_t queueFamilyIndexCount;
238         DE_NULL,                             // const uint32_t* pQueueFamilyIndices;
239         VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout initialLayout;
240     };
241 
242     return imageCreateInfo;
243 }
244 
makeQueryPool(const DeviceInterface & vk,const VkDevice device,const VkQueryType queryType,uint32_t queryCount)245 Move<VkQueryPool> makeQueryPool(const DeviceInterface &vk, const VkDevice device, const VkQueryType queryType,
246                                 uint32_t queryCount)
247 {
248     const VkQueryPoolCreateInfo queryPoolCreateInfo = {
249         VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // sType
250         DE_NULL,                                  // pNext
251         (VkQueryPoolCreateFlags)0,                // flags
252         queryType,                                // queryType
253         queryCount,                               // queryCount
254         0u,                                       // pipelineStatistics
255     };
256     return createQueryPool(vk, device, &queryPoolCreateInfo);
257 }
258 
registerShaderModule(const DeviceInterface & vkd,const VkDevice device,Context & context,std::vector<de::SharedPtr<Move<VkShaderModule>>> & shaderModules,std::vector<VkPipelineShaderStageCreateInfo> & shaderCreateInfos,VkShaderStageFlagBits stage,const std::string & externalNamePart,const std::string & internalNamePart)259 bool registerShaderModule(const DeviceInterface &vkd, const VkDevice device, Context &context,
260                           std::vector<de::SharedPtr<Move<VkShaderModule>>> &shaderModules,
261                           std::vector<VkPipelineShaderStageCreateInfo> &shaderCreateInfos, VkShaderStageFlagBits stage,
262                           const std::string &externalNamePart, const std::string &internalNamePart)
263 {
264     char fullShaderName[40];
265     snprintf(fullShaderName, 40, externalNamePart.c_str(), internalNamePart.c_str());
266     std::string fsn = fullShaderName;
267     if (fsn.empty())
268         return false;
269 
270     shaderModules.push_back(
271         makeVkSharedPtr(createShaderModule(vkd, device, context.getBinaryCollection().get(fsn), 0)));
272 
273     shaderCreateInfos.push_back({
274         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, DE_NULL, (VkPipelineShaderStageCreateFlags)0,
275         stage,                       // stage
276         shaderModules.back()->get(), // shader
277         "main",
278         DE_NULL, // pSpecializationInfo
279     });
280 
281     return true;
282 }
283 
registerShaderModule(const DeviceInterface & vkd,const VkDevice device,Context & context,RayTracingPipeline & rayTracingPipeline,VkShaderStageFlagBits shaderStage,const std::string & externalNamePart,const std::string & internalNamePart,uint32_t groupIndex)284 bool registerShaderModule(const DeviceInterface &vkd, const VkDevice device, Context &context,
285                           RayTracingPipeline &rayTracingPipeline, VkShaderStageFlagBits shaderStage,
286                           const std::string &externalNamePart, const std::string &internalNamePart, uint32_t groupIndex)
287 {
288     char fullShaderName[40];
289     snprintf(fullShaderName, 40, externalNamePart.c_str(), internalNamePart.c_str());
290     std::string fsn = fullShaderName;
291     if (fsn.empty())
292         return false;
293     Move<VkShaderModule> shaderModule = createShaderModule(vkd, device, context.getBinaryCollection().get(fsn), 0);
294     if (*shaderModule == DE_NULL)
295         return false;
296     rayTracingPipeline.addShader(shaderStage, shaderModule, groupIndex);
297     return true;
298 }
299 
getCullFlags(InstanceCullFlags flags)300 VkGeometryInstanceFlagsKHR getCullFlags(InstanceCullFlags flags)
301 {
302     VkGeometryInstanceFlagsKHR cullFlags = 0u;
303 
304     if (flags == InstanceCullFlags::CULL_DISABLE || flags == InstanceCullFlags::ALL)
305         cullFlags |= VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
306 
307     if (flags == InstanceCullFlags::COUNTERCLOCKWISE || flags == InstanceCullFlags::ALL)
308         cullFlags |= VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR;
309 
310     return cullFlags;
311 }
312 
313 class GraphicsConfiguration : public TestConfiguration
314 {
315 public:
316     virtual ~GraphicsConfiguration();
317     void initConfiguration(Context &context, TestParams &testParams) override;
318     void fillCommandBuffer(
319         Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
320         const VkWriteDescriptorSetAccelerationStructureKHR &rayQueryAccelerationStructureWriteDescriptorSet,
321         const VkDescriptorImageInfo &resultImageInfo) override;
322     bool verifyImage(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams) override;
323     VkFormat getResultImageFormat() override;
324     size_t getResultImageFormatSize() override;
325     VkClearValue getClearValue() override;
326 
327 protected:
328     Move<VkDescriptorSetLayout> descriptorSetLayout;
329     Move<VkDescriptorPool> descriptorPool;
330     Move<VkDescriptorSet> descriptorSet;
331     Move<VkPipelineLayout> pipelineLayout;
332     Move<VkRenderPass> renderPass;
333     Move<VkFramebuffer> framebuffer;
334     std::vector<de::SharedPtr<Move<VkShaderModule>>> shaderModules;
335     Move<VkPipeline> pipeline;
336     std::vector<tcu::Vec3> vertices;
337     Move<VkBuffer> vertexBuffer;
338     de::MovePtr<Allocation> vertexAlloc;
339 };
340 
~GraphicsConfiguration()341 GraphicsConfiguration::~GraphicsConfiguration()
342 {
343     shaderModules.clear();
344 }
345 
initConfiguration(Context & context,TestParams & testParams)346 void GraphicsConfiguration::initConfiguration(Context &context, TestParams &testParams)
347 {
348     const DeviceInterface &vkd      = context.getDeviceInterface();
349     const VkDevice device           = context.getDevice();
350     const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
351     Allocator &allocator            = context.getDefaultAllocator();
352 
353     descriptorSetLayout =
354         DescriptorSetLayoutBuilder()
355             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL_GRAPHICS)
356             .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL_GRAPHICS)
357             .build(vkd, device);
358     descriptorPool = DescriptorPoolBuilder()
359                          .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
360                          .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
361                          .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
362     descriptorSet  = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
363     pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
364 
365     std::vector<std::string> rayQueryTestName;
366     rayQueryTestName.push_back("as_triangle");
367     rayQueryTestName.push_back("as_aabb");
368 
369     const std::map<ShaderSourceType, std::vector<std::string>> shaderNames = {
370         //idx: 0                1                2                3                4
371         //shader: vert, tesc, tese, geom, frag,
372         {SST_VERTEX_SHADER,
373          {
374              "vert_%s",
375              "",
376              "",
377              "",
378              "",
379          }},
380         {SST_TESSELATION_CONTROL_SHADER,
381          {
382              "vert",
383              "tesc_%s",
384              "tese",
385              "",
386              "",
387          }},
388         {SST_TESSELATION_EVALUATION_SHADER,
389          {
390              "vert",
391              "tesc",
392              "tese_%s",
393              "",
394              "",
395          }},
396         {SST_GEOMETRY_SHADER,
397          {
398              "vert_vid",
399              "",
400              "",
401              "geom_%s",
402              "",
403          }},
404         {SST_FRAGMENT_SHADER,
405          {
406              "vert",
407              "",
408              "",
409              "",
410              "frag_%s",
411          }},
412     };
413 
414     auto shaderNameIt = shaderNames.find(testParams.shaderSourceType);
415     if (shaderNameIt == end(shaderNames))
416         TCU_THROW(InternalError, "Wrong shader source type");
417 
418     std::vector<VkPipelineShaderStageCreateInfo> shaderCreateInfos;
419     bool tescX, teseX, fragX;
420     const auto bottomTestTypeIdx = static_cast<int>(testParams.bottomTestType);
421     registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_VERTEX_BIT,
422                          shaderNameIt->second[0], rayQueryTestName[bottomTestTypeIdx]);
423     tescX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos,
424                                  VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, shaderNameIt->second[1],
425                                  rayQueryTestName[bottomTestTypeIdx]);
426     teseX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos,
427                                  VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, shaderNameIt->second[2],
428                                  rayQueryTestName[bottomTestTypeIdx]);
429     registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_GEOMETRY_BIT,
430                          shaderNameIt->second[3], rayQueryTestName[bottomTestTypeIdx]);
431     fragX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_FRAGMENT_BIT,
432                                  shaderNameIt->second[4], rayQueryTestName[bottomTestTypeIdx]);
433 
434     const vk::VkSubpassDescription subpassDesc = {
435         (vk::VkSubpassDescriptionFlags)0,
436         vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
437         0u,                                  // inputCount
438         DE_NULL,                             // pInputAttachments
439         0u,                                  // colorCount
440         DE_NULL,                             // pColorAttachments
441         DE_NULL,                             // pResolveAttachments
442         DE_NULL,                             // depthStencilAttachment
443         0u,                                  // preserveCount
444         DE_NULL,                             // pPreserveAttachments
445     };
446     const vk::VkRenderPassCreateInfo renderPassParams = {
447         vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // sType
448         DE_NULL,                                       // pNext
449         (vk::VkRenderPassCreateFlags)0,
450         0u,           // attachmentCount
451         DE_NULL,      // pAttachments
452         1u,           // subpassCount
453         &subpassDesc, // pSubpasses
454         0u,           // dependencyCount
455         DE_NULL,      // pDependencies
456     };
457 
458     renderPass = createRenderPass(vkd, device, &renderPassParams);
459 
460     const vk::VkFramebufferCreateInfo framebufferParams = {
461         vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType
462         DE_NULL,                                       // pNext
463         (vk::VkFramebufferCreateFlags)0,
464         *renderPass,       // renderPass
465         0u,                // attachmentCount
466         DE_NULL,           // pAttachments
467         testParams.width,  // width
468         testParams.height, // height
469         1u,                // layers
470     };
471 
472     framebuffer = createFramebuffer(vkd, device, &framebufferParams);
473 
474     VkPrimitiveTopology testTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
475     tcu::Vec3 v0(0.0f, 0.0f, 0.0f);
476     tcu::Vec3 v1(float(testParams.width) - 1.0f, 0.0f, 0.0f);
477     tcu::Vec3 v2(0.0f, float(testParams.height) - 1.0f, 0.0f);
478     tcu::Vec3 v3(float(testParams.width) - 1.0f, float(testParams.height) - 1.0f, 0.0f);
479 
480     switch (testParams.shaderSourceType)
481     {
482     case SST_TESSELATION_CONTROL_SHADER:
483     case SST_TESSELATION_EVALUATION_SHADER:
484         testTopology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
485         vertices.push_back(v0);
486         vertices.push_back(v1);
487         vertices.push_back(v2);
488         vertices.push_back(v1);
489         vertices.push_back(v3);
490         vertices.push_back(v2);
491         break;
492     case SST_VERTEX_SHADER:
493     case SST_GEOMETRY_SHADER:
494         vertices.push_back(v0);
495         vertices.push_back(v1);
496         vertices.push_back(v2);
497         vertices.push_back(v3);
498         break;
499     case SST_FRAGMENT_SHADER:
500         vertices.push_back(tcu::Vec3(-1.0f, 1.0f, 0.0f));
501         vertices.push_back(tcu::Vec3(-1.0f, -1.0f, 0.0f));
502         vertices.push_back(tcu::Vec3(1.0f, 1.0f, 0.0f));
503         vertices.push_back(tcu::Vec3(1.0f, -1.0f, 0.0f));
504         break;
505     default:
506         TCU_THROW(InternalError, "Wrong shader source type");
507     }
508 
509     const VkVertexInputBindingDescription vertexInputBindingDescription = {
510         0u,                          // uint32_t binding;
511         sizeof(tcu::Vec3),           // uint32_t stride;
512         VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
513     };
514 
515     const VkVertexInputAttributeDescription vertexInputAttributeDescription = {
516         0u,                         // uint32_t location;
517         0u,                         // uint32_t binding;
518         VK_FORMAT_R32G32B32_SFLOAT, // VkFormat format;
519         0u,                         // uint32_t offset;
520     };
521 
522     const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
523         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
524         DE_NULL,                                                   // const void* pNext;
525         (VkPipelineVertexInputStateCreateFlags)0,                  // VkPipelineVertexInputStateCreateFlags flags;
526         1u,                                                        // uint32_t vertexBindingDescriptionCount;
527         &vertexInputBindingDescription,  // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
528         1u,                              // uint32_t vertexAttributeDescriptionCount;
529         &vertexInputAttributeDescription // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
530     };
531 
532     const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = {
533         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
534         DE_NULL,                                                     // const void* pNext;
535         (VkPipelineInputAssemblyStateCreateFlags)0,                  // VkPipelineInputAssemblyStateCreateFlags flags;
536         testTopology,                                                // VkPrimitiveTopology topology;
537         VK_FALSE                                                     // VkBool32 primitiveRestartEnable;
538     };
539 
540     const VkPipelineTessellationStateCreateInfo tessellationStateCreateInfo = {
541         VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
542         DE_NULL,                                                   // const void* pNext;
543         VkPipelineTessellationStateCreateFlags(0u),                // VkPipelineTessellationStateCreateFlags flags;
544         3u                                                         // uint32_t patchControlPoints;
545     };
546 
547     VkViewport viewport = makeViewport(testParams.width, testParams.height);
548     VkRect2D scissor    = makeRect2D(testParams.width, testParams.height);
549 
550     const VkPipelineViewportStateCreateInfo viewportStateCreateInfo = {
551         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType                                    sType
552         DE_NULL,                               // const void*                                        pNext
553         (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags                flags
554         1u,                                    // uint32_t                                            viewportCount
555         &viewport,                             // const VkViewport*                                pViewports
556         1u,                                    // uint32_t                                            scissorCount
557         &scissor                               // const VkRect2D*                                    pScissors
558     };
559 
560     const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = {
561         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
562         DE_NULL,                                                    // const void* pNext;
563         (VkPipelineRasterizationStateCreateFlags)0,                 // VkPipelineRasterizationStateCreateFlags flags;
564         VK_FALSE,                                                   // VkBool32 depthClampEnable;
565         fragX ? VK_FALSE : VK_TRUE,                                 // VkBool32 rasterizerDiscardEnable;
566         VK_POLYGON_MODE_FILL,                                       // VkPolygonMode polygonMode;
567         VK_CULL_MODE_NONE,                                          // VkCullModeFlags cullMode;
568         VK_FRONT_FACE_CLOCKWISE,                                    // VkFrontFace frontFace;
569         VK_FALSE,                                                   // VkBool32 depthBiasEnable;
570         0.0f,                                                       // float depthBiasConstantFactor;
571         0.0f,                                                       // float depthBiasClamp;
572         0.0f,                                                       // float depthBiasSlopeFactor;
573         1.0f                                                        // float lineWidth;
574     };
575 
576     const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo = {
577         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
578         DE_NULL,                                                  // const void* pNext;
579         (VkPipelineMultisampleStateCreateFlags)0,                 // VkPipelineMultisampleStateCreateFlags flags;
580         VK_SAMPLE_COUNT_1_BIT,                                    // VkSampleCountFlagBits rasterizationSamples;
581         VK_FALSE,                                                 // VkBool32 sampleShadingEnable;
582         0.0f,                                                     // float minSampleShading;
583         DE_NULL,                                                  // const VkSampleMask* pSampleMask;
584         VK_FALSE,                                                 // VkBool32 alphaToCoverageEnable;
585         VK_FALSE                                                  // VkBool32 alphaToOneEnable;
586     };
587 
588     const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = {
589         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
590         DE_NULL,                                                  // const void* pNext;
591         (VkPipelineColorBlendStateCreateFlags)0,                  // VkPipelineColorBlendStateCreateFlags flags;
592         false,                                                    // VkBool32 logicOpEnable;
593         VK_LOGIC_OP_CLEAR,                                        // VkLogicOp logicOp;
594         0,                                                        // uint32_t attachmentCount;
595         DE_NULL,                 // const VkPipelineColorBlendAttachmentState* pAttachments;
596         {1.0f, 1.0f, 1.0f, 1.0f} // float blendConstants[4];
597     };
598 
599     const VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {
600         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
601         DE_NULL,                                         // const void* pNext;
602         (VkPipelineCreateFlags)0,                        // VkPipelineCreateFlags flags;
603         static_cast<uint32_t>(shaderCreateInfos.size()), // uint32_t stageCount;
604         shaderCreateInfos.data(),                        // const VkPipelineShaderStageCreateInfo* pStages;
605         &vertexInputStateCreateInfo,   // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
606         &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
607         (tescX || teseX) ? &tessellationStateCreateInfo :
608                            DE_NULL,                 // const VkPipelineTessellationStateCreateInfo* pTessellationState;
609         fragX ? &viewportStateCreateInfo : DE_NULL, // const VkPipelineViewportStateCreateInfo* pViewportState;
610         &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
611         fragX ? &multisampleStateCreateInfo : DE_NULL, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
612         DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
613         fragX ? &colorBlendStateCreateInfo : DE_NULL, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
614         DE_NULL,                                      // const VkPipelineDynamicStateCreateInfo* pDynamicState;
615         pipelineLayout.get(),                         // VkPipelineLayout layout;
616         renderPass.get(),                             // VkRenderPass renderPass;
617         0u,                                           // uint32_t subpass;
618         DE_NULL,                                      // VkPipeline basePipelineHandle;
619         0                                             // int basePipelineIndex;
620     };
621 
622     pipeline = createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineCreateInfo);
623 
624     const VkBufferCreateInfo vertexBufferParams = {
625         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                 // VkStructureType sType;
626         DE_NULL,                                                              // const void* pNext;
627         0u,                                                                   // VkBufferCreateFlags flags;
628         VkDeviceSize(sizeof(tcu::Vec3) * vertices.size()),                    // VkDeviceSize size;
629         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
630         VK_SHARING_MODE_EXCLUSIVE,                                            // VkSharingMode sharingMode;
631         1u,                                                                   // uint32_t queueFamilyIndexCount;
632         &queueFamilyIndex                                                     // const uint32_t* pQueueFamilyIndices;
633     };
634 
635     vertexBuffer = createBuffer(vkd, device, &vertexBufferParams);
636     vertexAlloc =
637         allocator.allocate(getBufferMemoryRequirements(vkd, device, *vertexBuffer), MemoryRequirement::HostVisible);
638     VK_CHECK(vkd.bindBufferMemory(device, *vertexBuffer, vertexAlloc->getMemory(), vertexAlloc->getOffset()));
639 
640     // Upload vertex data
641     deMemcpy(vertexAlloc->getHostPtr(), vertices.data(), vertices.size() * sizeof(tcu::Vec3));
642     flushAlloc(vkd, device, *vertexAlloc);
643 }
644 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)645 void GraphicsConfiguration::fillCommandBuffer(
646     Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
647     const VkWriteDescriptorSetAccelerationStructureKHR &rayQueryAccelerationStructureWriteDescriptorSet,
648     const VkDescriptorImageInfo &resultImageInfo)
649 {
650     const DeviceInterface &vkd = context.getDeviceInterface();
651     const VkDevice device      = context.getDevice();
652 
653     DescriptorSetUpdateBuilder()
654         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
655                      VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
656         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
657                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
658         .update(vkd, device);
659 
660     const VkRenderPassBeginInfo renderPassBeginInfo = {
661         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,        // VkStructureType sType;
662         DE_NULL,                                         // const void* pNext;
663         *renderPass,                                     // VkRenderPass renderPass;
664         *framebuffer,                                    // VkFramebuffer framebuffer;
665         makeRect2D(testParams.width, testParams.height), // VkRect2D renderArea;
666         0u,                                              // uint32_t clearValueCount;
667         DE_NULL                                          // const VkClearValue* pClearValues;
668     };
669     VkDeviceSize vertexBufferOffset = 0u;
670 
671     vkd.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
672     vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
673     vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u,
674                               &descriptorSet.get(), 0u, DE_NULL);
675     vkd.cmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
676     vkd.cmdDraw(commandBuffer, uint32_t(vertices.size()), 1, 0, 0);
677     vkd.cmdEndRenderPass(commandBuffer);
678 }
679 
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)680 bool GraphicsConfiguration::verifyImage(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams)
681 {
682     // create result image
683     const bool allMiss             = (testParams.emptyASCase != EmptyAccelerationStructureCase::NOT_EMPTY);
684     tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat());
685     tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2,
686                                              resultBuffer->getAllocation().getHostPtr());
687 
688     // create reference image
689     std::vector<uint32_t> reference(testParams.width * testParams.height * 2);
690     tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
691 
692     std::vector<std::vector<uint32_t>> primitives = {{0, 1, 2}, {1, 3, 2}};
693 
694     tcu::UVec4 hitValue0  = tcu::UVec4(1, 0, 0, 0);
695     tcu::UVec4 hitValue1  = tcu::UVec4(1, 0, 0, 0);
696     tcu::UVec4 missValue  = tcu::UVec4(0, 0, 0, 0);
697     tcu::UVec4 clearValue = tcu::UVec4(0xFF, 0, 0, 0);
698 
699     switch (testParams.shaderSourceType)
700     {
701     case SST_VERTEX_SHADER:
702         tcu::clear(referenceAccess, clearValue);
703         for (uint32_t vertexNdx = 0; vertexNdx < 4; ++vertexNdx)
704         {
705             if (!allMiss && (vertexNdx == 1 || vertexNdx == 2))
706             {
707                 referenceAccess.setPixel(hitValue0, vertexNdx, 0, 0);
708                 referenceAccess.setPixel(hitValue1, vertexNdx, 0, 1);
709             }
710             else
711             {
712                 referenceAccess.setPixel(missValue, vertexNdx, 0, 0);
713                 referenceAccess.setPixel(missValue, vertexNdx, 0, 1);
714             }
715         }
716         break;
717     case SST_TESSELATION_EVALUATION_SHADER:
718     case SST_TESSELATION_CONTROL_SHADER:
719     case SST_GEOMETRY_SHADER:
720         tcu::clear(referenceAccess, clearValue);
721         for (uint32_t primitiveNdx = 0; primitiveNdx < primitives.size(); ++primitiveNdx)
722             for (uint32_t vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
723             {
724                 uint32_t vNdx = primitives[primitiveNdx][vertexNdx];
725                 if (!allMiss && (vNdx == 1 || vNdx == 2))
726                 {
727                     referenceAccess.setPixel(hitValue0, primitiveNdx, vertexNdx, 0);
728                     referenceAccess.setPixel(hitValue1, primitiveNdx, vertexNdx, 1);
729                 }
730                 else
731                 {
732                     referenceAccess.setPixel(missValue, primitiveNdx, vertexNdx, 0);
733                     referenceAccess.setPixel(missValue, primitiveNdx, vertexNdx, 1);
734                 }
735             }
736         break;
737     case SST_FRAGMENT_SHADER:
738         tcu::clear(referenceAccess, missValue);
739         for (uint32_t y = 0; y < testParams.height; ++y)
740             for (uint32_t x = 0; x < testParams.width; ++x)
741             {
742                 if (allMiss || ((x + y) % 2) == 0)
743                     continue;
744 
745                 referenceAccess.setPixel(hitValue0, x, y, 0);
746                 referenceAccess.setPixel(hitValue1, x, y, 1);
747             }
748         break;
749     default:
750         TCU_THROW(InternalError, "Wrong shader source type");
751     }
752 
753     // compare result and reference
754     return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess,
755                                     resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
756 }
757 
getResultImageFormat()758 VkFormat GraphicsConfiguration::getResultImageFormat()
759 {
760     return VK_FORMAT_R32_UINT;
761 }
762 
getResultImageFormatSize()763 size_t GraphicsConfiguration::getResultImageFormatSize()
764 {
765     return sizeof(uint32_t);
766 }
767 
getClearValue()768 VkClearValue GraphicsConfiguration::getClearValue()
769 {
770     return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
771 }
772 
773 class ComputeConfiguration : public TestConfiguration
774 {
775 public:
776     virtual ~ComputeConfiguration();
777     void initConfiguration(Context &context, TestParams &testParams) override;
778     void fillCommandBuffer(
779         Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
780         const VkWriteDescriptorSetAccelerationStructureKHR &rayQueryAccelerationStructureWriteDescriptorSet,
781         const VkDescriptorImageInfo &resultImageInfo) override;
782     bool verifyImage(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams) override;
783     VkFormat getResultImageFormat() override;
784     size_t getResultImageFormatSize() override;
785     VkClearValue getClearValue() override;
786 
787 protected:
788     Move<VkDescriptorSetLayout> descriptorSetLayout;
789     Move<VkDescriptorPool> descriptorPool;
790     Move<VkDescriptorSet> descriptorSet;
791     Move<VkPipelineLayout> pipelineLayout;
792     Move<VkShaderModule> shaderModule;
793     Move<VkPipeline> pipeline;
794 };
795 
~ComputeConfiguration()796 ComputeConfiguration::~ComputeConfiguration()
797 {
798 }
799 
initConfiguration(Context & context,TestParams & testParams)800 void ComputeConfiguration::initConfiguration(Context &context, TestParams &testParams)
801 {
802     const DeviceInterface &vkd = context.getDeviceInterface();
803     const VkDevice device      = context.getDevice();
804 
805     descriptorSetLayout =
806         DescriptorSetLayoutBuilder()
807             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
808             .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_COMPUTE_BIT)
809             .build(vkd, device);
810     descriptorPool = DescriptorPoolBuilder()
811                          .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
812                          .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
813                          .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
814     descriptorSet  = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
815     pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
816 
817     std::vector<std::string> rayQueryTestName;
818     rayQueryTestName.push_back("comp_as_triangle");
819     rayQueryTestName.push_back("comp_as_aabb");
820 
821     const auto bottomTestTypeIdx = static_cast<int>(testParams.bottomTestType);
822     shaderModule =
823         createShaderModule(vkd, device, context.getBinaryCollection().get(rayQueryTestName[bottomTestTypeIdx]), 0u);
824     const VkPipelineShaderStageCreateInfo pipelineShaderStageParams = {
825         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
826         DE_NULL,                                             // const void* pNext;
827         0u,                                                  // VkPipelineShaderStageCreateFlags flags;
828         VK_SHADER_STAGE_COMPUTE_BIT,                         // VkShaderStageFlagBits stage;
829         *shaderModule,                                       // VkShaderModule module;
830         "main",                                              // const char* pName;
831         DE_NULL,                                             // const VkSpecializationInfo* pSpecializationInfo;
832     };
833     const VkComputePipelineCreateInfo pipelineCreateInfo = {
834         VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
835         DE_NULL,                                        // const void* pNext;
836         0u,                                             // VkPipelineCreateFlags flags;
837         pipelineShaderStageParams,                      // VkPipelineShaderStageCreateInfo stage;
838         *pipelineLayout,                                // VkPipelineLayout layout;
839         DE_NULL,                                        // VkPipeline basePipelineHandle;
840         0,                                              // int32_t basePipelineIndex;
841     };
842 
843     pipeline = createComputePipeline(vkd, device, DE_NULL, &pipelineCreateInfo);
844 }
845 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)846 void ComputeConfiguration::fillCommandBuffer(
847     Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
848     const VkWriteDescriptorSetAccelerationStructureKHR &rayQueryAccelerationStructureWriteDescriptorSet,
849     const VkDescriptorImageInfo &resultImageInfo)
850 {
851     const DeviceInterface &vkd = context.getDeviceInterface();
852     const VkDevice device      = context.getDevice();
853 
854     DescriptorSetUpdateBuilder()
855         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
856                      VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
857         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
858                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
859         .update(vkd, device);
860 
861     vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
862 
863     vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u,
864                               &descriptorSet.get(), 0u, DE_NULL);
865 
866     vkd.cmdDispatch(commandBuffer, testParams.width, testParams.height, 1);
867 }
868 
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)869 bool ComputeConfiguration::verifyImage(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams)
870 {
871     // create result image
872     const bool allMiss             = (testParams.emptyASCase != EmptyAccelerationStructureCase::NOT_EMPTY);
873     tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat());
874     tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2,
875                                              resultBuffer->getAllocation().getHostPtr());
876 
877     // create reference image
878     std::vector<uint32_t> reference(testParams.width * testParams.height * 2);
879     tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
880 
881     tcu::UVec4 hitValue0 = tcu::UVec4(1, 0, 0, 0);
882     tcu::UVec4 hitValue1 = tcu::UVec4(1, 0, 0, 0);
883     tcu::UVec4 missValue = tcu::UVec4(0, 0, 0, 0);
884 
885     tcu::clear(referenceAccess, missValue);
886 
887     for (uint32_t y = 0; y < testParams.height; ++y)
888         for (uint32_t x = 0; x < testParams.width; ++x)
889         {
890             if (allMiss || ((x + y) % 2) == 0)
891                 continue;
892 
893             referenceAccess.setPixel(hitValue0, x, y, 0);
894             referenceAccess.setPixel(hitValue1, x, y, 1);
895         }
896 
897     // compare result and reference
898     return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess,
899                                     resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
900 }
901 
getResultImageFormat()902 VkFormat ComputeConfiguration::getResultImageFormat()
903 {
904     return VK_FORMAT_R32_UINT;
905 }
906 
getResultImageFormatSize()907 size_t ComputeConfiguration::getResultImageFormatSize()
908 {
909     return sizeof(uint32_t);
910 }
911 
getClearValue()912 VkClearValue ComputeConfiguration::getClearValue()
913 {
914     return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
915 }
916 
917 class RayTracingConfiguration : public TestConfiguration
918 {
919 public:
920     virtual ~RayTracingConfiguration();
921     void initConfiguration(Context &context, TestParams &testParams) override;
922     void fillCommandBuffer(
923         Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
924         const VkWriteDescriptorSetAccelerationStructureKHR &rayQueryAccelerationStructureWriteDescriptorSet,
925         const VkDescriptorImageInfo &resultImageInfo) override;
926     bool verifyImage(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams) override;
927     VkFormat getResultImageFormat() override;
928     size_t getResultImageFormatSize() override;
929     VkClearValue getClearValue() override;
930 
931 protected:
932     Move<VkDescriptorSetLayout> descriptorSetLayout;
933     Move<VkDescriptorPool> descriptorPool;
934     Move<VkDescriptorSet> descriptorSet;
935     Move<VkPipelineLayout> pipelineLayout;
936 
937     de::MovePtr<RayTracingPipeline> rayTracingPipeline;
938     Move<VkPipeline> rtPipeline;
939 
940     de::MovePtr<BufferWithMemory> raygenShaderBindingTable;
941     de::MovePtr<BufferWithMemory> hitShaderBindingTable;
942     de::MovePtr<BufferWithMemory> missShaderBindingTable;
943     de::MovePtr<BufferWithMemory> callableShaderBindingTable;
944 
945     std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> bottomLevelAccelerationStructures;
946     de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure;
947 };
948 
~RayTracingConfiguration()949 RayTracingConfiguration::~RayTracingConfiguration()
950 {
951 }
952 
initConfiguration(Context & context,TestParams & testParams)953 void RayTracingConfiguration::initConfiguration(Context &context, TestParams &testParams)
954 {
955     const InstanceInterface &vki          = context.getInstanceInterface();
956     const DeviceInterface &vkd            = context.getDeviceInterface();
957     const VkDevice device                 = context.getDevice();
958     const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
959     Allocator &allocator                  = context.getDefaultAllocator();
960 
961     descriptorSetLayout = DescriptorSetLayoutBuilder()
962                               .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
963                               .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
964                               .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
965                               .build(vkd, device);
966     descriptorPool = DescriptorPoolBuilder()
967                          .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
968                          .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
969                          .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
970                          .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
971     descriptorSet  = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
972     pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
973 
974     rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
975 
976     const std::map<ShaderSourceType, std::vector<std::string>> shaderNames = {
977         //idx: 0                1                2                3                4                5
978         //shader: rgen, isect, ahit, chit, miss, call
979         //group: 0                1                1                1                2                3
980         {SST_RAY_GENERATION_SHADER, {"rgen_%s", "", "", "", "", ""}},
981         {SST_INTERSECTION_SHADER, {"rgen", "isect_%s", "", "chit_isect", "miss", ""}},
982         {SST_ANY_HIT_SHADER, {"rgen", "isect", "ahit_%s", "", "miss", ""}},
983         {SST_CLOSEST_HIT_SHADER, {"rgen", "isect", "", "chit_%s", "miss", ""}},
984         {SST_MISS_SHADER, {"rgen", "isect", "", "chit", "miss_%s", ""}},
985         {SST_CALLABLE_SHADER, {"rgen_call", "", "", "chit", "miss", "call_%s"}},
986     };
987 
988     std::vector<std::string> rayQueryTestName;
989     rayQueryTestName.push_back("as_triangle");
990     rayQueryTestName.push_back("as_aabb");
991 
992     auto shaderNameIt = shaderNames.find(testParams.shaderSourceType);
993     if (shaderNameIt == end(shaderNames))
994         TCU_THROW(InternalError, "Wrong shader source type");
995 
996     bool rgenX, isectX, ahitX, chitX, missX, callX;
997     const auto bottomTestTypeIdx = static_cast<int>(testParams.bottomTestType);
998     rgenX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_RAYGEN_BIT_KHR,
999                                  shaderNameIt->second[0], rayQueryTestName[bottomTestTypeIdx], 0);
1000     if (testParams.shaderSourceType == SST_INTERSECTION_SHADER)
1001         isectX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_INTERSECTION_BIT_KHR,
1002                                       shaderNameIt->second[1], rayQueryTestName[bottomTestTypeIdx], 1);
1003     else
1004         isectX = false;
1005     ahitX     = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_ANY_HIT_BIT_KHR,
1006                                      shaderNameIt->second[2], rayQueryTestName[bottomTestTypeIdx], 1);
1007     chitX     = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,
1008                                      shaderNameIt->second[3], rayQueryTestName[bottomTestTypeIdx], 1);
1009     missX     = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_MISS_BIT_KHR,
1010                                      shaderNameIt->second[4], rayQueryTestName[bottomTestTypeIdx], 2);
1011     callX     = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_CALLABLE_BIT_KHR,
1012                                      shaderNameIt->second[5], rayQueryTestName[bottomTestTypeIdx], 3);
1013     bool hitX = isectX || ahitX || chitX;
1014 
1015     rtPipeline = rayTracingPipeline->createPipeline(vkd, device, *pipelineLayout);
1016 
1017     uint32_t shaderGroupHandleSize    = getShaderGroupHandleSize(vki, physicalDevice);
1018     uint32_t shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice);
1019 
1020     if (rgenX)
1021         raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(
1022             vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
1023     if (hitX)
1024         hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(
1025             vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
1026     if (missX)
1027         missShaderBindingTable = rayTracingPipeline->createShaderBindingTable(
1028             vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1);
1029     if (callX)
1030         callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(
1031             vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 3, 1);
1032 }
1033 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)1034 void RayTracingConfiguration::fillCommandBuffer(
1035     Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
1036     const VkWriteDescriptorSetAccelerationStructureKHR &rayQueryAccelerationStructureWriteDescriptorSet,
1037     const VkDescriptorImageInfo &resultImageInfo)
1038 {
1039     const InstanceInterface &vki          = context.getInstanceInterface();
1040     const DeviceInterface &vkd            = context.getDeviceInterface();
1041     const VkDevice device                 = context.getDevice();
1042     const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1043     Allocator &allocator                  = context.getDefaultAllocator();
1044 
1045     {
1046         de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure =
1047             makeBottomLevelAccelerationStructure();
1048         bottomLevelAccelerationStructure->setGeometryCount(1);
1049 
1050         de::SharedPtr<RaytracedGeometryBase> geometry;
1051         if (testParams.shaderSourceType != SST_INTERSECTION_SHADER)
1052         {
1053             tcu::Vec3 v0(0.0f, float(testParams.height), 0.0f);
1054             tcu::Vec3 v1(0.0f, 0.0f, 0.0f);
1055             tcu::Vec3 v2(float(testParams.width), float(testParams.height), 0.0f);
1056             tcu::Vec3 v3(float(testParams.width), 0.0f, 0.0f);
1057             tcu::Vec3 missOffset(0.0f, 0.0f, 0.0f);
1058             if (testParams.shaderSourceType == SST_MISS_SHADER)
1059                 missOffset = tcu::Vec3(1.0f + float(testParams.width), 0.0f, 0.0f);
1060 
1061             geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_FORMAT_R32G32B32_SFLOAT,
1062                                              VK_INDEX_TYPE_NONE_KHR);
1063             geometry->addVertex(v0 + missOffset);
1064             geometry->addVertex(v1 + missOffset);
1065             geometry->addVertex(v2 + missOffset);
1066             geometry->addVertex(v2 + missOffset);
1067             geometry->addVertex(v1 + missOffset);
1068             geometry->addVertex(v3 + missOffset);
1069         }
1070         else // testParams.shaderSourceType == SST_INTERSECTION_SHADER
1071         {
1072             tcu::Vec3 v0(0.0f, 0.0f, -0.1f);
1073             tcu::Vec3 v1(float(testParams.width), float(testParams.height), 0.1f);
1074 
1075             geometry =
1076                 makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1077             geometry->addVertex(v0);
1078             geometry->addVertex(v1);
1079         }
1080         bottomLevelAccelerationStructure->addGeometry(geometry);
1081         bottomLevelAccelerationStructures.push_back(
1082             de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1083 
1084         for (auto &blas : bottomLevelAccelerationStructures)
1085             blas->createAndBuild(vkd, device, commandBuffer, allocator);
1086     }
1087 
1088     topLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1089     topLevelAccelerationStructure->setInstanceCount(1);
1090     topLevelAccelerationStructure->addInstance(bottomLevelAccelerationStructures[0]);
1091     topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1092 
1093     const TopLevelAccelerationStructure *topLevelAccelerationStructurePtr = topLevelAccelerationStructure.get();
1094     VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = {
1095         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, //  VkStructureType sType;
1096         DE_NULL,                                                           //  const void* pNext;
1097         1u,                                                                //  uint32_t accelerationStructureCount;
1098         topLevelAccelerationStructurePtr->getPtr(), //  const VkAccelerationStructureKHR* pAccelerationStructures;
1099     };
1100 
1101     DescriptorSetUpdateBuilder()
1102         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
1103                      VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
1104         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
1105                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1106         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u),
1107                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
1108         .update(vkd, device);
1109 
1110     vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1,
1111                               &descriptorSet.get(), 0, DE_NULL);
1112 
1113     vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *rtPipeline);
1114 
1115     uint32_t shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice);
1116     VkStridedDeviceAddressRegionKHR raygenShaderBindingTableRegion =
1117         raygenShaderBindingTable.get() != DE_NULL ?
1118             makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0),
1119                                               shaderGroupHandleSize, shaderGroupHandleSize) :
1120             makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1121     VkStridedDeviceAddressRegionKHR hitShaderBindingTableRegion =
1122         hitShaderBindingTable.get() != DE_NULL ?
1123             makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0),
1124                                               shaderGroupHandleSize, shaderGroupHandleSize) :
1125             makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1126     VkStridedDeviceAddressRegionKHR missShaderBindingTableRegion =
1127         missShaderBindingTable.get() != DE_NULL ?
1128             makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0),
1129                                               shaderGroupHandleSize, shaderGroupHandleSize) :
1130             makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1131     VkStridedDeviceAddressRegionKHR callableShaderBindingTableRegion =
1132         callableShaderBindingTable.get() != DE_NULL ?
1133             makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0),
1134                                               shaderGroupHandleSize, shaderGroupHandleSize) :
1135             makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1136 
1137     cmdTraceRays(vkd, commandBuffer, &raygenShaderBindingTableRegion, &missShaderBindingTableRegion,
1138                  &hitShaderBindingTableRegion, &callableShaderBindingTableRegion, testParams.width, testParams.height,
1139                  1);
1140 }
1141 
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)1142 bool RayTracingConfiguration::verifyImage(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams)
1143 {
1144     // create result image
1145     const bool allMiss             = (testParams.emptyASCase != EmptyAccelerationStructureCase::NOT_EMPTY);
1146     tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat());
1147     tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2,
1148                                              resultBuffer->getAllocation().getHostPtr());
1149 
1150     // create reference image
1151     std::vector<uint32_t> reference(testParams.width * testParams.height * 2);
1152     tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
1153 
1154     tcu::UVec4 missValue(0, 0, 0, 0);
1155     tcu::UVec4 hitValue(1, 0, 0, 0);
1156 
1157     for (uint32_t y = 0; y < testParams.height; ++y)
1158         for (uint32_t x = 0; x < testParams.width; ++x)
1159         {
1160             if (allMiss || ((x + y) % 2) == 0)
1161             {
1162                 referenceAccess.setPixel(missValue, x, y, 0);
1163                 referenceAccess.setPixel(missValue, x, y, 1);
1164             }
1165             else
1166             {
1167                 referenceAccess.setPixel(hitValue, x, y, 0);
1168                 referenceAccess.setPixel(hitValue, x, y, 1);
1169             }
1170         }
1171 
1172     // compare result and reference
1173     return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess,
1174                                     resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
1175 }
1176 
getResultImageFormat()1177 VkFormat RayTracingConfiguration::getResultImageFormat()
1178 {
1179     return VK_FORMAT_R32_UINT;
1180 }
1181 
getResultImageFormatSize()1182 size_t RayTracingConfiguration::getResultImageFormatSize()
1183 {
1184     return sizeof(uint32_t);
1185 }
1186 
getClearValue()1187 VkClearValue RayTracingConfiguration::getClearValue()
1188 {
1189     return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
1190 }
1191 
createTestConfiguration(const ShaderSourcePipeline & shaderSourcePipeline)1192 de::SharedPtr<TestConfiguration> createTestConfiguration(const ShaderSourcePipeline &shaderSourcePipeline)
1193 {
1194     switch (shaderSourcePipeline)
1195     {
1196     case SSP_GRAPHICS_PIPELINE:
1197         return de::SharedPtr<TestConfiguration>(new GraphicsConfiguration());
1198     case SSP_COMPUTE_PIPELINE:
1199         return de::SharedPtr<TestConfiguration>(new ComputeConfiguration());
1200     case SSP_RAY_TRACING_PIPELINE:
1201         return de::SharedPtr<TestConfiguration>(new RayTracingConfiguration());
1202     default:
1203         TCU_THROW(InternalError, "Wrong shader source pipeline");
1204     }
1205     return de::SharedPtr<TestConfiguration>();
1206 }
1207 
1208 class CheckerboardSceneBuilder : public SceneBuilder
1209 {
1210 public:
1211     std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> initBottomAccelerationStructures(
1212         Context &context, TestParams &testParams) override;
1213     de::MovePtr<TopLevelAccelerationStructure> initTopAccelerationStructure(
1214         Context &context, TestParams &testParams,
1215         std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> &bottomLevelAccelerationStructures) override;
1216 };
1217 
initBottomAccelerationStructures(Context & context,TestParams & testParams)1218 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> CheckerboardSceneBuilder::initBottomAccelerationStructures(
1219     Context &context, TestParams &testParams)
1220 {
1221     DE_UNREF(context);
1222 
1223     // Cull flags can only be used with triangles.
1224     DE_ASSERT(testParams.cullFlags == InstanceCullFlags::NONE ||
1225               testParams.bottomTestType == BottomTestType::TRIANGLES);
1226 
1227     std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> result;
1228 
1229     const auto instanceFlags = getCullFlags(testParams.cullFlags);
1230 
1231     tcu::Vec3 v0(0.0, 1.0, 0.0);
1232     tcu::Vec3 v1(0.0, 0.0, 0.0);
1233     tcu::Vec3 v2(1.0, 1.0, 0.0);
1234     tcu::Vec3 v3(1.0, 0.0, 0.0);
1235 
1236     // Different vertex configurations of a triangle whose parameter x is set to NaN during inactive_triangles tests
1237     const bool nanConfig[4][4] = {
1238         {true, true, true, true},
1239         {false, true, true, false},
1240         {false, false, true, false},
1241         {false, true, false, false},
1242     };
1243 
1244     unsigned int geometryCount = testParams.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_TRIANGLES ? 4U : 1U;
1245 
1246     if (testParams.topTestType == TopTestType::DIFFERENT_INSTANCES)
1247     {
1248         de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure =
1249             makeBottomLevelAccelerationStructure();
1250         bottomLevelAccelerationStructure->setGeometryCount(1u);
1251         de::SharedPtr<RaytracedGeometryBase> geometry;
1252         if (testParams.bottomTestType == BottomTestType::TRIANGLES)
1253         {
1254             geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, testParams.vertexFormat,
1255                                              testParams.indexType, testParams.padVertices);
1256             if (testParams.indexType == VK_INDEX_TYPE_NONE_KHR)
1257             {
1258                 if (instanceFlags == 0u)
1259                 {
1260                     geometry->addVertex(v0);
1261                     geometry->addVertex(v1);
1262                     geometry->addVertex(v2);
1263                     geometry->addVertex(v2);
1264                     geometry->addVertex(v1);
1265                     geometry->addVertex(v3);
1266                 }
1267                 else // Counterclockwise so the flags will be needed for the geometry to be visible.
1268                 {
1269                     geometry->addVertex(v2);
1270                     geometry->addVertex(v1);
1271                     geometry->addVertex(v0);
1272                     geometry->addVertex(v3);
1273                     geometry->addVertex(v1);
1274                     geometry->addVertex(v2);
1275                 }
1276             }
1277             else // m_data.indexType != VK_INDEX_TYPE_NONE_KHR
1278             {
1279                 geometry->addVertex(v0);
1280                 geometry->addVertex(v1);
1281                 geometry->addVertex(v2);
1282                 geometry->addVertex(v3);
1283 
1284                 if (instanceFlags == 0u)
1285                 {
1286                     geometry->addIndex(0);
1287                     geometry->addIndex(1);
1288                     geometry->addIndex(2);
1289                     geometry->addIndex(2);
1290                     geometry->addIndex(1);
1291                     geometry->addIndex(3);
1292                 }
1293                 else // Counterclockwise so the flags will be needed for the geometry to be visible.
1294                 {
1295                     geometry->addIndex(2);
1296                     geometry->addIndex(1);
1297                     geometry->addIndex(0);
1298                     geometry->addIndex(3);
1299                     geometry->addIndex(1);
1300                     geometry->addIndex(2);
1301                 }
1302             }
1303         }
1304         else // m_data.bottomTestType == BTT_AABBS
1305         {
1306             geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, testParams.vertexFormat, testParams.indexType,
1307                                              testParams.padVertices);
1308 
1309             if (!testParams.padVertices)
1310             {
1311                 // Single AABB.
1312                 geometry->addVertex(tcu::Vec3(0.0f, 0.0f, -0.1f));
1313                 geometry->addVertex(tcu::Vec3(1.0f, 1.0f, 0.1f));
1314             }
1315             else
1316             {
1317                 // Multiple AABBs covering the same space.
1318                 geometry->addVertex(tcu::Vec3(0.0f, 0.0f, -0.1f));
1319                 geometry->addVertex(tcu::Vec3(0.5f, 0.5f, 0.1f));
1320 
1321                 geometry->addVertex(tcu::Vec3(0.5f, 0.5f, -0.1f));
1322                 geometry->addVertex(tcu::Vec3(1.0f, 1.0f, 0.1f));
1323 
1324                 geometry->addVertex(tcu::Vec3(0.0f, 0.5f, -0.1f));
1325                 geometry->addVertex(tcu::Vec3(0.5f, 1.0f, 0.1f));
1326 
1327                 geometry->addVertex(tcu::Vec3(0.5f, 0.0f, -0.1f));
1328                 geometry->addVertex(tcu::Vec3(1.0f, 0.5f, 0.1f));
1329             }
1330         }
1331 
1332         bottomLevelAccelerationStructure->addGeometry(geometry);
1333         result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1334     }
1335     else // m_data.topTestType == TTT_IDENTICAL_INSTANCES
1336     {
1337         tcu::TextureFormat texFormat = mapVkFormat(testParams.vertexFormat);
1338         tcu::Vec3 scale(1.0f, 1.0f, 1.0f);
1339         if (tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
1340             scale = tcu::Vec3(1.0f / float(testParams.width), 1.0f / float(testParams.height), 1.0f);
1341 
1342         // triangle and aabb tests use geometries/aabbs with different vertex positions and the same identity matrix in each instance data
1343         for (uint32_t y = 0; y < testParams.height; ++y)
1344             for (uint32_t x = 0; x < testParams.width; ++x)
1345             {
1346                 // let's build a chessboard of geometries
1347                 if (((x + y) % 2) == 0)
1348                     continue;
1349                 tcu::Vec3 xyz((float)x, (float)y, 0.0f);
1350 
1351                 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure =
1352                     makeBottomLevelAccelerationStructure();
1353                 bottomLevelAccelerationStructure->setGeometryCount(geometryCount);
1354 
1355                 if (testParams.bottomTestType == BottomTestType::TRIANGLES)
1356                 {
1357                     for (unsigned int i = 0; i < geometryCount; i++)
1358                     {
1359                         de::SharedPtr<RaytracedGeometryBase> geometry;
1360                         geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, testParams.vertexFormat,
1361                                                          testParams.indexType, testParams.padVertices);
1362 
1363                         if (testParams.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_TRIANGLES)
1364                         {
1365                             const auto nanValue = tcu::Float32::nan().asFloat();
1366 
1367                             if (nanConfig[i][0])
1368                                 v0.x() = nanValue;
1369                             if (nanConfig[i][1])
1370                                 v1.x() = nanValue;
1371                             if (nanConfig[i][2])
1372                                 v2.x() = nanValue;
1373                             if (nanConfig[i][3])
1374                                 v3.x() = nanValue;
1375                         }
1376 
1377                         if (testParams.indexType == VK_INDEX_TYPE_NONE_KHR)
1378                         {
1379                             if (instanceFlags == 0u)
1380                             {
1381                                 geometry->addVertex(scale * (xyz + v0));
1382                                 geometry->addVertex(scale * (xyz + v1));
1383                                 geometry->addVertex(scale * (xyz + v2));
1384                                 geometry->addVertex(scale * (xyz + v2));
1385                                 geometry->addVertex(scale * (xyz + v1));
1386                                 geometry->addVertex(scale * (xyz + v3));
1387                             }
1388                             else // Counterclockwise so the flags will be needed for the geometry to be visible.
1389                             {
1390                                 geometry->addVertex(scale * (xyz + v2));
1391                                 geometry->addVertex(scale * (xyz + v1));
1392                                 geometry->addVertex(scale * (xyz + v0));
1393                                 geometry->addVertex(scale * (xyz + v3));
1394                                 geometry->addVertex(scale * (xyz + v1));
1395                                 geometry->addVertex(scale * (xyz + v2));
1396                             }
1397                         }
1398 
1399                         else
1400                         {
1401                             geometry->addVertex(scale * (xyz + v0));
1402                             geometry->addVertex(scale * (xyz + v1));
1403                             geometry->addVertex(scale * (xyz + v2));
1404                             geometry->addVertex(scale * (xyz + v3));
1405 
1406                             if (instanceFlags == 0u)
1407                             {
1408                                 geometry->addIndex(0);
1409                                 geometry->addIndex(1);
1410                                 geometry->addIndex(2);
1411                                 geometry->addIndex(2);
1412                                 geometry->addIndex(1);
1413                                 geometry->addIndex(3);
1414                             }
1415                             else // Counterclockwise so the flags will be needed for the geometry to be visible.
1416                             {
1417                                 geometry->addIndex(2);
1418                                 geometry->addIndex(1);
1419                                 geometry->addIndex(0);
1420                                 geometry->addIndex(3);
1421                                 geometry->addIndex(1);
1422                                 geometry->addIndex(2);
1423                             }
1424                         }
1425 
1426                         bottomLevelAccelerationStructure->addGeometry(geometry);
1427                     }
1428                 }
1429                 else // testParams.bottomTestType == BTT_AABBS
1430                 {
1431                     de::SharedPtr<RaytracedGeometryBase> geometry;
1432                     geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, testParams.vertexFormat,
1433                                                      testParams.indexType, testParams.padVertices);
1434 
1435                     if (!testParams.padVertices)
1436                     {
1437                         // Single AABB.
1438                         geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.0f, -0.1f)));
1439                         geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 1.0f, 0.1f)));
1440                     }
1441                     else
1442                     {
1443                         // Multiple AABBs covering the same space.
1444                         geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.0f, -0.1f)));
1445                         geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.5f, 0.1f)));
1446 
1447                         geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.5f, -0.1f)));
1448                         geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 1.0f, 0.1f)));
1449 
1450                         geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.5f, -0.1f)));
1451                         geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 1.0f, 0.1f)));
1452 
1453                         geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.0f, -0.1f)));
1454                         geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 0.5f, 0.1f)));
1455                     }
1456 
1457                     bottomLevelAccelerationStructure->addGeometry(geometry);
1458                 }
1459 
1460                 result.push_back(
1461                     de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1462             }
1463     }
1464 
1465     return result;
1466 }
1467 
initTopAccelerationStructure(Context & context,TestParams & testParams,std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> & bottomLevelAccelerationStructures)1468 de::MovePtr<TopLevelAccelerationStructure> CheckerboardSceneBuilder::initTopAccelerationStructure(
1469     Context &context, TestParams &testParams,
1470     std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> &bottomLevelAccelerationStructures)
1471 {
1472     DE_UNREF(context);
1473 
1474     const auto instanceCount = testParams.width * testParams.height / 2u;
1475     const auto instanceFlags = getCullFlags(testParams.cullFlags);
1476 
1477     de::MovePtr<TopLevelAccelerationStructure> result = makeTopLevelAccelerationStructure();
1478     result->setInstanceCount(instanceCount);
1479 
1480     if (testParams.topTestType == TopTestType::DIFFERENT_INSTANCES)
1481     {
1482 
1483         for (uint32_t y = 0; y < testParams.height; ++y)
1484             for (uint32_t x = 0; x < testParams.width; ++x)
1485             {
1486                 if (((x + y) % 2) == 0)
1487                     continue;
1488                 const VkTransformMatrixKHR transformMatrixKHR = {{
1489                     //  float matrix[3][4];
1490                     {1.0f, 0.0f, 0.0f, (float)x},
1491                     {0.0f, 1.0f, 0.0f, (float)y},
1492                     {0.0f, 0.0f, 1.0f, 0.0f},
1493                 }};
1494                 result->addInstance(bottomLevelAccelerationStructures[0], transformMatrixKHR, 0u, 0xFFu, 0u,
1495                                     instanceFlags);
1496             }
1497     }
1498     else // testParams.topTestType == TTT_IDENTICAL_INSTANCES
1499     {
1500         tcu::TextureFormat texFormat = mapVkFormat(testParams.vertexFormat);
1501         tcu::Vec3 scale(1.0f, 1.0f, 1.0f);
1502         if (tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
1503             scale = tcu::Vec3(float(testParams.width), float(testParams.height), 1.0f);
1504 
1505         const VkTransformMatrixKHR transformMatrixKHR = {{
1506             //  float matrix[3][4];
1507             {scale.x(), 0.0f, 0.0f, 0.0f},
1508             {0.0f, scale.y(), 0.0f, 0.0f},
1509             {0.0f, 0.0f, scale.z(), 0.0f},
1510         }};
1511 
1512         uint32_t currentInstanceIndex = 0;
1513 
1514         for (uint32_t y = 0; y < testParams.height; ++y)
1515             for (uint32_t x = 0; x < testParams.width; ++x)
1516             {
1517                 if (((x + y) % 2) == 0)
1518                     continue;
1519                 result->addInstance(bottomLevelAccelerationStructures[currentInstanceIndex++], transformMatrixKHR, 0u,
1520                                     0xFFu, 0u, instanceFlags);
1521             }
1522     }
1523 
1524     return result;
1525 }
1526 
commonASTestsCheckSupport(Context & context)1527 void commonASTestsCheckSupport(Context &context)
1528 {
1529     context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
1530     context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
1531     context.requireDeviceFunctionality("VK_KHR_ray_query");
1532 
1533     const VkPhysicalDeviceRayQueryFeaturesKHR &rayQueryFeaturesKHR = context.getRayQueryFeatures();
1534     if (rayQueryFeaturesKHR.rayQuery == false)
1535         TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");
1536 
1537     const VkPhysicalDeviceAccelerationStructureFeaturesKHR &accelerationStructureFeaturesKHR =
1538         context.getAccelerationStructureFeatures();
1539     if (accelerationStructureFeaturesKHR.accelerationStructure == false)
1540         TCU_THROW(TestError,
1541                   "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
1542 }
1543 
1544 class RayQueryASBasicTestCase : public TestCase
1545 {
1546 public:
1547     RayQueryASBasicTestCase(tcu::TestContext &context, const char *name, const TestParams &data);
1548     ~RayQueryASBasicTestCase(void);
1549 
1550     virtual void checkSupport(Context &context) const;
1551     virtual void initPrograms(SourceCollections &programCollection) const;
1552     virtual TestInstance *createInstance(Context &context) const;
1553 
1554 protected:
1555     TestParams m_data;
1556 };
1557 
1558 class RayQueryASFuncArgTestCase : public RayQueryASBasicTestCase
1559 {
1560 public:
1561     RayQueryASFuncArgTestCase(tcu::TestContext &context, const char *name, const TestParams &data);
~RayQueryASFuncArgTestCase(void)1562     ~RayQueryASFuncArgTestCase(void)
1563     {
1564     }
1565 
1566     virtual void initPrograms(SourceCollections &programCollection) const;
1567 };
1568 
1569 class RayQueryASBasicTestInstance : public TestInstance
1570 {
1571 public:
1572     RayQueryASBasicTestInstance(Context &context, const TestParams &data);
1573     ~RayQueryASBasicTestInstance(void);
1574     tcu::TestStatus iterate(void);
1575 
1576 protected:
1577     bool iterateNoWorkers(void);
1578     bool iterateWithWorkers(void);
1579     de::MovePtr<BufferWithMemory> runTest(TestConfiguration *testConfiguration, SceneBuilder *sceneBuilder,
1580                                           const uint32_t workerThreadsCount);
1581 
1582 private:
1583     TestParams m_data;
1584 };
1585 
RayQueryASBasicTestCase(tcu::TestContext & context,const char * name,const TestParams & data)1586 RayQueryASBasicTestCase::RayQueryASBasicTestCase(tcu::TestContext &context, const char *name, const TestParams &data)
1587     : vkt::TestCase(context, name)
1588     , m_data(data)
1589 {
1590 }
1591 
~RayQueryASBasicTestCase(void)1592 RayQueryASBasicTestCase::~RayQueryASBasicTestCase(void)
1593 {
1594 }
1595 
checkSupport(Context & context) const1596 void RayQueryASBasicTestCase::checkSupport(Context &context) const
1597 {
1598     commonASTestsCheckSupport(context);
1599 
1600     const VkPhysicalDeviceFeatures2 &features2 = context.getDeviceFeatures2();
1601 
1602     if ((m_data.shaderSourceType == SST_TESSELATION_CONTROL_SHADER ||
1603          m_data.shaderSourceType == SST_TESSELATION_EVALUATION_SHADER) &&
1604         features2.features.tessellationShader == false)
1605         TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.tessellationShader");
1606 
1607     if (m_data.shaderSourceType == SST_GEOMETRY_SHADER && features2.features.geometryShader == false)
1608         TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.geometryShader");
1609 
1610     if (m_data.shaderSourceType == SST_RAY_GENERATION_SHADER || m_data.shaderSourceType == SST_INTERSECTION_SHADER ||
1611         m_data.shaderSourceType == SST_ANY_HIT_SHADER || m_data.shaderSourceType == SST_CLOSEST_HIT_SHADER ||
1612         m_data.shaderSourceType == SST_MISS_SHADER || m_data.shaderSourceType == SST_CALLABLE_SHADER)
1613     {
1614         context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1615 
1616         const VkPhysicalDeviceRayTracingPipelineFeaturesKHR &rayTracingPipelineFeaturesKHR =
1617             context.getRayTracingPipelineFeatures();
1618 
1619         if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == false)
1620             TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1621     }
1622 
1623     switch (m_data.shaderSourceType)
1624     {
1625     case SST_VERTEX_SHADER:
1626     case SST_TESSELATION_CONTROL_SHADER:
1627     case SST_TESSELATION_EVALUATION_SHADER:
1628     case SST_GEOMETRY_SHADER:
1629         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
1630         break;
1631     default:
1632         break;
1633     }
1634 
1635     const VkPhysicalDeviceAccelerationStructureFeaturesKHR &accelerationStructureFeaturesKHR =
1636         context.getAccelerationStructureFeatures();
1637     if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR &&
1638         accelerationStructureFeaturesKHR.accelerationStructureHostCommands == false)
1639         TCU_THROW(NotSupportedError,
1640                   "Requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructureHostCommands");
1641 
1642     // Check supported vertex format.
1643     checkAccelerationStructureVertexBufferFormat(context.getInstanceInterface(), context.getPhysicalDevice(),
1644                                                  m_data.vertexFormat);
1645 }
1646 
initPrograms(SourceCollections & programCollection) const1647 void RayQueryASBasicTestCase::initPrograms(SourceCollections &programCollection) const
1648 {
1649     const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1650 
1651     // create parts of programs responsible for test execution
1652     std::vector<std::string> rayQueryTest;
1653     std::vector<std::string> rayQueryTestName;
1654     rayQueryTestName.push_back("as_triangle");
1655     rayQueryTestName.push_back("as_aabb");
1656 
1657     {
1658         std::stringstream css;
1659         css << "  float tmin     = 0.0;\n"
1660                "  float tmax     = 1.0;\n"
1661                "  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1662                "  rayQueryEXT rq;\n"
1663                "  rayQueryInitializeEXT(rq, rqTopLevelAS, "
1664             << ((m_data.cullFlags == InstanceCullFlags::NONE) ? "0" : "gl_RayFlagsCullBackFacingTrianglesEXT")
1665             << ", 0xFF, origin, tmin, direct, tmax);\n"
1666                "  if(rayQueryProceedEXT(rq))\n"
1667                "  {\n"
1668                "    if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT)\n"
1669                "    {\n"
1670                "      hitValue.y = 1;\n"
1671                "      hitValue.x = 1;\n"
1672                "    }\n"
1673                "  }\n";
1674         rayQueryTest.push_back(css.str());
1675     }
1676     {
1677         std::stringstream css;
1678         css << "  float tmin     = 0.0;\n"
1679                "  float tmax     = 1.0;\n"
1680                "  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1681                "  rayQueryEXT rq;\n"
1682                "  rayQueryInitializeEXT(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);\n"
1683                "  if(rayQueryProceedEXT(rq))\n"
1684                "  {\n"
1685                "    if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionAABBEXT)\n"
1686                "    {\n"
1687                "      hitValue.y = 1;\n"
1688                "      hitValue.x = 1;\n"
1689                "    }\n"
1690                "  }\n";
1691         rayQueryTest.push_back(css.str());
1692     }
1693 
1694     const auto bottomTestTypeIdx = static_cast<int>(m_data.bottomTestType);
1695 
1696     // create all programs
1697     if (m_data.shaderSourcePipeline == SSP_GRAPHICS_PIPELINE)
1698     {
1699         {
1700             std::stringstream css;
1701             css << "#version 460 core\n"
1702                    "layout (location = 0) in vec3 position;\n"
1703                    "out gl_PerVertex\n"
1704                    "{\n"
1705                    "  vec4 gl_Position;\n"
1706                    "};\n"
1707                    "void main()\n"
1708                    "{\n"
1709                    "  gl_Position = vec4(position, 1.0);\n"
1710                    "}\n";
1711             programCollection.glslSources.add("vert") << glu::VertexSource(css.str()) << buildOptions;
1712         }
1713 
1714         {
1715             std::stringstream css;
1716             css << "#version 460 core\n"
1717                    "layout (location = 0) in vec3 position;\n"
1718                    "out gl_PerVertex\n"
1719                    "{\n"
1720                    "  vec4 gl_Position;\n"
1721                    "};\n"
1722                    "layout(location = 0) out int vertexIndex;\n"
1723                    "void main()\n"
1724                    "{\n"
1725                    "  gl_Position = vec4(position, 1.0);\n"
1726                    "  vertexIndex = gl_VertexIndex;\n"
1727                    "}\n";
1728             programCollection.glslSources.add("vert_vid") << glu::VertexSource(css.str()) << buildOptions;
1729         }
1730 
1731         {
1732             std::stringstream css;
1733             css << "#version 460 core\n"
1734                    "#extension GL_EXT_ray_query : require\n"
1735                    "layout (location = 0) in vec3 position;\n"
1736                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1737                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1738                    "void main()\n"
1739                    "{\n"
1740                    "  vec3  origin   = vec3(float(position.x) + 0.5, float(position.y) + 0.5, 0.5);\n"
1741                    "  uvec4 hitValue = uvec4(0,0,0,0);\n"
1742                 << rayQueryTest[bottomTestTypeIdx]
1743                 << "  imageStore(result, ivec3(gl_VertexIndex, 0, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1744                    "  imageStore(result, ivec3(gl_VertexIndex, 0, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1745                    "  gl_Position = vec4(position,1);\n"
1746                    "}\n";
1747             std::stringstream cssName;
1748             cssName << "vert_" << rayQueryTestName[bottomTestTypeIdx];
1749 
1750             programCollection.glslSources.add(cssName.str()) << glu::VertexSource(css.str()) << buildOptions;
1751         }
1752 
1753         {
1754             std::stringstream css;
1755             css << "#version 460 core\n"
1756                    "#extension GL_EXT_tessellation_shader : require\n"
1757                    "in gl_PerVertex {\n"
1758                    "  vec4  gl_Position;\n"
1759                    "} gl_in[];\n"
1760                    "layout(vertices = 3) out;\n"
1761                    "void main (void)\n"
1762                    "{\n"
1763                    "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1764                    "  gl_TessLevelInner[0] = 1;\n"
1765                    "  gl_TessLevelOuter[0] = 1;\n"
1766                    "  gl_TessLevelOuter[1] = 1;\n"
1767                    "  gl_TessLevelOuter[2] = 1;\n"
1768                    "}\n";
1769             programCollection.glslSources.add("tesc") << glu::TessellationControlSource(css.str()) << buildOptions;
1770         }
1771 
1772         {
1773             std::stringstream css;
1774             css << "#version 460 core\n"
1775                    "#extension GL_EXT_tessellation_shader : require\n"
1776                    "#extension GL_EXT_ray_query : require\n"
1777                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1778                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1779                    "in gl_PerVertex {\n"
1780                    "  vec4  gl_Position;\n"
1781                    "} gl_in[];\n"
1782                    "layout(vertices = 3) out;\n"
1783                    "void main (void)\n"
1784                    "{\n"
1785                    "  vec3  origin   = vec3(gl_in[gl_InvocationID].gl_Position.x + 0.5, "
1786                    "gl_in[gl_InvocationID].gl_Position.y + 0.5, 0.5);\n"
1787                    "  uvec4 hitValue = uvec4(0,0,0,0);\n"
1788                 << rayQueryTest[bottomTestTypeIdx]
1789                 << "  imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1790                    "  imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1791                    "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1792                    "  gl_TessLevelInner[0] = 1;\n"
1793                    "  gl_TessLevelOuter[0] = 1;\n"
1794                    "  gl_TessLevelOuter[1] = 1;\n"
1795                    "  gl_TessLevelOuter[2] = 1;\n"
1796                    "}\n";
1797             std::stringstream cssName;
1798             cssName << "tesc_" << rayQueryTestName[bottomTestTypeIdx];
1799 
1800             programCollection.glslSources.add(cssName.str())
1801                 << glu::TessellationControlSource(css.str()) << buildOptions;
1802         }
1803 
1804         {
1805             std::stringstream css;
1806             css << "#version 460 core\n"
1807                    "#extension GL_EXT_tessellation_shader : require\n"
1808                    "#extension GL_EXT_ray_query : require\n"
1809                    "layout(triangles, equal_spacing, ccw) in;\n"
1810                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1811                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1812                    "void main (void)\n"
1813                    "{\n"
1814                    "  for (int i = 0; i < 3; ++i)\n"
1815                    "  {\n"
1816                    "    vec3  origin   = vec3(gl_in[i].gl_Position.x + 0.5, gl_in[i].gl_Position.y + 0.5, 0.5);\n"
1817                    "    uvec4 hitValue = uvec4(0,0,0,0);\n"
1818                 << rayQueryTest[bottomTestTypeIdx]
1819                 << "    imageStore(result, ivec3(gl_PrimitiveID, i, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1820                    "    imageStore(result, ivec3(gl_PrimitiveID, i, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1821                    "  }\n"
1822                    "  gl_Position = gl_in[0].gl_Position;\n"
1823                    "}\n";
1824             std::stringstream cssName;
1825             cssName << "tese_" << rayQueryTestName[bottomTestTypeIdx];
1826 
1827             programCollection.glslSources.add(cssName.str())
1828                 << glu::TessellationEvaluationSource(css.str()) << buildOptions;
1829         }
1830 
1831         {
1832             std::stringstream css;
1833             css << "#version 460 core\n"
1834                    "#extension GL_EXT_tessellation_shader : require\n"
1835                    "layout(triangles, equal_spacing, ccw) in;\n"
1836                    "void main (void)\n"
1837                    "{\n"
1838                    "  gl_Position = gl_in[0].gl_Position;\n"
1839                    "}\n";
1840 
1841             programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(css.str()) << buildOptions;
1842         }
1843 
1844         {
1845             std::stringstream css;
1846             css << "#version 460 core\n"
1847                    "#extension GL_EXT_ray_query : require\n"
1848                    "layout(triangles) in;\n"
1849                    "layout (triangle_strip, max_vertices = 4) out;\n"
1850                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1851                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1852                    "\n"
1853                    "in gl_PerVertex {\n"
1854                    "  vec4  gl_Position;\n"
1855                    "} gl_in[];\n"
1856                    "layout(location = 0) in int vertexIndex[];\n"
1857                    "out gl_PerVertex {\n"
1858                    "  vec4 gl_Position;\n"
1859                    "};\n"
1860                    "void main (void)\n"
1861                    "{\n"
1862                    "  // geometry shader may reorder the vertices, keeping only the winding of the triangles.\n"
1863                    "  // To iterate from the 'first vertex' of the triangle we need to find it first by looking for\n"
1864                    "  // smallest vertex index value.\n"
1865                    "  int minVertexIndex = 10000;"
1866                    "  int firstVertex;"
1867                    "  for (int i = 0; i < gl_in.length(); ++i)\n"
1868                    "  {\n"
1869                    "    if (minVertexIndex > vertexIndex[i])\n"
1870                    "    {\n"
1871                    "      minVertexIndex = vertexIndex[i];\n"
1872                    "      firstVertex    = i;\n"
1873                    "    }\n"
1874                    "  }\n"
1875                    "  for (int j = 0; j < gl_in.length(); ++j)\n"
1876                    "  {\n"
1877                    "    // iterate starting at firstVertex, possibly wrapping around, so the triangle is\n"
1878                    "    // always iterated starting from the smallest vertex index, as found above.\n"
1879                    "    int i = (firstVertex + j) % gl_in.length();\n"
1880                    "    vec3  origin   = vec3(gl_in[i].gl_Position.x + 0.5, gl_in[i].gl_Position.y + 0.5, 0.5);\n"
1881                    "    uvec4 hitValue = uvec4(0,0,0,0);\n"
1882                 << rayQueryTest[bottomTestTypeIdx]
1883                 << "    imageStore(result, ivec3(gl_PrimitiveIDIn, j, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1884                    "    imageStore(result, ivec3(gl_PrimitiveIDIn, j, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1885                    "    gl_Position      = gl_in[i].gl_Position;\n"
1886                    "    EmitVertex();\n"
1887                    "  }\n"
1888                    "  EndPrimitive();\n"
1889                    "}\n";
1890             std::stringstream cssName;
1891             cssName << "geom_" << rayQueryTestName[bottomTestTypeIdx];
1892 
1893             programCollection.glslSources.add(cssName.str()) << glu::GeometrySource(css.str()) << buildOptions;
1894         }
1895 
1896         {
1897             std::stringstream css;
1898             css << "#version 460 core\n"
1899                    "#extension GL_EXT_ray_query : require\n"
1900                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1901                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1902                    "void main()\n"
1903                    "{\n"
1904                    "  vec3  origin   = vec3(gl_FragCoord.x, gl_FragCoord.y, 0.5);\n"
1905                    "  uvec4 hitValue = uvec4(0,0,0,0);\n"
1906                 << rayQueryTest[bottomTestTypeIdx]
1907                 << "  imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 0), uvec4(hitValue.x, 0, 0, 0));\n"
1908                    "  imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 1), uvec4(hitValue.y, 0, 0, 0));\n"
1909                    "}\n";
1910             std::stringstream cssName;
1911             cssName << "frag_" << rayQueryTestName[bottomTestTypeIdx];
1912 
1913             programCollection.glslSources.add(cssName.str()) << glu::FragmentSource(css.str()) << buildOptions;
1914         }
1915     }
1916     else if (m_data.shaderSourcePipeline == SSP_COMPUTE_PIPELINE)
1917     {
1918         {
1919             std::stringstream css;
1920             css << "#version 460 core\n"
1921                    "#extension GL_EXT_ray_query : require\n"
1922                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1923                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1924                    "void main()\n"
1925                    "{\n"
1926                    "  vec3  origin   = vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + "
1927                    "0.5, 0.5);\n"
1928                    "  uvec4 hitValue = uvec4(0,0,0,0);\n"
1929                 << rayQueryTest[bottomTestTypeIdx]
1930                 << "  imageStore(result, ivec3(gl_GlobalInvocationID.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1931                    "  imageStore(result, ivec3(gl_GlobalInvocationID.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1932                    "}\n";
1933             std::stringstream cssName;
1934             cssName << "comp_" << rayQueryTestName[bottomTestTypeIdx];
1935 
1936             programCollection.glslSources.add(cssName.str()) << glu::ComputeSource(css.str()) << buildOptions;
1937         }
1938     }
1939     else if (m_data.shaderSourcePipeline == SSP_RAY_TRACING_PIPELINE)
1940     {
1941         {
1942             std::stringstream css;
1943             css << "#version 460 core\n"
1944                    "#extension GL_EXT_ray_tracing : require\n"
1945                    "layout(location = 0) rayPayloadEXT uvec4 hitValue;\n"
1946                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1947                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1948                    "void main()\n"
1949                    "{\n"
1950                    "  float tmin     = 0.0;\n"
1951                    "  float tmax     = 1.0;\n"
1952                    "  vec3  origin   = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1953                    "  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1954                    "  hitValue       = uvec4(0,0,0,0);\n"
1955                    "  traceRayEXT(topLevelAS, 0, 0xFF, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
1956                    "  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1957                    "  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1958                    "}\n";
1959             programCollection.glslSources.add("rgen")
1960                 << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1961         }
1962 
1963         {
1964             std::stringstream css;
1965             css << "#version 460 core\n"
1966                    "#extension GL_EXT_ray_tracing : require\n"
1967                    "#extension GL_EXT_ray_query : require\n"
1968                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1969                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1970                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1971                    "void main()\n"
1972                    "{\n"
1973                    "  vec3  origin    = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1974                    "  uvec4  hitValue = uvec4(0,0,0,0);\n"
1975                 << rayQueryTest[bottomTestTypeIdx]
1976                 << "  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1977                    "  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1978                    "}\n";
1979             std::stringstream cssName;
1980             cssName << "rgen_" << rayQueryTestName[bottomTestTypeIdx];
1981 
1982             programCollection.glslSources.add(cssName.str())
1983                 << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1984         }
1985 
1986         {
1987             std::stringstream css;
1988             css << "#version 460 core\n"
1989                    "#extension GL_EXT_ray_tracing : require\n"
1990                    "struct CallValue\n{\n"
1991                    "  vec3  origin;\n"
1992                    "  uvec4 hitValue;\n"
1993                    "};\n"
1994                    "layout(location = 0) callableDataEXT CallValue param;\n"
1995                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1996                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1997                    "void main()\n"
1998                    "{\n"
1999                    "  param.origin   = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
2000                    "  param.hitValue = uvec4(0, 0, 0, 0);\n"
2001                    "  executeCallableEXT(0, 0);\n"
2002                    "  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(param.hitValue.x, 0, 0, 0));\n"
2003                    "  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(param.hitValue.y, 0, 0, 0));\n"
2004                    "}\n";
2005             programCollection.glslSources.add("rgen_call")
2006                 << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
2007         }
2008 
2009         {
2010             std::stringstream css;
2011             css << "#version 460 core\n"
2012                    "#extension GL_EXT_ray_tracing : require\n"
2013                    "hitAttributeEXT uvec4 hitValue;\n"
2014                    "void main()\n"
2015                    "{\n"
2016                    "  reportIntersectionEXT(0.5f, 0);\n"
2017                    "}\n";
2018 
2019             programCollection.glslSources.add("isect")
2020                 << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
2021         }
2022 
2023         {
2024             std::stringstream css;
2025             css << "#version 460 core\n"
2026                    "#extension GL_EXT_ray_tracing : require\n"
2027                    "#extension GL_EXT_ray_query : require\n"
2028                    "hitAttributeEXT uvec4 hitValue;\n"
2029                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2030                    "void main()\n"
2031                    "{\n"
2032                    "  vec3 origin = gl_WorldRayOriginEXT;\n"
2033                    "  hitValue    = uvec4(0,0,0,0);\n"
2034                 << rayQueryTest[bottomTestTypeIdx]
2035                 << "  reportIntersectionEXT(0.5f, 0);\n"
2036                    "}\n";
2037             std::stringstream cssName;
2038             cssName << "isect_" << rayQueryTestName[bottomTestTypeIdx];
2039 
2040             programCollection.glslSources.add(cssName.str())
2041                 << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
2042         }
2043 
2044         {
2045             std::stringstream css;
2046             css << "#version 460 core\n"
2047                    "#extension GL_EXT_ray_tracing : require\n"
2048                    "#extension GL_EXT_ray_query : require\n"
2049                    "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2050                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2051                    "void main()\n"
2052                    "{\n"
2053                    "  vec3 origin = gl_WorldRayOriginEXT;\n"
2054                 << rayQueryTest[bottomTestTypeIdx] << "}\n";
2055             std::stringstream cssName;
2056             cssName << "ahit_" << rayQueryTestName[bottomTestTypeIdx];
2057 
2058             programCollection.glslSources.add(cssName.str())
2059                 << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2060         }
2061 
2062         {
2063             std::stringstream css;
2064             css << "#version 460 core\n"
2065                    "#extension GL_EXT_ray_tracing : require\n"
2066                    "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2067                    "void main()\n"
2068                    "{\n"
2069                    "  hitValue.y = 3;\n"
2070                    "}\n";
2071 
2072             programCollection.glslSources.add("chit")
2073                 << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2074         }
2075 
2076         {
2077             std::stringstream css;
2078             css << "#version 460 core\n"
2079                    "#extension GL_EXT_ray_tracing : require\n"
2080                    "#extension GL_EXT_ray_query : require\n"
2081                    "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2082                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2083                    "void main()\n"
2084                    "{\n"
2085                    "  vec3 origin = gl_WorldRayOriginEXT;\n"
2086                 << rayQueryTest[bottomTestTypeIdx] << "}\n";
2087             std::stringstream cssName;
2088             cssName << "chit_" << rayQueryTestName[bottomTestTypeIdx];
2089 
2090             programCollection.glslSources.add(cssName.str())
2091                 << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2092         }
2093 
2094         {
2095             std::stringstream css;
2096             css << "#version 460 core\n"
2097                    "#extension GL_EXT_ray_tracing : require\n"
2098                    "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2099                    "hitAttributeEXT uvec4 hitAttrib;\n"
2100                    "void main()\n"
2101                    "{\n"
2102                    "  hitValue = hitAttrib;\n"
2103                    "}\n";
2104 
2105             programCollection.glslSources.add("chit_isect")
2106                 << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2107         }
2108 
2109         {
2110             std::stringstream css;
2111             css << "#version 460 core\n"
2112                    "#extension GL_EXT_ray_tracing : require\n"
2113                    "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2114                    "void main()\n"
2115                    "{\n"
2116                    "  hitValue.x = 4;\n"
2117                    "}\n";
2118 
2119             programCollection.glslSources.add("miss")
2120                 << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
2121         }
2122 
2123         {
2124             std::stringstream css;
2125             css << "#version 460 core\n"
2126                    "#extension GL_EXT_ray_tracing : require\n"
2127                    "#extension GL_EXT_ray_query : require\n"
2128                    "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2129                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2130                    "void main()\n"
2131                    "{\n"
2132                    "  vec3 origin = gl_WorldRayOriginEXT;\n"
2133                 << rayQueryTest[bottomTestTypeIdx] << "}\n";
2134             std::stringstream cssName;
2135             cssName << "miss_" << rayQueryTestName[bottomTestTypeIdx];
2136 
2137             programCollection.glslSources.add(cssName.str())
2138                 << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
2139         }
2140 
2141         {
2142             std::stringstream css;
2143             css << "#version 460 core\n"
2144                    "#extension GL_EXT_ray_tracing : require\n"
2145                    "#extension GL_EXT_ray_query : require\n"
2146                    "struct CallValue\n{\n"
2147                    "  vec3  origin;\n"
2148                    "  uvec4 hitValue;\n"
2149                    "};\n"
2150                    "layout(location = 0) callableDataInEXT CallValue result;\n"
2151                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2152                    "void main()\n"
2153                    "{\n"
2154                    "  vec3 origin    = result.origin;\n"
2155                    "  uvec4 hitValue = uvec4(0,0,0,0);\n"
2156                 << rayQueryTest[bottomTestTypeIdx]
2157                 << "  result.hitValue = hitValue;\n"
2158                    "}\n";
2159             std::stringstream cssName;
2160             cssName << "call_" << rayQueryTestName[bottomTestTypeIdx];
2161 
2162             programCollection.glslSources.add(cssName.str())
2163                 << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
2164         }
2165     }
2166 }
2167 
createInstance(Context & context) const2168 TestInstance *RayQueryASBasicTestCase::createInstance(Context &context) const
2169 {
2170     return new RayQueryASBasicTestInstance(context, m_data);
2171 }
2172 
RayQueryASFuncArgTestCase(tcu::TestContext & context,const char * name,const TestParams & data)2173 RayQueryASFuncArgTestCase::RayQueryASFuncArgTestCase(tcu::TestContext &context, const char *name,
2174                                                      const TestParams &data)
2175     : RayQueryASBasicTestCase(context, name, data)
2176 {
2177 }
2178 
initPrograms(SourceCollections & programCollection) const2179 void RayQueryASFuncArgTestCase::initPrograms(SourceCollections &programCollection) const
2180 {
2181     const vk::SpirVAsmBuildOptions spvBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true);
2182 
2183     DE_ASSERT(m_data.shaderSourcePipeline == SSP_COMPUTE_PIPELINE);
2184     DE_ASSERT(m_data.bottomTestType == BottomTestType::TRIANGLES);
2185 
2186     // The SPIR-V assembly shader below is based on the following GLSL code.
2187     // In it, rayQueryInitializeBottomWrapper has been modified to take a
2188     // bare AS as the second argument, instead of a pointer.
2189     //
2190     //    #version 460 core
2191     //    #extension GL_EXT_ray_query : require
2192     // layout(r32ui, set = 0, binding = 0) uniform uimage3D result;
2193     // layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;
2194     //
2195     //    void rayQueryInitializeBottomWrapper(rayQueryEXT rayQuery,
2196     //           accelerationStructureEXT topLevel,
2197     //           uint rayFlags, uint cullMask, vec3 origin,
2198     //           float tMin, vec3 direction, float tMax)
2199     //    {
2200     //   rayQueryInitializeEXT(rayQuery, topLevel, rayFlags, cullMask, origin, tMin, direction, tMax);
2201     //    }
2202     //
2203     //    void rayQueryInitializeTopWrapper(rayQueryEXT rayQuery,
2204     //           accelerationStructureEXT topLevel,
2205     //           uint rayFlags, uint cullMask, vec3 origin,
2206     //           float tMin, vec3 direction, float tMax)
2207     //    {
2208     //   rayQueryInitializeBottomWrapper(rayQuery, topLevel, rayFlags, cullMask, origin, tMin, direction, tMax);
2209     //    }
2210     //
2211     //    void main()
2212     //    {
2213     //   vec3  origin   = vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + 0.5, 0.5);
2214     //   uvec4 hitValue = uvec4(0,0,0,0);
2215     //   float tmin     = 0.0;
2216     //   float tmax     = 1.0;
2217     //   vec3  direct   = vec3(0.0, 0.0, -1.0);
2218     //   rayQueryEXT rq;
2219     //   rayQueryInitializeTopWrapper(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);
2220     //      if(rayQueryProceedEXT(rq))
2221     //      {
2222     //        if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT)
2223     //        {
2224     //       hitValue.y = 1;
2225     //       hitValue.x = 1;
2226     //        }
2227     //      }
2228     //   imageStore(result, ivec3(gl_GlobalInvocationID.xy, 0), uvec4(hitValue.x, 0, 0, 0));
2229     //   imageStore(result, ivec3(gl_GlobalInvocationID.xy, 1), uvec4(hitValue.y, 0, 0, 0));
2230     //    }
2231 
2232     std::stringstream css;
2233     css << "; SPIR-V\n"
2234         << "; Version: 1.4\n"
2235         << "; Generator: Khronos Glslang Reference Front End; 10\n"
2236         << "; Bound: 139\n"
2237         << "; Schema: 0\n"
2238         << "OpCapability Shader\n"
2239         << "OpCapability RayQueryKHR\n"
2240         << "OpExtension \"SPV_KHR_ray_query\"\n"
2241         << "%1 = OpExtInstImport \"GLSL.std.450\"\n"
2242         << "OpMemoryModel Logical GLSL450\n"
2243         << "OpEntryPoint GLCompute %4 \"main\" %60 %86 %114\n"
2244         << "OpExecutionMode %4 LocalSize 1 1 1\n"
2245         << "OpDecorate %60 BuiltIn GlobalInvocationId\n"
2246         << "OpDecorate %86 DescriptorSet 0\n"
2247         << "OpDecorate %86 Binding 1\n"
2248         << "OpDecorate %114 DescriptorSet 0\n"
2249         << "OpDecorate %114 Binding 0\n"
2250         << "%2 = OpTypeVoid\n"
2251         << "%3 = OpTypeFunction %2\n"
2252 
2253         // Bare query type
2254         << "%6 = OpTypeRayQueryKHR\n"
2255 
2256         // Pointer to query.
2257         << "%7 = OpTypePointer Function %6\n"
2258 
2259         // Bare AS type.
2260         << "%8 = OpTypeAccelerationStructureKHR\n"
2261 
2262         // Pointer to AS.
2263         << "%9 = OpTypePointer UniformConstant %8\n"
2264 
2265         << "%10 = OpTypeInt 32 0\n"
2266         << "%11 = OpTypePointer Function %10\n"
2267         << "%12 = OpTypeFloat 32\n"
2268         << "%13 = OpTypeVector %12 3\n"
2269         << "%14 = OpTypePointer Function %13\n"
2270         << "%15 = OpTypePointer Function %12\n"
2271 
2272         // This is the function type for rayQueryInitializeTopWrapper and the old rayQueryInitializeBottomWrapper.
2273         << "%16 = OpTypeFunction %2 %7 %9 %11 %11 %14 %15 %14 %15\n"
2274 
2275         // This is the new function type for the modified rayQueryInitializeBottomWrapper that uses a bare AS.
2276         //<< "%16b = OpTypeFunction %2 %6 %8 %11 %11 %14 %15 %14 %15\n"
2277         << "%16b = OpTypeFunction %2 %7 %8 %11 %11 %14 %15 %14 %15\n"
2278 
2279         << "%58 = OpTypeVector %10 3\n"
2280         << "%59 = OpTypePointer Input %58\n"
2281         << "%60 = OpVariable %59 Input\n"
2282         << "%61 = OpConstant %10 0\n"
2283         << "%62 = OpTypePointer Input %10\n"
2284         << "%66 = OpConstant %12 0.5\n"
2285         << "%68 = OpConstant %10 1\n"
2286         << "%74 = OpTypeVector %10 4\n"
2287         << "%75 = OpTypePointer Function %74\n"
2288         << "%77 = OpConstantComposite %74 %61 %61 %61 %61\n"
2289         << "%79 = OpConstant %12 0\n"
2290         << "%81 = OpConstant %12 1\n"
2291         << "%83 = OpConstant %12 -1\n"
2292         << "%84 = OpConstantComposite %13 %79 %79 %83\n"
2293         << "%86 = OpVariable %9 UniformConstant\n"
2294         << "%87 = OpConstant %10 255\n"
2295         << "%99 = OpTypeBool\n"
2296         << "%103 = OpConstantFalse %99\n"
2297         << "%104 = OpTypeInt 32 1\n"
2298         << "%105 = OpConstant %104 0\n"
2299         << "%112 = OpTypeImage %10 3D 0 0 0 2 R32ui\n"
2300         << "%113 = OpTypePointer UniformConstant %112\n"
2301         << "%114 = OpVariable %113 UniformConstant\n"
2302         << "%116 = OpTypeVector %10 2\n"
2303         << "%119 = OpTypeVector %104 2\n"
2304         << "%121 = OpTypeVector %104 3\n"
2305         << "%132 = OpConstant %104 1\n"
2306 
2307         // This is main().
2308         << "%4 = OpFunction %2 None %3\n"
2309         << "%5 = OpLabel\n"
2310         << "%57 = OpVariable %14 Function\n"
2311         << "%76 = OpVariable %75 Function\n"
2312         << "%78 = OpVariable %15 Function\n"
2313         << "%80 = OpVariable %15 Function\n"
2314         << "%82 = OpVariable %14 Function\n"
2315         << "%85 = OpVariable %7 Function\n"
2316         << "%88 = OpVariable %11 Function\n"
2317         << "%89 = OpVariable %11 Function\n"
2318         << "%90 = OpVariable %14 Function\n"
2319         << "%92 = OpVariable %15 Function\n"
2320         << "%94 = OpVariable %14 Function\n"
2321         << "%96 = OpVariable %15 Function\n"
2322         << "%63 = OpAccessChain %62 %60 %61\n"
2323         << "%64 = OpLoad %10 %63\n"
2324         << "%65 = OpConvertUToF %12 %64\n"
2325         << "%67 = OpFAdd %12 %65 %66\n"
2326         << "%69 = OpAccessChain %62 %60 %68\n"
2327         << "%70 = OpLoad %10 %69\n"
2328         << "%71 = OpConvertUToF %12 %70\n"
2329         << "%72 = OpFAdd %12 %71 %66\n"
2330         << "%73 = OpCompositeConstruct %13 %67 %72 %66\n"
2331         << "OpStore %57 %73\n"
2332         << "OpStore %76 %77\n"
2333         << "OpStore %78 %79\n"
2334         << "OpStore %80 %81\n"
2335         << "OpStore %82 %84\n"
2336         << "OpStore %88 %61\n"
2337         << "OpStore %89 %87\n"
2338         << "%91 = OpLoad %13 %57\n"
2339         << "OpStore %90 %91\n"
2340         << "%93 = OpLoad %12 %78\n"
2341         << "OpStore %92 %93\n"
2342         << "%95 = OpLoad %13 %82\n"
2343         << "OpStore %94 %95\n"
2344         << "%97 = OpLoad %12 %80\n"
2345         << "OpStore %96 %97\n"
2346         << "%98 = OpFunctionCall %2 %35 %85 %86 %88 %89 %90 %92 %94 %96\n"
2347         << "%100 = OpRayQueryProceedKHR %99 %85\n"
2348         << "OpSelectionMerge %102 None\n"
2349         << "OpBranchConditional %100 %101 %102\n"
2350         << "%101 = OpLabel\n"
2351         << "%106 = OpRayQueryGetIntersectionTypeKHR %10 %85 %105\n"
2352         << "%107 = OpIEqual %99 %106 %61\n"
2353         << "OpSelectionMerge %109 None\n"
2354         << "OpBranchConditional %107 %108 %109\n"
2355         << "%108 = OpLabel\n"
2356         << "%110 = OpAccessChain %11 %76 %68\n"
2357         << "OpStore %110 %68\n"
2358         << "%111 = OpAccessChain %11 %76 %61\n"
2359         << "OpStore %111 %68\n"
2360         << "OpBranch %109\n"
2361         << "%109 = OpLabel\n"
2362         << "OpBranch %102\n"
2363         << "%102 = OpLabel\n"
2364         << "%115 = OpLoad %112 %114\n"
2365         << "%117 = OpLoad %58 %60\n"
2366         << "%118 = OpVectorShuffle %116 %117 %117 0 1\n"
2367         << "%120 = OpBitcast %119 %118\n"
2368         << "%122 = OpCompositeExtract %104 %120 0\n"
2369         << "%123 = OpCompositeExtract %104 %120 1\n"
2370         << "%124 = OpCompositeConstruct %121 %122 %123 %105\n"
2371         << "%125 = OpAccessChain %11 %76 %61\n"
2372         << "%126 = OpLoad %10 %125\n"
2373         << "%127 = OpCompositeConstruct %74 %126 %61 %61 %61\n"
2374         << "OpImageWrite %115 %124 %127 ZeroExtend\n"
2375         << "%128 = OpLoad %112 %114\n"
2376         << "%129 = OpLoad %58 %60\n"
2377         << "%130 = OpVectorShuffle %116 %129 %129 0 1\n"
2378         << "%131 = OpBitcast %119 %130\n"
2379         << "%133 = OpCompositeExtract %104 %131 0\n"
2380         << "%134 = OpCompositeExtract %104 %131 1\n"
2381         << "%135 = OpCompositeConstruct %121 %133 %134 %132\n"
2382         << "%136 = OpAccessChain %11 %76 %68\n"
2383         << "%137 = OpLoad %10 %136\n"
2384         << "%138 = OpCompositeConstruct %74 %137 %61 %61 %61\n"
2385         << "OpImageWrite %128 %135 %138 ZeroExtend\n"
2386         << "OpReturn\n"
2387         << "OpFunctionEnd\n"
2388 
2389         // This is rayQueryInitializeBottomWrapper, calling OpRayQueryInitializeKHR.
2390         // We have modified the function type so it takes bare arguments.
2391         //%25 = OpFunction %2 None %16
2392         << "%25 = OpFunction %2 None %16b\n"
2393 
2394         // These is the modified parameter.
2395         << "%17 = OpFunctionParameter %7\n"
2396         //<< "%17 = OpFunctionParameter %6\n"
2397         //%18 = OpFunctionParameter %9
2398         << "%18 = OpFunctionParameter %8\n"
2399 
2400         << "%19 = OpFunctionParameter %11\n"
2401         << "%20 = OpFunctionParameter %11\n"
2402         << "%21 = OpFunctionParameter %14\n"
2403         << "%22 = OpFunctionParameter %15\n"
2404         << "%23 = OpFunctionParameter %14\n"
2405         << "%24 = OpFunctionParameter %15\n"
2406         << "%26 = OpLabel\n"
2407 
2408         // We no longer need to load this parameter.
2409         //%37 = OpLoad %8 %18
2410 
2411         << "%38 = OpLoad %10 %19\n"
2412         << "%39 = OpLoad %10 %20\n"
2413         << "%40 = OpLoad %13 %21\n"
2414         << "%41 = OpLoad %12 %22\n"
2415         << "%42 = OpLoad %13 %23\n"
2416         << "%43 = OpLoad %12 %24\n"
2417 
2418         // We call OpRayQueryInitializeKHR with bare arguments.
2419         // Note: some experimental lines to pass a bare rayQuery as the first argument have been commented out.
2420         //OpRayQueryInitializeKHR %17 %37 %38 %39 %40 %41 %42 %43
2421         << "OpRayQueryInitializeKHR %17 %18 %38 %39 %40 %41 %42 %43\n"
2422 
2423         << "OpReturn\n"
2424         << "OpFunctionEnd\n"
2425 
2426         // This is rayQueryInitializeTopWrapper, calling rayQueryInitializeBottomWrapper.
2427         << "%35 = OpFunction %2 None %16\n"
2428         << "%27 = OpFunctionParameter %7\n"
2429         << "%28 = OpFunctionParameter %9\n"
2430         << "%29 = OpFunctionParameter %11\n"
2431         << "%30 = OpFunctionParameter %11\n"
2432         << "%31 = OpFunctionParameter %14\n"
2433         << "%32 = OpFunctionParameter %15\n"
2434         << "%33 = OpFunctionParameter %14\n"
2435         << "%34 = OpFunctionParameter %15\n"
2436         << "%36 = OpLabel\n"
2437         << "%44 = OpVariable %11 Function\n"
2438         << "%46 = OpVariable %11 Function\n"
2439         << "%48 = OpVariable %14 Function\n"
2440         << "%50 = OpVariable %15 Function\n"
2441         << "%52 = OpVariable %14 Function\n"
2442         << "%54 = OpVariable %15 Function\n"
2443 
2444         // We need to load the second argument.
2445         //<< "%27b = OpLoad %6 %27\n"
2446         << "%28b = OpLoad %8 %28\n"
2447 
2448         << "%45 = OpLoad %10 %29\n"
2449         << "OpStore %44 %45\n"
2450         << "%47 = OpLoad %10 %30\n"
2451         << "OpStore %46 %47\n"
2452         << "%49 = OpLoad %13 %31\n"
2453         << "OpStore %48 %49\n"
2454         << "%51 = OpLoad %12 %32\n"
2455         << "OpStore %50 %51\n"
2456         << "%53 = OpLoad %13 %33\n"
2457         << "OpStore %52 %53\n"
2458         << "%55 = OpLoad %12 %34\n"
2459         << "OpStore %54 %55\n"
2460 
2461         // We call rayQueryInitializeBottomWrapper with the loaded argument.
2462         //%56 = OpFunctionCall %2 %25 %27 %28 %44 %46 %48 %50 %52 %54
2463         //<< "%56 = OpFunctionCall %2 %25 %27b %28b %44 %46 %48 %50 %52 %54\n"
2464         << "%56 = OpFunctionCall %2 %25 %27 %28b %44 %46 %48 %50 %52 %54\n"
2465 
2466         << "OpReturn\n"
2467         << "OpFunctionEnd\n";
2468 
2469     programCollection.spirvAsmSources.add("comp_as_triangle") << spvBuildOptions << css.str();
2470 }
2471 
RayQueryASBasicTestInstance(Context & context,const TestParams & data)2472 RayQueryASBasicTestInstance::RayQueryASBasicTestInstance(Context &context, const TestParams &data)
2473     : vkt::TestInstance(context)
2474     , m_data(data)
2475 {
2476 }
2477 
~RayQueryASBasicTestInstance(void)2478 RayQueryASBasicTestInstance::~RayQueryASBasicTestInstance(void)
2479 {
2480 }
2481 
runTest(TestConfiguration * testConfiguration,SceneBuilder * sceneBuilder,const uint32_t workerThreadsCount)2482 de::MovePtr<BufferWithMemory> RayQueryASBasicTestInstance::runTest(TestConfiguration *testConfiguration,
2483                                                                    SceneBuilder *sceneBuilder,
2484                                                                    const uint32_t workerThreadsCount)
2485 {
2486     testConfiguration->initConfiguration(m_context, m_data);
2487 
2488     const DeviceInterface &vkd      = m_context.getDeviceInterface();
2489     const VkDevice device           = m_context.getDevice();
2490     const VkQueue queue             = m_context.getUniversalQueue();
2491     Allocator &allocator            = m_context.getDefaultAllocator();
2492     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2493 
2494     const bool htCopy      = (workerThreadsCount != 0) && (m_data.operationType == OP_COPY);
2495     const bool htSerialize = (workerThreadsCount != 0) && (m_data.operationType == OP_SERIALIZE);
2496 
2497     const VkFormat imageFormat              = testConfiguration->getResultImageFormat();
2498     const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_data.width, m_data.height, 2, imageFormat);
2499     const VkImageSubresourceRange imageSubresourceRange =
2500         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2501     const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(
2502         new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
2503     const Move<VkImageView> imageView =
2504         makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, imageFormat, imageSubresourceRange);
2505 
2506     const VkBufferCreateInfo resultBufferCreateInfo =
2507         makeBufferCreateInfo(m_data.width * m_data.height * 2 * testConfiguration->getResultImageFormatSize(),
2508                              VK_BUFFER_USAGE_TRANSFER_DST_BIT);
2509     const VkImageSubresourceLayers resultBufferImageSubresourceLayers =
2510         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2511     const VkBufferImageCopy resultBufferImageRegion =
2512         makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, 2), resultBufferImageSubresourceLayers);
2513     de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(
2514         new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
2515 
2516     const VkDescriptorImageInfo resultImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
2517 
2518     const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
2519     const Move<VkCommandBuffer> cmdBuffer =
2520         allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2521 
2522     std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> bottomLevelAccelerationStructures;
2523     de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure;
2524     std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> bottomLevelAccelerationStructureCopies;
2525     de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructureCopy;
2526     std::vector<de::SharedPtr<SerialStorage>> bottomSerialized;
2527     std::vector<de::SharedPtr<SerialStorage>> topSerialized;
2528     std::vector<VkDeviceSize> accelerationCompactedSizes;
2529     std::vector<VkDeviceSize> accelerationSerialSizes;
2530     Move<VkQueryPool> m_queryPoolCompact;
2531     Move<VkQueryPool> m_queryPoolSerial;
2532 
2533     beginCommandBuffer(vkd, *cmdBuffer, 0u);
2534     {
2535         const VkImageMemoryBarrier preImageBarrier =
2536             makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
2537                                    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, **image, imageSubresourceRange);
2538         cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
2539                                       VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
2540 
2541         const VkClearValue clearValue = testConfiguration->getClearValue();
2542         vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1,
2543                                &imageSubresourceRange);
2544 
2545         const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(
2546             VK_ACCESS_TRANSFER_WRITE_BIT,
2547             VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
2548             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, **image, imageSubresourceRange);
2549         cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
2550                                       VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
2551 
2552         // build bottom level acceleration structures and their copies ( only when we are testing copying bottom level acceleration structures )
2553         bool bottomCompact = m_data.operationType == OP_COMPACT && m_data.operationTarget == OT_BOTTOM_ACCELERATION;
2554         bool bottomSerial  = m_data.operationType == OP_SERIALIZE && m_data.operationTarget == OT_BOTTOM_ACCELERATION;
2555         const bool buildWithoutGeom   = (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_GEOMETRIES_BOTTOM);
2556         const bool bottomNoPrimitives = (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_PRIMITIVES_BOTTOM);
2557         const bool topNoPrimitives    = (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_PRIMITIVES_TOP);
2558         const bool inactiveInstances  = (m_data.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_INSTANCES);
2559         bottomLevelAccelerationStructures = sceneBuilder->initBottomAccelerationStructures(m_context, m_data);
2560         VkBuildAccelerationStructureFlagsKHR allowCompactionFlag =
2561             VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR;
2562         VkBuildAccelerationStructureFlagsKHR emptyCompactionFlag = VkBuildAccelerationStructureFlagsKHR(0);
2563         VkBuildAccelerationStructureFlagsKHR bottomCompactFlags =
2564             (bottomCompact ? allowCompactionFlag : emptyCompactionFlag);
2565         VkBuildAccelerationStructureFlagsKHR bottomBuildFlags = m_data.buildFlags | bottomCompactFlags;
2566         std::vector<VkAccelerationStructureKHR> accelerationStructureHandles;
2567         std::vector<VkDeviceSize> bottomBlasCompactSize;
2568         std::vector<VkDeviceSize> bottomBlasSerialSize;
2569 
2570         for (auto &blas : bottomLevelAccelerationStructures)
2571         {
2572             blas->setBuildType(m_data.buildType);
2573             blas->setBuildFlags(bottomBuildFlags);
2574             blas->setUseArrayOfPointers(m_data.bottomUsesAOP);
2575             blas->setCreateGeneric(m_data.bottomGeneric);
2576             blas->setCreationBufferUnbounded(m_data.bottomUnboundedCreation);
2577             blas->setBuildWithoutGeometries(buildWithoutGeom);
2578             blas->setBuildWithoutPrimitives(bottomNoPrimitives);
2579             blas->createAndBuild(vkd, device, *cmdBuffer, allocator);
2580             accelerationStructureHandles.push_back(*(blas->getPtr()));
2581         }
2582 
2583         if (m_data.operationType == OP_COMPACT)
2584         {
2585             uint32_t queryCount = (m_data.operationTarget == OT_BOTTOM_ACCELERATION) ?
2586                                       uint32_t(bottomLevelAccelerationStructures.size()) :
2587                                       1u;
2588             if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2589                 m_queryPoolCompact =
2590                     makeQueryPool(vkd, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, queryCount);
2591             if (m_data.operationTarget == OT_BOTTOM_ACCELERATION)
2592                 queryAccelerationStructureSize(
2593                     vkd, device, *cmdBuffer, accelerationStructureHandles, m_data.buildType, m_queryPoolCompact.get(),
2594                     VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, 0u, bottomBlasCompactSize);
2595         }
2596         if (m_data.operationType == OP_SERIALIZE)
2597         {
2598             uint32_t queryCount = (m_data.operationTarget == OT_BOTTOM_ACCELERATION) ?
2599                                       uint32_t(bottomLevelAccelerationStructures.size()) :
2600                                       1u;
2601             if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2602                 m_queryPoolSerial =
2603                     makeQueryPool(vkd, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, queryCount);
2604             if (m_data.operationTarget == OT_BOTTOM_ACCELERATION)
2605                 queryAccelerationStructureSize(
2606                     vkd, device, *cmdBuffer, accelerationStructureHandles, m_data.buildType, m_queryPoolSerial.get(),
2607                     VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, bottomBlasSerialSize);
2608         }
2609 
2610         // if AS is built on GPU and we are planning to make a compact copy of it or serialize / deserialize it - we have to have download query results to CPU
2611         if ((m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) && (bottomCompact || bottomSerial))
2612         {
2613             endCommandBuffer(vkd, *cmdBuffer);
2614 
2615             submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2616 
2617             if (bottomCompact)
2618                 VK_CHECK(vkd.getQueryPoolResults(
2619                     device, *m_queryPoolCompact, 0u, uint32_t(bottomBlasCompactSize.size()),
2620                     sizeof(VkDeviceSize) * bottomBlasCompactSize.size(), bottomBlasCompactSize.data(),
2621                     sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
2622             if (bottomSerial)
2623                 VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolSerial, 0u, uint32_t(bottomBlasSerialSize.size()),
2624                                                  sizeof(VkDeviceSize) * bottomBlasSerialSize.size(),
2625                                                  bottomBlasSerialSize.data(), sizeof(VkDeviceSize),
2626                                                  VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
2627 
2628             vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2629             beginCommandBuffer(vkd, *cmdBuffer, 0u);
2630         }
2631 
2632         auto bottomLevelAccelerationStructuresPtr = &bottomLevelAccelerationStructures;
2633         if (m_data.operationType != OP_NONE && m_data.operationTarget == OT_BOTTOM_ACCELERATION)
2634         {
2635             switch (m_data.operationType)
2636             {
2637             case OP_COPY:
2638             {
2639                 for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i)
2640                 {
2641                     de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
2642                     asCopy->setDeferredOperation(htCopy, workerThreadsCount);
2643                     asCopy->setBuildType(m_data.buildType);
2644                     asCopy->setBuildFlags(m_data.buildFlags);
2645                     asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP);
2646                     asCopy->setCreateGeneric(m_data.bottomGeneric);
2647                     asCopy->setCreationBufferUnbounded(m_data.bottomUnboundedCreation);
2648                     asCopy->setBuildWithoutGeometries(buildWithoutGeom);
2649                     asCopy->setBuildWithoutPrimitives(bottomNoPrimitives);
2650                     asCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator,
2651                                               bottomLevelAccelerationStructures[i].get(), 0u, 0u);
2652                     bottomLevelAccelerationStructureCopies.push_back(
2653                         de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
2654                 }
2655                 break;
2656             }
2657             case OP_COMPACT:
2658             {
2659                 for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i)
2660                 {
2661                     de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
2662                     asCopy->setBuildType(m_data.buildType);
2663                     asCopy->setBuildFlags(m_data.buildFlags);
2664                     asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP);
2665                     asCopy->setCreateGeneric(m_data.bottomGeneric);
2666                     asCopy->setCreationBufferUnbounded(m_data.bottomUnboundedCreation);
2667                     asCopy->setBuildWithoutGeometries(buildWithoutGeom);
2668                     asCopy->setBuildWithoutPrimitives(bottomNoPrimitives);
2669                     asCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator,
2670                                               bottomLevelAccelerationStructures[i].get(), bottomBlasCompactSize[i], 0u);
2671                     bottomLevelAccelerationStructureCopies.push_back(
2672                         de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
2673                 }
2674                 break;
2675             }
2676             case OP_SERIALIZE:
2677             {
2678                 for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i)
2679                 {
2680                     de::SharedPtr<SerialStorage> storage(
2681                         new SerialStorage(vkd, device, allocator, m_data.buildType, bottomBlasSerialSize[i]));
2682 
2683                     bottomLevelAccelerationStructures[i]->setDeferredOperation(htSerialize, workerThreadsCount);
2684                     bottomLevelAccelerationStructures[i]->serialize(vkd, device, *cmdBuffer, storage.get());
2685                     bottomSerialized.push_back(storage);
2686 
2687                     if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2688                     {
2689                         endCommandBuffer(vkd, *cmdBuffer);
2690 
2691                         submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2692 
2693                         vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2694                         beginCommandBuffer(vkd, *cmdBuffer, 0u);
2695                     }
2696 
2697                     de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
2698                     asCopy->setBuildType(m_data.buildType);
2699                     asCopy->setBuildFlags(m_data.buildFlags);
2700                     asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP);
2701                     asCopy->setCreateGeneric(m_data.bottomGeneric);
2702                     asCopy->setCreationBufferUnbounded(m_data.bottomUnboundedCreation);
2703                     asCopy->setBuildWithoutGeometries(buildWithoutGeom);
2704                     asCopy->setBuildWithoutPrimitives(bottomNoPrimitives);
2705                     asCopy->setDeferredOperation(htSerialize, workerThreadsCount);
2706                     asCopy->createAndDeserializeFrom(vkd, device, *cmdBuffer, allocator, storage.get(), 0u);
2707                     bottomLevelAccelerationStructureCopies.push_back(
2708                         de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
2709                 }
2710                 break;
2711             }
2712             default:
2713                 DE_ASSERT(false);
2714             }
2715             bottomLevelAccelerationStructuresPtr = &bottomLevelAccelerationStructureCopies;
2716         }
2717 
2718         // build top level acceleration structures and their copies ( only when we are testing copying top level acceleration structures )
2719         bool topCompact = m_data.operationType == OP_COMPACT && m_data.operationTarget == OT_TOP_ACCELERATION;
2720         bool topSerial  = m_data.operationType == OP_SERIALIZE && m_data.operationTarget == OT_TOP_ACCELERATION;
2721         VkBuildAccelerationStructureFlagsKHR topCompactFlags = (topCompact ? allowCompactionFlag : emptyCompactionFlag);
2722         VkBuildAccelerationStructureFlagsKHR topBuildFlags   = m_data.buildFlags | topCompactFlags;
2723         std::vector<VkAccelerationStructureKHR> topLevelStructureHandles;
2724         std::vector<VkDeviceSize> topBlasCompactSize;
2725         std::vector<VkDeviceSize> topBlasSerialSize;
2726 
2727         topLevelAccelerationStructure =
2728             sceneBuilder->initTopAccelerationStructure(m_context, m_data, *bottomLevelAccelerationStructuresPtr);
2729         topLevelAccelerationStructure->setBuildType(m_data.buildType);
2730         topLevelAccelerationStructure->setBuildFlags(topBuildFlags);
2731         topLevelAccelerationStructure->setBuildWithoutPrimitives(topNoPrimitives);
2732         topLevelAccelerationStructure->setUseArrayOfPointers(m_data.topUsesAOP);
2733         topLevelAccelerationStructure->setCreateGeneric(m_data.topGeneric);
2734         topLevelAccelerationStructure->setCreationBufferUnbounded(m_data.topUnboundedCreation);
2735         topLevelAccelerationStructure->setInactiveInstances(inactiveInstances);
2736         topLevelAccelerationStructure->createAndBuild(vkd, device, *cmdBuffer, allocator);
2737         topLevelStructureHandles.push_back(*(topLevelAccelerationStructure->getPtr()));
2738 
2739         if (topCompact)
2740             queryAccelerationStructureSize(
2741                 vkd, device, *cmdBuffer, topLevelStructureHandles, m_data.buildType, m_queryPoolCompact.get(),
2742                 VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, 0u, topBlasCompactSize);
2743         if (topSerial)
2744             queryAccelerationStructureSize(
2745                 vkd, device, *cmdBuffer, topLevelStructureHandles, m_data.buildType, m_queryPoolSerial.get(),
2746                 VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, topBlasSerialSize);
2747 
2748         // if AS is built on GPU and we are planning to make a compact copy of it or serialize / deserialize it - we have to have download query results to CPU
2749         if ((m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) && (topCompact || topSerial))
2750         {
2751             endCommandBuffer(vkd, *cmdBuffer);
2752 
2753             submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2754 
2755             if (topCompact)
2756                 VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolCompact, 0u, uint32_t(topBlasCompactSize.size()),
2757                                                  sizeof(VkDeviceSize) * topBlasCompactSize.size(),
2758                                                  topBlasCompactSize.data(), sizeof(VkDeviceSize),
2759                                                  VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
2760             if (topSerial)
2761                 VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolSerial, 0u, uint32_t(topBlasSerialSize.size()),
2762                                                  sizeof(VkDeviceSize) * topBlasSerialSize.size(),
2763                                                  topBlasSerialSize.data(), sizeof(VkDeviceSize),
2764                                                  VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
2765 
2766             vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2767             beginCommandBuffer(vkd, *cmdBuffer, 0u);
2768         }
2769 
2770         const TopLevelAccelerationStructure *topLevelRayTracedPtr = topLevelAccelerationStructure.get();
2771         if (m_data.operationType != OP_NONE && m_data.operationTarget == OT_TOP_ACCELERATION)
2772         {
2773             switch (m_data.operationType)
2774             {
2775             case OP_COPY:
2776             {
2777                 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2778                 topLevelAccelerationStructureCopy->setDeferredOperation(htCopy, workerThreadsCount);
2779                 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
2780                 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags);
2781                 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives);
2782                 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances);
2783                 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP);
2784                 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric);
2785                 topLevelAccelerationStructureCopy->setCreationBufferUnbounded(m_data.topUnboundedCreation);
2786                 topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator,
2787                                                                      topLevelAccelerationStructure.get(), 0u, 0u);
2788                 break;
2789             }
2790             case OP_COMPACT:
2791             {
2792                 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2793                 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
2794                 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags);
2795                 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives);
2796                 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances);
2797                 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP);
2798                 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric);
2799                 topLevelAccelerationStructureCopy->setCreationBufferUnbounded(m_data.topUnboundedCreation);
2800                 topLevelAccelerationStructureCopy->createAndCopyFrom(
2801                     vkd, device, *cmdBuffer, allocator, topLevelAccelerationStructure.get(), topBlasCompactSize[0], 0u);
2802                 break;
2803             }
2804             case OP_SERIALIZE:
2805             {
2806                 de::SharedPtr<SerialStorage> storage(
2807                     new SerialStorage(vkd, device, allocator, m_data.buildType, topBlasSerialSize[0]));
2808 
2809                 topLevelAccelerationStructure->setDeferredOperation(htSerialize, workerThreadsCount);
2810                 topLevelAccelerationStructure->serialize(vkd, device, *cmdBuffer, storage.get());
2811                 topSerialized.push_back(storage);
2812 
2813                 if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2814                 {
2815                     endCommandBuffer(vkd, *cmdBuffer);
2816 
2817                     submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2818 
2819                     vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2820                     beginCommandBuffer(vkd, *cmdBuffer, 0u);
2821                 }
2822 
2823                 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2824                 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
2825                 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags);
2826                 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives);
2827                 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances);
2828                 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP);
2829                 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric);
2830                 topLevelAccelerationStructureCopy->setCreationBufferUnbounded(m_data.topUnboundedCreation);
2831                 topLevelAccelerationStructureCopy->setDeferredOperation(htSerialize, workerThreadsCount);
2832                 topLevelAccelerationStructureCopy->createAndDeserializeFrom(vkd, device, *cmdBuffer, allocator,
2833                                                                             storage.get(), 0u);
2834                 break;
2835             }
2836             case OP_UPDATE:
2837             {
2838                 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2839                 topLevelAccelerationStructureCopy->create(vkd, device, allocator, 0u, 0u);
2840                 // Update AS based on topLevelAccelerationStructure
2841                 topLevelAccelerationStructureCopy->build(vkd, device, *cmdBuffer, topLevelAccelerationStructure.get());
2842                 break;
2843             }
2844             case OP_UPDATE_IN_PLACE:
2845             {
2846                 // Update in place
2847                 topLevelAccelerationStructure->build(vkd, device, *cmdBuffer, topLevelAccelerationStructure.get());
2848                 // Make a coppy
2849                 topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2850                 topLevelAccelerationStructureCopy->setDeferredOperation(htCopy, workerThreadsCount);
2851                 topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
2852                 topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags);
2853                 topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives);
2854                 topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances);
2855                 topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP);
2856                 topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric);
2857                 topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator,
2858                                                                      topLevelAccelerationStructure.get(), 0u, 0u);
2859                 break;
2860             }
2861             default:
2862                 DE_ASSERT(false);
2863             }
2864             topLevelRayTracedPtr = topLevelAccelerationStructureCopy.get();
2865         }
2866 
2867         const VkMemoryBarrier preTraceMemoryBarrier =
2868             makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
2869         cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
2870                                  &preTraceMemoryBarrier);
2871 
2872         VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = {
2873             VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, //  VkStructureType sType;
2874             DE_NULL,                                                           //  const void* pNext;
2875             1u,                                                                //  uint32_t accelerationStructureCount;
2876             topLevelRayTracedPtr->getPtr(), //  const VkAccelerationStructureKHR* pAccelerationStructures;
2877         };
2878 
2879         testConfiguration->fillCommandBuffer(m_context, m_data, *cmdBuffer, accelerationStructureWriteDescriptorSet,
2880                                              resultImageInfo);
2881 
2882         const VkMemoryBarrier postTestMemoryBarrier =
2883             makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
2884         const VkMemoryBarrier postCopyMemoryBarrier =
2885             makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
2886         cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2887                                  &postTestMemoryBarrier);
2888 
2889         vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u,
2890                                  &resultBufferImageRegion);
2891 
2892         cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2893                                  &postCopyMemoryBarrier);
2894     }
2895     endCommandBuffer(vkd, *cmdBuffer);
2896 
2897     submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2898 
2899     invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(),
2900                                 resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
2901 
2902     return resultBuffer;
2903 }
2904 
iterateNoWorkers(void)2905 bool RayQueryASBasicTestInstance::iterateNoWorkers(void)
2906 {
2907     de::SharedPtr<TestConfiguration> testConfiguration = createTestConfiguration(m_data.shaderSourcePipeline);
2908     de::SharedPtr<SceneBuilder> sceneBuilder           = de::SharedPtr<SceneBuilder>(new CheckerboardSceneBuilder());
2909 
2910     const de::MovePtr<BufferWithMemory> buffer = runTest(testConfiguration.get(), sceneBuilder.get(), 0);
2911 
2912     return testConfiguration->verifyImage(buffer.get(), m_context, m_data);
2913 }
2914 
iterateWithWorkers(void)2915 bool RayQueryASBasicTestInstance::iterateWithWorkers(void)
2916 {
2917     de::SharedPtr<SceneBuilder> sceneBuilder = de::SharedPtr<SceneBuilder>(new CheckerboardSceneBuilder());
2918 
2919     de::SharedPtr<TestConfiguration> testConfigurationS = createTestConfiguration(m_data.shaderSourcePipeline);
2920     de::MovePtr<BufferWithMemory> singleThreadBufferCPU = runTest(testConfigurationS.get(), sceneBuilder.get(), 0);
2921     const bool singleThreadValidation = testConfigurationS->verifyImage(singleThreadBufferCPU.get(), m_context, m_data);
2922     testConfigurationS.clear();
2923 
2924     de::SharedPtr<TestConfiguration> testConfigurationM = createTestConfiguration(m_data.shaderSourcePipeline);
2925     de::MovePtr<BufferWithMemory> multiThreadBufferCPU =
2926         runTest(testConfigurationM.get(), sceneBuilder.get(), m_data.workerThreadsCount);
2927     const bool multiThreadValidation = testConfigurationM->verifyImage(multiThreadBufferCPU.get(), m_context, m_data);
2928     testConfigurationM.clear();
2929 
2930     const uint32_t result = singleThreadValidation && multiThreadValidation;
2931 
2932     return result;
2933 }
2934 
iterate(void)2935 tcu::TestStatus RayQueryASBasicTestInstance::iterate(void)
2936 {
2937     bool result;
2938     if (m_data.workerThreadsCount != 0)
2939         result = iterateWithWorkers();
2940     else
2941         result = iterateNoWorkers();
2942 
2943     if (result)
2944         return tcu::TestStatus::pass("Pass");
2945     else
2946         return tcu::TestStatus::fail("Fail");
2947 }
2948 
2949 // Tests dynamic indexing of acceleration structures
2950 class RayQueryASDynamicIndexingTestCase : public TestCase
2951 {
2952 public:
2953     RayQueryASDynamicIndexingTestCase(tcu::TestContext &context, const char *name);
2954     ~RayQueryASDynamicIndexingTestCase(void) = default;
2955 
2956     void checkSupport(Context &context) const override;
2957     void initPrograms(SourceCollections &programCollection) const override;
2958     TestInstance *createInstance(Context &context) const override;
2959 };
2960 
2961 class RayQueryASDynamicIndexingTestInstance : public TestInstance
2962 {
2963 public:
2964     RayQueryASDynamicIndexingTestInstance(Context &context);
2965     ~RayQueryASDynamicIndexingTestInstance(void) = default;
2966     tcu::TestStatus iterate(void) override;
2967 };
2968 
RayQueryASDynamicIndexingTestCase(tcu::TestContext & context,const char * name)2969 RayQueryASDynamicIndexingTestCase::RayQueryASDynamicIndexingTestCase(tcu::TestContext &context, const char *name)
2970     : TestCase(context, name)
2971 {
2972 }
2973 
checkSupport(Context & context) const2974 void RayQueryASDynamicIndexingTestCase::checkSupport(Context &context) const
2975 {
2976     commonASTestsCheckSupport(context);
2977     context.requireDeviceFunctionality("VK_EXT_descriptor_indexing");
2978 }
2979 
initPrograms(SourceCollections & programCollection) const2980 void RayQueryASDynamicIndexingTestCase::initPrograms(SourceCollections &programCollection) const
2981 {
2982     const vk::SpirVAsmBuildOptions spvBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true);
2983 
2984     // compute shader is defined in spir-v as it requires possing pointer to TLAS that was read from ssbo;
2985     // original spir-v code was generated using following glsl code but resulting spir-v code was modiifed
2986 
2987     // #version 460 core
2988     // #extension GL_EXT_ray_query : require
2989     // #extension GL_EXT_nonuniform_qualifier : enable
2990 
2991     // #define ARRAY_SIZE 500
2992     // layout(set = 0, binding = 0) uniform accelerationStructureEXT tlasArray[ARRAY_SIZE];
2993     // layout(set = 0, binding = 1) readonly buffer topLevelASPointers {
2994     //     uvec2 ptr[];
2995     // } tlasPointers;
2996     // layout(set = 0, binding = 2) readonly buffer topLevelASIndices {
2997     //     uint idx[];
2998     // } tlasIndices;
2999     // layout(set = 0, binding = 3, std430) writeonly buffer Result {
3000     //     uint value[];
3001     // } result;
3002 
3003     // void main()
3004     // {
3005     //   float tmin      = 0.0;
3006     //   float tmax      = 2.0;
3007     //   vec3  origin    = vec3(0.25f, 0.5f, 1.0);
3008     //   vec3  direction = vec3(0.0,0.0,-1.0);
3009     //   uint  tlasIndex = tlasIndices.idx[nonuniformEXT(gl_GlobalInvocationID.x)];
3010 
3011     //   rayQueryEXT rq;
3012     //   rayQueryInitializeEXT(rq, tlasArray[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax);
3013     //   atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x)], 2);
3014 
3015     //   if (rayQueryProceedEXT(rq))
3016     //   {
3017     //     if (rayQueryGetIntersectionTypeEXT(rq, false) == gl_RayQueryCandidateIntersectionTriangleEXT)
3018     //       atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x)], 3);
3019     //   }
3020 
3021     //   //rayQueryInitializeEXT(rq, tlasArray[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax);
3022     //   rayQueryInitializeEXT(rq, *tlasPointers.ptr[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax);
3023     //   atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x * 2)], 5);
3024 
3025     //   if (rayQueryProceedEXT(rq))
3026     //   {
3027     //     if (rayQueryGetIntersectionTypeEXT(rq, false) == gl_RayQueryCandidateIntersectionTriangleEXT)
3028     //       atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x * 3)], 7);
3029     //   }
3030     // }
3031 
3032     const std::string compSource =
3033         "OpCapability Shader\n"
3034         "OpCapability RayQueryKHR\n"
3035         "OpCapability ShaderNonUniform\n"
3036         "OpExtension \"SPV_EXT_descriptor_indexing\"\n"
3037         "OpExtension \"SPV_KHR_ray_query\"\n"
3038         "%1 = OpExtInstImport \"GLSL.std.450\"\n"
3039         "OpMemoryModel Logical GLSL450\n"
3040         "OpEntryPoint GLCompute %4 \"main\" %var_index_ssbo %33 %var_as_arr_uni_ptr %64 %83 %var_as_pointers_ssbo\n"
3041         "OpExecutionMode %4 LocalSize 1 1 1\n"
3042         "OpDecorate %25 ArrayStride 4\n"
3043         "OpMemberDecorate %26 0 NonWritable\n"
3044         "OpMemberDecorate %26 0 Offset 0\n"
3045         "OpDecorate %26 Block\n"
3046         "OpDecorate %var_index_ssbo DescriptorSet 0\n"
3047         "OpDecorate %var_index_ssbo Binding 2\n"
3048         "OpDecorate %33 BuiltIn GlobalInvocationId\n"
3049         "OpDecorate %38 NonUniform\n"
3050         "OpDecorate %40 NonUniform\n"
3051         "OpDecorate %41 NonUniform\n"
3052         "OpDecorate %var_as_arr_uni_ptr DescriptorSet 0\n"
3053         "OpDecorate %var_as_arr_uni_ptr Binding 0\n"
3054         "OpDecorate %51 NonUniform\n"
3055         "OpDecorate %53 NonUniform\n"
3056         "OpDecorate %54 NonUniform\n"
3057         "OpDecorate %61 ArrayStride 4\n"
3058         "OpMemberDecorate %62 0 NonReadable\n"
3059         "OpMemberDecorate %62 0 Offset 0\n"
3060         "OpDecorate %62 Block\n"
3061         "OpDecorate %64 DescriptorSet 0\n"
3062         "OpDecorate %64 Binding 3\n"
3063         "OpDecorate %67 NonUniform\n"
3064         "OpDecorate %83 BuiltIn NumWorkgroups\n"
3065         "OpDecorate %87 NonUniform\n"
3066         "OpDecorate %as_index NonUniform\n"
3067         "OpDecorate %as_device_addres NonUniform\n"
3068         "OpDecorate %105 NonUniform\n"
3069         "OpDecorate %122 NonUniform\n"
3070         "OpDecorate %127 ArrayStride 8\n"
3071         "OpMemberDecorate %128 0 NonWritable\n"
3072         "OpMemberDecorate %128 0 Offset 0\n"
3073         "OpDecorate %128 Block\n"
3074         "OpDecorate %var_as_pointers_ssbo DescriptorSet 0\n"
3075         "OpDecorate %var_as_pointers_ssbo Binding 1\n"
3076         "%2 = OpTypeVoid\n"
3077         "%3 = OpTypeFunction %2\n"
3078         "%6 = OpTypeFloat 32\n"
3079         "%7 = OpTypePointer Function %6\n"
3080         "%9 = OpConstant %6 0\n"
3081         "%11 = OpConstant %6 2\n"
3082         "%12 = OpTypeVector %6 3\n"
3083         "%13 = OpTypePointer Function %12\n"
3084         "%15 = OpConstant %6 0.25\n"
3085         "%16 = OpConstant %6 0.5\n"
3086         "%17 = OpConstant %6 1\n"
3087         "%18 = OpConstantComposite %12 %15 %16 %17\n"
3088         "%20 = OpConstant %6 -1\n"
3089         "%21 = OpConstantComposite %12 %9 %9 %20\n"
3090         "%type_uint32 = OpTypeInt 32 0\n"
3091         "%23 = OpTypePointer Function %type_uint32\n"
3092         "%25 = OpTypeRuntimeArray %type_uint32\n"
3093         "%26 = OpTypeStruct %25\n"
3094         "%27 = OpTypePointer StorageBuffer %26\n"
3095         "%var_index_ssbo = OpVariable %27 StorageBuffer\n"
3096         "%29 = OpTypeInt 32 1\n"
3097         "%c_int32_0 = OpConstant %29 0\n"
3098         "%31 = OpTypeVector %type_uint32 3\n"
3099         "%32 = OpTypePointer Input %31\n"
3100         "%33 = OpVariable %32 Input\n"
3101         "%34 = OpConstant %type_uint32 0\n"
3102         "%35 = OpTypePointer Input %type_uint32\n"
3103         "%type_uint32_ssbo_ptr = OpTypePointer StorageBuffer %type_uint32\n"
3104         "%42 = OpTypeRayQueryKHR\n"
3105         "%43 = OpTypePointer Function %42\n"
3106         "%type_as = OpTypeAccelerationStructureKHR\n"
3107         "%46 = OpConstant %type_uint32 500\n"
3108         "%type_as_arr = OpTypeArray %type_as %46\n"
3109         "%type_as_arr_uni_ptr = OpTypePointer UniformConstant %type_as_arr\n"
3110         "%var_as_arr_uni_ptr = OpVariable %type_as_arr_uni_ptr UniformConstant\n"
3111         "%type_as_uni_ptr = OpTypePointer UniformConstant %type_as\n"
3112         "%55 = OpConstant %type_uint32 16\n"
3113         "%56 = OpConstant %type_uint32 255\n"
3114         "%61 = OpTypeRuntimeArray %type_uint32\n"
3115         "%62 = OpTypeStruct %61\n"
3116         "%63 = OpTypePointer StorageBuffer %62\n"
3117         "%64 = OpVariable %63 StorageBuffer\n"
3118         "%69 = OpConstant %type_uint32 2\n"
3119         "%70 = OpConstant %type_uint32 1\n"
3120         "%72 = OpTypeBool\n"
3121         "%76 = OpConstantFalse %72\n"
3122         "%83 = OpVariable %32 Input\n"
3123         "%89 = OpConstant %type_uint32 3\n"
3124         "%107 = OpConstant %type_uint32 5\n"
3125         "%124 = OpConstant %type_uint32 7\n"
3126 
3127         // <changed_section>
3128         "%v2uint = OpTypeVector %type_uint32 2\n"
3129         "%127 = OpTypeRuntimeArray %v2uint\n"
3130         "%128 = OpTypeStruct %127\n"
3131         "%129 = OpTypePointer StorageBuffer %128\n"
3132         "%var_as_pointers_ssbo = OpVariable %129 StorageBuffer\n"
3133         "%type_uint64_ssbo_ptr = OpTypePointer StorageBuffer %v2uint\n"
3134         // </changed_section>
3135 
3136         // void main()
3137         "%4 = OpFunction %2 None %3\n"
3138         "%5 = OpLabel\n"
3139         "%8 = OpVariable %7 Function\n"
3140         "%10 = OpVariable %7 Function\n"
3141         "%14 = OpVariable %13 Function\n"
3142         "%19 = OpVariable %13 Function\n"
3143         "%24 = OpVariable %23 Function\n"
3144         "%var_ray_query = OpVariable %43 Function\n"
3145         "OpStore %8 %9\n"
3146         "OpStore %10 %11\n"
3147         "OpStore %14 %18\n"
3148         "OpStore %19 %21\n"
3149         "%36 = OpAccessChain %35 %33 %34\n"
3150         "%37 = OpLoad %type_uint32 %36\n"
3151         "%38 = OpCopyObject %type_uint32 %37\n"
3152         "%40 = OpAccessChain %type_uint32_ssbo_ptr %var_index_ssbo %c_int32_0 %38\n"
3153         "%41 = OpLoad %type_uint32 %40\n"
3154         "OpStore %24 %41\n"
3155 
3156         // rayQueryInitializeEXT using AS that was read from array
3157         "%50 = OpLoad %type_uint32 %24\n"
3158         "%51 = OpCopyObject %type_uint32 %50\n"
3159         "%53 = OpAccessChain %type_as_uni_ptr %var_as_arr_uni_ptr %51\n"
3160         "%54 = OpLoad %type_as %53\n"
3161         "%57 = OpLoad %12 %14\n"
3162         "%58 = OpLoad %6 %8\n"
3163         "%59 = OpLoad %12 %19\n"
3164         "%60 = OpLoad %6 %10\n"
3165         "OpRayQueryInitializeKHR %var_ray_query %54 %55 %56 %57 %58 %59 %60\n"
3166 
3167         "%65 = OpAccessChain %35 %33 %34\n"
3168         "%66 = OpLoad %type_uint32 %65\n"
3169         "%67 = OpCopyObject %type_uint32 %66\n"
3170         "%68 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %67\n"
3171         "%71 = OpAtomicIAdd %type_uint32 %68 %70 %34 %69\n"
3172 
3173         "%73 = OpRayQueryProceedKHR %72 %var_ray_query\n"
3174         "OpSelectionMerge %75 None\n"
3175         "OpBranchConditional %73 %74 %75\n"
3176         "%74 = OpLabel\n"
3177 
3178         "%77 = OpRayQueryGetIntersectionTypeKHR %type_uint32 %var_ray_query %c_int32_0\n"
3179         "%78 = OpIEqual %72 %77 %34\n"
3180         "OpSelectionMerge %80 None\n"
3181         "OpBranchConditional %78 %79 %80\n"
3182         "%79 = OpLabel\n"
3183         "%81 = OpAccessChain %35 %33 %34\n"
3184         "%82 = OpLoad %type_uint32 %81\n"
3185         "%84 = OpAccessChain %35 %83 %34\n"
3186         "%85 = OpLoad %type_uint32 %84\n"
3187         "%86 = OpIAdd %type_uint32 %82 %85\n"
3188         "%87 = OpCopyObject %type_uint32 %86\n"
3189         "%88 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %87\n"
3190         "%90 = OpAtomicIAdd %type_uint32 %88 %70 %34 %89\n"
3191         "OpBranch %80\n"
3192         "%80 = OpLabel\n"
3193         "OpBranch %75\n"
3194         "%75 = OpLabel\n"
3195 
3196         // rayQueryInitializeEXT using pointer to AS
3197         "%91 = OpLoad %type_uint32 %24\n"
3198         "%as_index = OpCopyObject %type_uint32 %91\n"
3199 
3200         // <changed_section>
3201         "%as_device_addres_ptr = OpAccessChain %type_uint64_ssbo_ptr %var_as_pointers_ssbo %c_int32_0 %as_index\n"
3202         "%as_device_addres = OpLoad %v2uint %as_device_addres_ptr\n"
3203         "%as_to_use = OpConvertUToAccelerationStructureKHR %type_as %as_device_addres\n"
3204         // </changed_section>
3205 
3206         "%95 = OpLoad %12 %14\n"
3207         "%96 = OpLoad %6 %8\n"
3208         "%97 = OpLoad %12 %19\n"
3209         "%98 = OpLoad %6 %10\n"
3210         "OpRayQueryInitializeKHR %var_ray_query %as_to_use %55 %56 %95 %96 %97 %98\n"
3211 
3212         "%99 = OpAccessChain %35 %33 %34\n"
3213         "%100 = OpLoad %type_uint32 %99\n"
3214         "%101 = OpAccessChain %35 %83 %34\n"
3215         "%102 = OpLoad %type_uint32 %101\n"
3216         "%103 = OpIMul %type_uint32 %102 %69\n"
3217         "%104 = OpIAdd %type_uint32 %100 %103\n"
3218         "%105 = OpCopyObject %type_uint32 %104\n"
3219         "%106 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %105\n"
3220         "%108 = OpAtomicIAdd %type_uint32 %106 %70 %34 %107\n"
3221 
3222         "%109 = OpRayQueryProceedKHR %72 %var_ray_query\n"
3223         "OpSelectionMerge %111 None\n"
3224         "OpBranchConditional %109 %110 %111\n"
3225         "%110 = OpLabel\n"
3226 
3227         "%112 = OpRayQueryGetIntersectionTypeKHR %type_uint32 %var_ray_query %c_int32_0\n"
3228         "%113 = OpIEqual %72 %112 %34\n"
3229         "OpSelectionMerge %115 None\n"
3230         "OpBranchConditional %113 %114 %115\n"
3231         "%114 = OpLabel\n"
3232         "%116 = OpAccessChain %35 %33 %34\n"
3233         "%117 = OpLoad %type_uint32 %116\n"
3234         "%118 = OpAccessChain %35 %83 %34\n"
3235         "%119 = OpLoad %type_uint32 %118\n"
3236         "%120 = OpIMul %type_uint32 %119 %89\n"
3237         "%121 = OpIAdd %type_uint32 %117 %120\n"
3238         "%122 = OpCopyObject %type_uint32 %121\n"
3239         "%123 = OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %122\n"
3240         "%125 = OpAtomicIAdd %type_uint32 %123 %70 %34 %124\n"
3241         "OpBranch %115\n"
3242         "%115 = OpLabel\n"
3243         "OpBranch %111\n"
3244         "%111 = OpLabel\n"
3245         "OpReturn\n"
3246         "OpFunctionEnd\n";
3247 
3248     programCollection.spirvAsmSources.add("comp") << compSource << spvBuildOptions;
3249 }
3250 
createInstance(Context & context) const3251 TestInstance *RayQueryASDynamicIndexingTestCase::createInstance(Context &context) const
3252 {
3253     return new RayQueryASDynamicIndexingTestInstance(context);
3254 }
3255 
RayQueryASDynamicIndexingTestInstance(Context & context)3256 RayQueryASDynamicIndexingTestInstance::RayQueryASDynamicIndexingTestInstance(Context &context)
3257     : vkt::TestInstance(context)
3258 {
3259 }
3260 
iterate(void)3261 tcu::TestStatus RayQueryASDynamicIndexingTestInstance::iterate(void)
3262 {
3263     const DeviceInterface &vkd      = m_context.getDeviceInterface();
3264     const VkDevice device           = m_context.getDevice();
3265     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3266     const VkQueue queue             = m_context.getUniversalQueue();
3267     Allocator &allocator            = m_context.getDefaultAllocator();
3268     const uint32_t tlasCount        = 500; // changing this will require also changing shaders
3269     const uint32_t activeTlasCount  = 32;  // number of tlas out of <tlasCount> that will be active
3270 
3271     const Move<VkDescriptorSetLayout> descriptorSetLayout =
3272         DescriptorSetLayoutBuilder()
3273             .addArrayBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount, VK_SHADER_STAGE_COMPUTE_BIT)
3274             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
3275                               VK_SHADER_STAGE_COMPUTE_BIT) // pointers to all acceleration structures
3276             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
3277                               VK_SHADER_STAGE_COMPUTE_BIT) // ssbo with indices of all acceleration structures
3278             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT) // ssbo with result values
3279             .build(vkd, device);
3280 
3281     const Move<VkDescriptorPool> descriptorPool =
3282         DescriptorPoolBuilder()
3283             .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount)
3284             .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3285             .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3286             .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3287             .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
3288     const Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
3289 
3290     const Move<VkPipelineLayout> pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
3291     Move<VkShaderModule> shaderModule =
3292         createShaderModule(vkd, device, m_context.getBinaryCollection().get("comp"), 0u);
3293     const VkComputePipelineCreateInfo pipelineCreateInfo{
3294         VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType                        sType
3295         DE_NULL,                                        // const void*                            pNext
3296         0u,                                             // VkPipelineCreateFlags                flags
3297         {                                               // VkPipelineShaderStageCreateInfo        stage
3298          VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, DE_NULL, (VkPipelineShaderStageCreateFlags)0,
3299          VK_SHADER_STAGE_COMPUTE_BIT, *shaderModule, "main", DE_NULL},
3300         *pipelineLayout, // VkPipelineLayout                        layout
3301         DE_NULL,         // VkPipeline                            basePipelineHandle
3302         0,               // int32_t                                basePipelineIndex
3303     };
3304 
3305     Move<VkPipeline> pipeline = createComputePipeline(vkd, device, DE_NULL, &pipelineCreateInfo);
3306 
3307     const VkDeviceSize pointerBufferSize = tlasCount * sizeof(VkDeviceAddress);
3308     const VkBufferCreateInfo pointerBufferCreateInfo =
3309         makeBufferCreateInfo(pointerBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
3310     de::MovePtr<BufferWithMemory> pointerBuffer = de::MovePtr<BufferWithMemory>(
3311         new BufferWithMemory(vkd, device, allocator, pointerBufferCreateInfo,
3312                              MemoryRequirement::HostVisible | MemoryRequirement::DeviceAddress));
3313 
3314     const VkDeviceSize indicesBufferSize = activeTlasCount * sizeof(uint32_t);
3315     const VkBufferCreateInfo indicesBufferCreateInfo =
3316         makeBufferCreateInfo(indicesBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
3317     de::MovePtr<BufferWithMemory> indicesBuffer = de::MovePtr<BufferWithMemory>(
3318         new BufferWithMemory(vkd, device, allocator, indicesBufferCreateInfo, MemoryRequirement::HostVisible));
3319 
3320     const VkDeviceSize resultBufferSize = activeTlasCount * sizeof(uint32_t) * 4;
3321     const VkBufferCreateInfo resultBufferCreateInfo =
3322         makeBufferCreateInfo(resultBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
3323     de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(
3324         new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
3325 
3326     const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
3327     const Move<VkCommandBuffer> cmdBuffer =
3328         allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3329 
3330     de::SharedPtr<BottomLevelAccelerationStructure> blas =
3331         de::SharedPtr<BottomLevelAccelerationStructure>(makeBottomLevelAccelerationStructure().release());
3332     std::vector<de::MovePtr<TopLevelAccelerationStructure>> tlasVect(tlasCount);
3333     std::vector<VkDeviceAddress> tlasPtrVect(tlasCount);
3334     std::vector<VkAccelerationStructureKHR> tlasVkVect;
3335 
3336     // randomly scatter AS indices across the range (number of them should be equal to the max subgroup size)
3337     deRandom rnd;
3338     deRandom_init(&rnd, 123);
3339     std::set<uint32_t> asIndicesSet;
3340     while (asIndicesSet.size() < activeTlasCount)
3341         asIndicesSet.insert(deRandom_getUint32(&rnd) % tlasCount);
3342 
3343     // fill indices buffer
3344     uint32_t helperIndex       = 0;
3345     auto &indicesBufferAlloc   = indicesBuffer->getAllocation();
3346     uint32_t *indicesBufferPtr = reinterpret_cast<uint32_t *>(indicesBufferAlloc.getHostPtr());
3347     std::for_each(asIndicesSet.begin(), asIndicesSet.end(),
3348                   [&helperIndex, indicesBufferPtr](const uint32_t &index) { indicesBufferPtr[helperIndex++] = index; });
3349     vk::flushAlloc(vkd, device, indicesBufferAlloc);
3350 
3351     // clear result buffer
3352     auto &resultBufferAlloc = resultBuffer->getAllocation();
3353     void *resultBufferPtr   = resultBufferAlloc.getHostPtr();
3354     deMemset(resultBufferPtr, 0, static_cast<size_t>(resultBufferSize));
3355     vk::flushAlloc(vkd, device, resultBufferAlloc);
3356 
3357     beginCommandBuffer(vkd, *cmdBuffer, 0u);
3358     {
3359         // build bottom level acceleration structure
3360         blas->setGeometryData(
3361             {
3362                 {0.0, 0.0, 0.0},
3363                 {1.0, 0.0, 0.0},
3364                 {0.0, 1.0, 0.0},
3365             },
3366             true, 0u);
3367 
3368         blas->createAndBuild(vkd, device, *cmdBuffer, allocator);
3369 
3370         // build top level acceleration structures
3371         for (uint32_t tlasIndex = 0; tlasIndex < tlasCount; ++tlasIndex)
3372         {
3373             auto &tlas = tlasVect[tlasIndex];
3374             tlas       = makeTopLevelAccelerationStructure();
3375             tlas->setInstanceCount(1);
3376             tlas->addInstance(blas);
3377             if (!asIndicesSet.count(tlasIndex))
3378             {
3379                 // tlas that are not in asIndicesSet should be empty but it is hard to do
3380                 // that with current cts utils so we are marking them as inactive instead
3381                 tlas->setInactiveInstances(true);
3382             }
3383             tlas->createAndBuild(vkd, device, *cmdBuffer, allocator);
3384 
3385             // get acceleration structure device address
3386             const VkAccelerationStructureDeviceAddressInfoKHR addressInfo = {
3387                 VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR, // VkStructureType                sType
3388                 DE_NULL,        // const void*                    pNext
3389                 *tlas->getPtr() // VkAccelerationStructureKHR    accelerationStructure
3390             };
3391             VkDeviceAddress vkda   = vkd.getAccelerationStructureDeviceAddressKHR(device, &addressInfo);
3392             tlasPtrVect[tlasIndex] = vkda;
3393         }
3394 
3395         // fill pointer buffer
3396         vkd.cmdUpdateBuffer(*cmdBuffer, **pointerBuffer, 0, pointerBufferSize, tlasPtrVect.data());
3397 
3398         // wait for data transfers
3399         const VkMemoryBarrier uploadBarrier =
3400             makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
3401         cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
3402                                  &uploadBarrier, 1u);
3403 
3404         // wait for as build
3405         const VkMemoryBarrier asBuildBarrier = makeMemoryBarrier(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
3406                                                                  VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR);
3407         cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
3408                                  VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, &asBuildBarrier, 1u);
3409 
3410         tlasVkVect.reserve(tlasCount);
3411         for (auto &tlas : tlasVect)
3412             tlasVkVect.push_back(*tlas->getPtr());
3413 
3414         VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = {
3415             VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
3416             DE_NULL,                                                           // const void* pNext;
3417             tlasCount,                                                         // uint32_t accelerationStructureCount;
3418             tlasVkVect.data(), // const VkAccelerationStructureKHR* pAccelerationStructures;
3419         };
3420 
3421         const vk::VkDescriptorBufferInfo pointerBufferInfo =
3422             makeDescriptorBufferInfo(**pointerBuffer, 0u, VK_WHOLE_SIZE);
3423         const vk::VkDescriptorBufferInfo indicesBufferInfo =
3424             makeDescriptorBufferInfo(**indicesBuffer, 0u, VK_WHOLE_SIZE);
3425         const vk::VkDescriptorBufferInfo resultInfo = makeDescriptorBufferInfo(**resultBuffer, 0u, VK_WHOLE_SIZE);
3426 
3427         DescriptorSetUpdateBuilder()
3428             .writeArray(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
3429                         VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount,
3430                         &accelerationStructureWriteDescriptorSet)
3431             .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
3432                          VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &pointerBufferInfo)
3433             .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u),
3434                          VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &indicesBufferInfo)
3435             .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(3u),
3436                          VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo)
3437             .update(vkd, device);
3438 
3439         vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, 1,
3440                                   &descriptorSet.get(), 0, DE_NULL);
3441 
3442         vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
3443 
3444         vkd.cmdDispatch(*cmdBuffer, activeTlasCount, 1, 1);
3445 
3446         const VkMemoryBarrier postTraceMemoryBarrier =
3447             makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
3448         cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
3449                                  &postTraceMemoryBarrier);
3450     }
3451     endCommandBuffer(vkd, *cmdBuffer);
3452 
3453     submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
3454 
3455     invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(),
3456                                 resultBuffer->getAllocation().getOffset(), resultBufferSize);
3457 
3458     // verify result buffer
3459     uint32_t failures         = 0;
3460     const uint32_t *resultPtr = reinterpret_cast<uint32_t *>(resultBuffer->getAllocation().getHostPtr());
3461     for (uint32_t index = 0; index < activeTlasCount; ++index)
3462     {
3463         failures += (resultPtr[0 * activeTlasCount + index] != 2) + (resultPtr[1 * activeTlasCount + index] != 3) +
3464                     (resultPtr[2 * activeTlasCount + index] != 5) + (resultPtr[3 * activeTlasCount + index] != 7);
3465     }
3466 
3467     if (failures)
3468         return tcu::TestStatus::fail(de::toString(failures) + " failures, " +
3469                                      de::toString(4 * activeTlasCount - failures) + " are ok");
3470     return tcu::TestStatus::pass("Pass");
3471 }
3472 
3473 } // namespace
3474 
3475 /********************/
3476 
addBasicBuildingTests(tcu::TestCaseGroup * group)3477 void addBasicBuildingTests(tcu::TestCaseGroup *group)
3478 {
3479     struct ShaderSourceTypeData
3480     {
3481         ShaderSourceType shaderSourceType;
3482         ShaderSourcePipeline shaderSourcePipeline;
3483         const char *name;
3484     } shaderSourceTypes[] = {
3485         {
3486             SST_FRAGMENT_SHADER,
3487             SSP_GRAPHICS_PIPELINE,
3488             "fragment_shader",
3489         },
3490         {
3491             SST_COMPUTE_SHADER,
3492             SSP_COMPUTE_PIPELINE,
3493             "compute_shader",
3494         },
3495         {
3496             SST_CLOSEST_HIT_SHADER,
3497             SSP_RAY_TRACING_PIPELINE,
3498             "chit_shader",
3499         },
3500     };
3501 
3502     struct
3503     {
3504         vk::VkAccelerationStructureBuildTypeKHR buildType;
3505         const char *name;
3506     } buildTypes[] = {
3507         {VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built"},
3508         {VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built"},
3509     };
3510 
3511     struct
3512     {
3513         BottomTestType testType;
3514         bool usesAOP;
3515         const char *name;
3516     } bottomTestTypes[] = {
3517         {BottomTestType::TRIANGLES, false, "triangles"},
3518         {BottomTestType::TRIANGLES, true, "triangles_aop"},
3519         {BottomTestType::AABBS, false, "aabbs"},
3520         {BottomTestType::AABBS, true, "aabbs_aop"},
3521     };
3522 
3523     struct
3524     {
3525         TopTestType testType;
3526         bool usesAOP;
3527         const char *name;
3528     } topTestTypes[] = {
3529         {TopTestType::IDENTICAL_INSTANCES, false, "identical_instances"},
3530         {TopTestType::IDENTICAL_INSTANCES, true, "identical_instances_aop"},
3531         {TopTestType::DIFFERENT_INSTANCES, false, "different_instances"},
3532         {TopTestType::DIFFERENT_INSTANCES, true, "different_instances_aop"},
3533     };
3534 
3535     struct BuildFlagsData
3536     {
3537         VkBuildAccelerationStructureFlagsKHR flags;
3538         const char *name;
3539     };
3540 
3541     BuildFlagsData optimizationTypes[] = {
3542         {VkBuildAccelerationStructureFlagsKHR(0u), "0"},
3543         {VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR, "fasttrace"},
3544         {VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR, "fastbuild"},
3545     };
3546 
3547     BuildFlagsData updateTypes[] = {
3548         {VkBuildAccelerationStructureFlagsKHR(0u), "0"},
3549         {VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR, "update"},
3550     };
3551 
3552     BuildFlagsData compactionTypes[] = {
3553         {VkBuildAccelerationStructureFlagsKHR(0u), "0"},
3554         {VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR, "compaction"},
3555     };
3556 
3557     BuildFlagsData lowMemoryTypes[] = {
3558         {VkBuildAccelerationStructureFlagsKHR(0u), "0"},
3559         {VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR, "lowmemory"},
3560     };
3561 
3562     struct
3563     {
3564         bool padVertices;
3565         const char *name;
3566     } paddingType[] = {
3567         {false, "nopadding"},
3568         {true, "padded"},
3569     };
3570 
3571     struct
3572     {
3573         bool topGeneric;
3574         bool bottomGeneric;
3575         const char *suffix;
3576     } createGenericParams[] = {
3577         {false, false, ""},
3578         {false, true, "_bottomgeneric"},
3579         {true, false, "_topgeneric"},
3580         {true, true, "_bothgeneric"},
3581     };
3582 
3583     // In order not to create thousands of new test variants for unbound buffer memory on acceleration structure creation, we will
3584     // set these options on some of the tests.
3585     de::ModCounter32 unboundedCreationBottomCounter(3u);
3586     de::ModCounter32 unboundedCreationTopCounter(7u);
3587 
3588     for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
3589     {
3590         de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(
3591             new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name));
3592 
3593         for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3594         {
3595             de::MovePtr<tcu::TestCaseGroup> buildGroup(
3596                 new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name));
3597 
3598             for (size_t bottomNdx = 0; bottomNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++bottomNdx)
3599             {
3600                 de::MovePtr<tcu::TestCaseGroup> bottomGroup(
3601                     new tcu::TestCaseGroup(group->getTestContext(), bottomTestTypes[bottomNdx].name));
3602 
3603                 for (size_t topNdx = 0; topNdx < DE_LENGTH_OF_ARRAY(topTestTypes); ++topNdx)
3604                 {
3605                     de::MovePtr<tcu::TestCaseGroup> topGroup(
3606                         new tcu::TestCaseGroup(group->getTestContext(), topTestTypes[topNdx].name));
3607 
3608                     for (int paddingTypeIdx = 0; paddingTypeIdx < DE_LENGTH_OF_ARRAY(paddingType); ++paddingTypeIdx)
3609                     {
3610                         de::MovePtr<tcu::TestCaseGroup> paddingTypeGroup(
3611                             new tcu::TestCaseGroup(group->getTestContext(), paddingType[paddingTypeIdx].name));
3612 
3613                         for (size_t optimizationNdx = 0; optimizationNdx < DE_LENGTH_OF_ARRAY(optimizationTypes);
3614                              ++optimizationNdx)
3615                         {
3616                             for (size_t updateNdx = 0; updateNdx < DE_LENGTH_OF_ARRAY(updateTypes); ++updateNdx)
3617                             {
3618                                 for (size_t compactionNdx = 0; compactionNdx < DE_LENGTH_OF_ARRAY(compactionTypes);
3619                                      ++compactionNdx)
3620                                 {
3621                                     for (size_t lowMemoryNdx = 0; lowMemoryNdx < DE_LENGTH_OF_ARRAY(lowMemoryTypes);
3622                                          ++lowMemoryNdx)
3623                                     {
3624                                         for (int createGenericIdx = 0;
3625                                              createGenericIdx < DE_LENGTH_OF_ARRAY(createGenericParams);
3626                                              ++createGenericIdx)
3627                                         {
3628                                             std::string testName =
3629                                                 std::string(optimizationTypes[optimizationNdx].name) + "_" +
3630                                                 std::string(updateTypes[updateNdx].name) + "_" +
3631                                                 std::string(compactionTypes[compactionNdx].name) + "_" +
3632                                                 std::string(lowMemoryTypes[lowMemoryNdx].name) +
3633                                                 std::string(createGenericParams[createGenericIdx].suffix);
3634 
3635                                             const bool unboundedCreationBottom =
3636                                                 (static_cast<uint32_t>(unboundedCreationBottomCounter++) == 0u);
3637                                             const bool unboundedCreationTop =
3638                                                 (static_cast<uint32_t>(unboundedCreationTopCounter++) == 0u);
3639 
3640                                             TestParams testParams{
3641                                                 shaderSourceTypes[shaderSourceNdx].shaderSourceType,
3642                                                 shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
3643                                                 buildTypes[buildTypeNdx].buildType,
3644                                                 VK_FORMAT_R32G32B32_SFLOAT,
3645                                                 paddingType[paddingTypeIdx].padVertices,
3646                                                 VK_INDEX_TYPE_NONE_KHR,
3647                                                 bottomTestTypes[bottomNdx].testType,
3648                                                 InstanceCullFlags::NONE,
3649                                                 bottomTestTypes[bottomNdx].usesAOP,
3650                                                 createGenericParams[createGenericIdx].bottomGeneric,
3651                                                 unboundedCreationBottom,
3652                                                 topTestTypes[topNdx].testType,
3653                                                 topTestTypes[topNdx].usesAOP,
3654                                                 createGenericParams[createGenericIdx].topGeneric,
3655                                                 unboundedCreationTop,
3656                                                 optimizationTypes[optimizationNdx].flags |
3657                                                     updateTypes[updateNdx].flags |
3658                                                     compactionTypes[compactionNdx].flags |
3659                                                     lowMemoryTypes[lowMemoryNdx].flags,
3660                                                 OT_NONE,
3661                                                 OP_NONE,
3662                                                 TEST_WIDTH,
3663                                                 TEST_HEIGHT,
3664                                                 0u,
3665                                                 EmptyAccelerationStructureCase::NOT_EMPTY,
3666                                             };
3667                                             paddingTypeGroup->addChild(new RayQueryASBasicTestCase(
3668                                                 group->getTestContext(), testName.c_str(), testParams));
3669                                         }
3670                                     }
3671                                 }
3672                             }
3673                         }
3674                         topGroup->addChild(paddingTypeGroup.release());
3675                     }
3676                     bottomGroup->addChild(topGroup.release());
3677                 }
3678                 buildGroup->addChild(bottomGroup.release());
3679             }
3680             sourceTypeGroup->addChild(buildGroup.release());
3681         }
3682         group->addChild(sourceTypeGroup.release());
3683     }
3684 }
3685 
addVertexIndexFormatsTests(tcu::TestCaseGroup * group)3686 void addVertexIndexFormatsTests(tcu::TestCaseGroup *group)
3687 {
3688     struct ShaderSourceTypeData
3689     {
3690         ShaderSourceType shaderSourceType;
3691         ShaderSourcePipeline shaderSourcePipeline;
3692         const char *name;
3693     } shaderSourceTypes[] = {
3694         {SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader"},
3695         {SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader"},
3696         {SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader"},
3697         {
3698             SST_GEOMETRY_SHADER,
3699             SSP_GRAPHICS_PIPELINE,
3700             "geometry_shader",
3701         },
3702         {
3703             SST_FRAGMENT_SHADER,
3704             SSP_GRAPHICS_PIPELINE,
3705             "fragment_shader",
3706         },
3707         {
3708             SST_COMPUTE_SHADER,
3709             SSP_COMPUTE_PIPELINE,
3710             "compute_shader",
3711         },
3712         {
3713             SST_RAY_GENERATION_SHADER,
3714             SSP_RAY_TRACING_PIPELINE,
3715             "rgen_shader",
3716         },
3717         {
3718             SST_INTERSECTION_SHADER,
3719             SSP_RAY_TRACING_PIPELINE,
3720             "isect_shader",
3721         },
3722         {
3723             SST_ANY_HIT_SHADER,
3724             SSP_RAY_TRACING_PIPELINE,
3725             "ahit_shader",
3726         },
3727         {
3728             SST_CLOSEST_HIT_SHADER,
3729             SSP_RAY_TRACING_PIPELINE,
3730             "chit_shader",
3731         },
3732         {
3733             SST_MISS_SHADER,
3734             SSP_RAY_TRACING_PIPELINE,
3735             "miss_shader",
3736         },
3737         {
3738             SST_CALLABLE_SHADER,
3739             SSP_RAY_TRACING_PIPELINE,
3740             "call_shader",
3741         },
3742     };
3743 
3744     struct
3745     {
3746         vk::VkAccelerationStructureBuildTypeKHR buildType;
3747         const char *name;
3748     } buildTypes[] = {
3749         {VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built"},
3750         {VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built"},
3751     };
3752 
3753     const VkFormat vertexFormats[] = {
3754         // Mandatory formats.
3755         VK_FORMAT_R32G32_SFLOAT,
3756         VK_FORMAT_R32G32B32_SFLOAT,
3757         VK_FORMAT_R16G16_SFLOAT,
3758         VK_FORMAT_R16G16B16A16_SFLOAT,
3759         VK_FORMAT_R16G16_SNORM,
3760         VK_FORMAT_R16G16B16A16_SNORM,
3761 
3762         // Additional formats.
3763         VK_FORMAT_R8G8_SNORM,
3764         VK_FORMAT_R8G8B8_SNORM,
3765         VK_FORMAT_R8G8B8A8_SNORM,
3766         VK_FORMAT_R16G16B16_SNORM,
3767         VK_FORMAT_R16G16B16_SFLOAT,
3768         VK_FORMAT_R32G32B32A32_SFLOAT,
3769         VK_FORMAT_R64G64_SFLOAT,
3770         VK_FORMAT_R64G64B64_SFLOAT,
3771         VK_FORMAT_R64G64B64A64_SFLOAT,
3772     };
3773 
3774     struct
3775     {
3776         VkIndexType indexType;
3777         const char *name;
3778     } indexFormats[] = {
3779         {VK_INDEX_TYPE_NONE_KHR, "index_none"},
3780         {VK_INDEX_TYPE_UINT16, "index_uint16"},
3781         {VK_INDEX_TYPE_UINT32, "index_uint32"},
3782     };
3783 
3784     struct
3785     {
3786         bool padVertices;
3787         const char *name;
3788     } paddingType[] = {
3789         {false, "nopadding"},
3790         {true, "padded"},
3791     };
3792 
3793     for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
3794     {
3795         de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(
3796             new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name));
3797 
3798         for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3799         {
3800             de::MovePtr<tcu::TestCaseGroup> buildGroup(
3801                 new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name));
3802 
3803             for (size_t vertexFormatNdx = 0; vertexFormatNdx < DE_LENGTH_OF_ARRAY(vertexFormats); ++vertexFormatNdx)
3804             {
3805                 const auto format     = vertexFormats[vertexFormatNdx];
3806                 const auto formatName = getFormatSimpleName(format);
3807 
3808                 de::MovePtr<tcu::TestCaseGroup> vertexFormatGroup(
3809                     new tcu::TestCaseGroup(group->getTestContext(), formatName.c_str()));
3810 
3811                 for (int paddingIdx = 0; paddingIdx < DE_LENGTH_OF_ARRAY(paddingType); ++paddingIdx)
3812                 {
3813                     de::MovePtr<tcu::TestCaseGroup> paddingGroup(
3814                         new tcu::TestCaseGroup(group->getTestContext(), paddingType[paddingIdx].name));
3815 
3816                     for (size_t indexFormatNdx = 0; indexFormatNdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatNdx)
3817                     {
3818                         TestParams testParams{
3819                             shaderSourceTypes[shaderSourceNdx].shaderSourceType,
3820                             shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
3821                             buildTypes[buildTypeNdx].buildType,
3822                             format,
3823                             paddingType[paddingIdx].padVertices,
3824                             indexFormats[indexFormatNdx].indexType,
3825                             BottomTestType::TRIANGLES,
3826                             InstanceCullFlags::NONE,
3827                             false,
3828                             false,
3829                             false,
3830                             TopTestType::IDENTICAL_INSTANCES,
3831                             false,
3832                             false,
3833                             false,
3834                             VkBuildAccelerationStructureFlagsKHR(0u),
3835                             OT_NONE,
3836                             OP_NONE,
3837                             TEST_WIDTH,
3838                             TEST_HEIGHT,
3839                             0u,
3840                             EmptyAccelerationStructureCase::NOT_EMPTY,
3841                         };
3842                         paddingGroup->addChild(new RayQueryASBasicTestCase(
3843                             group->getTestContext(), indexFormats[indexFormatNdx].name, testParams));
3844                     }
3845                     vertexFormatGroup->addChild(paddingGroup.release());
3846                 }
3847                 buildGroup->addChild(vertexFormatGroup.release());
3848             }
3849             sourceTypeGroup->addChild(buildGroup.release());
3850         }
3851         group->addChild(sourceTypeGroup.release());
3852     }
3853 }
3854 
addOperationTestsImpl(tcu::TestCaseGroup * group,const uint32_t workerThreads)3855 void addOperationTestsImpl(tcu::TestCaseGroup *group, const uint32_t workerThreads)
3856 {
3857     struct ShaderSourceTypeData
3858     {
3859         ShaderSourceType shaderSourceType;
3860         ShaderSourcePipeline shaderSourcePipeline;
3861         const char *name;
3862     } shaderSourceTypes[] = {
3863         {SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader"},
3864         {SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader"},
3865         {SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader"},
3866         {
3867             SST_GEOMETRY_SHADER,
3868             SSP_GRAPHICS_PIPELINE,
3869             "geometry_shader",
3870         },
3871         {
3872             SST_FRAGMENT_SHADER,
3873             SSP_GRAPHICS_PIPELINE,
3874             "fragment_shader",
3875         },
3876         {
3877             SST_COMPUTE_SHADER,
3878             SSP_COMPUTE_PIPELINE,
3879             "compute_shader",
3880         },
3881         {
3882             SST_RAY_GENERATION_SHADER,
3883             SSP_RAY_TRACING_PIPELINE,
3884             "rgen_shader",
3885         },
3886         {
3887             SST_INTERSECTION_SHADER,
3888             SSP_RAY_TRACING_PIPELINE,
3889             "isect_shader",
3890         },
3891         {
3892             SST_ANY_HIT_SHADER,
3893             SSP_RAY_TRACING_PIPELINE,
3894             "ahit_shader",
3895         },
3896         {
3897             SST_CLOSEST_HIT_SHADER,
3898             SSP_RAY_TRACING_PIPELINE,
3899             "chit_shader",
3900         },
3901         {
3902             SST_MISS_SHADER,
3903             SSP_RAY_TRACING_PIPELINE,
3904             "miss_shader",
3905         },
3906         {
3907             SST_CALLABLE_SHADER,
3908             SSP_RAY_TRACING_PIPELINE,
3909             "call_shader",
3910         },
3911     };
3912 
3913     struct
3914     {
3915         OperationType operationType;
3916         const char *name;
3917     } operationTypes[] = {
3918         {OP_COPY, "copy"},
3919         {OP_COMPACT, "compaction"},
3920         {OP_SERIALIZE, "serialization"},
3921     };
3922 
3923     struct
3924     {
3925         vk::VkAccelerationStructureBuildTypeKHR buildType;
3926         const char *name;
3927     } buildTypes[] = {
3928         {VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built"},
3929         {VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built"},
3930     };
3931 
3932     struct
3933     {
3934         OperationTarget operationTarget;
3935         const char *name;
3936     } operationTargets[] = {
3937         {OT_TOP_ACCELERATION, "top_acceleration_structure"},
3938         {OT_BOTTOM_ACCELERATION, "bottom_acceleration_structure"},
3939     };
3940 
3941     struct
3942     {
3943         BottomTestType testType;
3944         const char *name;
3945     } bottomTestTypes[] = {
3946         {BottomTestType::TRIANGLES, "triangles"},
3947         {BottomTestType::AABBS, "aabbs"},
3948     };
3949 
3950     for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
3951     {
3952         de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(
3953             new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name));
3954 
3955         for (size_t operationTypeNdx = 0; operationTypeNdx < DE_LENGTH_OF_ARRAY(operationTypes); ++operationTypeNdx)
3956         {
3957             if (workerThreads > 0)
3958                 if (operationTypes[operationTypeNdx].operationType != OP_COPY &&
3959                     operationTypes[operationTypeNdx].operationType != OP_SERIALIZE)
3960                     continue;
3961 
3962             de::MovePtr<tcu::TestCaseGroup> operationTypeGroup(
3963                 new tcu::TestCaseGroup(group->getTestContext(), operationTypes[operationTypeNdx].name));
3964 
3965             for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3966             {
3967                 if (workerThreads > 0 &&
3968                     buildTypes[buildTypeNdx].buildType != VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR)
3969                     continue;
3970 
3971                 de::MovePtr<tcu::TestCaseGroup> buildGroup(
3972                     new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name));
3973 
3974                 for (size_t operationTargetNdx = 0; operationTargetNdx < DE_LENGTH_OF_ARRAY(operationTargets);
3975                      ++operationTargetNdx)
3976                 {
3977                     de::MovePtr<tcu::TestCaseGroup> operationTargetGroup(
3978                         new tcu::TestCaseGroup(group->getTestContext(), operationTargets[operationTargetNdx].name));
3979 
3980                     for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++testTypeNdx)
3981                     {
3982                         TopTestType topTest =
3983                             (operationTargets[operationTargetNdx].operationTarget == OT_TOP_ACCELERATION) ?
3984                                 TopTestType::DIFFERENT_INSTANCES :
3985                                 TopTestType::IDENTICAL_INSTANCES;
3986 
3987                         TestParams testParams{
3988                             shaderSourceTypes[shaderSourceNdx].shaderSourceType,
3989                             shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
3990                             buildTypes[buildTypeNdx].buildType,
3991                             VK_FORMAT_R32G32B32_SFLOAT,
3992                             false,
3993                             VK_INDEX_TYPE_NONE_KHR,
3994                             bottomTestTypes[testTypeNdx].testType,
3995                             InstanceCullFlags::NONE,
3996                             false,
3997                             false,
3998                             false,
3999                             topTest,
4000                             false,
4001                             false,
4002                             false,
4003                             VkBuildAccelerationStructureFlagsKHR(0u),
4004                             operationTargets[operationTargetNdx].operationTarget,
4005                             operationTypes[operationTypeNdx].operationType,
4006                             TEST_WIDTH,
4007                             TEST_HEIGHT,
4008                             workerThreads,
4009                             EmptyAccelerationStructureCase::NOT_EMPTY,
4010                         };
4011                         operationTargetGroup->addChild(new RayQueryASBasicTestCase(
4012                             group->getTestContext(), bottomTestTypes[testTypeNdx].name, testParams));
4013                     }
4014                     buildGroup->addChild(operationTargetGroup.release());
4015                 }
4016                 operationTypeGroup->addChild(buildGroup.release());
4017             }
4018             sourceTypeGroup->addChild(operationTypeGroup.release());
4019         }
4020         group->addChild(sourceTypeGroup.release());
4021     }
4022 }
4023 
addOperationTests(tcu::TestCaseGroup * group)4024 void addOperationTests(tcu::TestCaseGroup *group)
4025 {
4026     addOperationTestsImpl(group, 0);
4027 }
4028 
addHostThreadingOperationTests(tcu::TestCaseGroup * group)4029 void addHostThreadingOperationTests(tcu::TestCaseGroup *group)
4030 {
4031     const uint32_t threads[] = {1, 2, 3, 4, 8, std::numeric_limits<uint32_t>::max()};
4032 
4033     for (size_t threadsNdx = 0; threadsNdx < DE_LENGTH_OF_ARRAY(threads); ++threadsNdx)
4034     {
4035         const std::string groupName =
4036             threads[threadsNdx] != std::numeric_limits<uint32_t>::max() ? de::toString(threads[threadsNdx]) : "max";
4037 
4038         de::MovePtr<tcu::TestCaseGroup> threadGroup(new tcu::TestCaseGroup(group->getTestContext(), groupName.c_str()));
4039 
4040         addOperationTestsImpl(threadGroup.get(), threads[threadsNdx]);
4041 
4042         group->addChild(threadGroup.release());
4043     }
4044 }
4045 
addFuncArgTests(tcu::TestCaseGroup * group)4046 void addFuncArgTests(tcu::TestCaseGroup *group)
4047 {
4048     const struct
4049     {
4050         vk::VkAccelerationStructureBuildTypeKHR buildType;
4051         const char *name;
4052     } buildTypes[] = {
4053         {VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built"},
4054         {VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built"},
4055     };
4056 
4057     auto &ctx = group->getTestContext();
4058 
4059     for (int buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
4060     {
4061         TestParams testParams{
4062             SST_COMPUTE_SHADER,
4063             SSP_COMPUTE_PIPELINE,
4064             buildTypes[buildTypeNdx].buildType,
4065             VK_FORMAT_R32G32B32_SFLOAT,
4066             false,
4067             VK_INDEX_TYPE_NONE_KHR,
4068             BottomTestType::TRIANGLES,
4069             InstanceCullFlags::NONE,
4070             false,
4071             false,
4072             false,
4073             TopTestType::IDENTICAL_INSTANCES,
4074             false,
4075             false,
4076             false,
4077             VkBuildAccelerationStructureFlagsKHR(0u),
4078             OT_NONE,
4079             OP_NONE,
4080             TEST_WIDTH,
4081             TEST_HEIGHT,
4082             0u,
4083             EmptyAccelerationStructureCase::NOT_EMPTY,
4084         };
4085 
4086         group->addChild(new RayQueryASFuncArgTestCase(ctx, buildTypes[buildTypeNdx].name, testParams));
4087     }
4088 }
4089 
addInstanceTriangleCullingTests(tcu::TestCaseGroup * group)4090 void addInstanceTriangleCullingTests(tcu::TestCaseGroup *group)
4091 {
4092     const struct
4093     {
4094         ShaderSourceType shaderSourceType;
4095         ShaderSourcePipeline shaderSourcePipeline;
4096         std::string name;
4097     } shaderSourceTypes[] = {
4098         {SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader"},
4099         {SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader"},
4100         {SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader"},
4101         {
4102             SST_GEOMETRY_SHADER,
4103             SSP_GRAPHICS_PIPELINE,
4104             "geometry_shader",
4105         },
4106         {
4107             SST_FRAGMENT_SHADER,
4108             SSP_GRAPHICS_PIPELINE,
4109             "fragment_shader",
4110         },
4111         {
4112             SST_COMPUTE_SHADER,
4113             SSP_COMPUTE_PIPELINE,
4114             "compute_shader",
4115         },
4116         {
4117             SST_RAY_GENERATION_SHADER,
4118             SSP_RAY_TRACING_PIPELINE,
4119             "rgen_shader",
4120         },
4121         {
4122             SST_INTERSECTION_SHADER,
4123             SSP_RAY_TRACING_PIPELINE,
4124             "isect_shader",
4125         },
4126         {
4127             SST_ANY_HIT_SHADER,
4128             SSP_RAY_TRACING_PIPELINE,
4129             "ahit_shader",
4130         },
4131         {
4132             SST_CLOSEST_HIT_SHADER,
4133             SSP_RAY_TRACING_PIPELINE,
4134             "chit_shader",
4135         },
4136         {
4137             SST_MISS_SHADER,
4138             SSP_RAY_TRACING_PIPELINE,
4139             "miss_shader",
4140         },
4141         {
4142             SST_CALLABLE_SHADER,
4143             SSP_RAY_TRACING_PIPELINE,
4144             "call_shader",
4145         },
4146     };
4147 
4148     const struct
4149     {
4150         InstanceCullFlags cullFlags;
4151         std::string name;
4152     } cullFlags[] = {
4153         {InstanceCullFlags::NONE, "noflags"},
4154         {InstanceCullFlags::COUNTERCLOCKWISE, "ccw"},
4155         {InstanceCullFlags::CULL_DISABLE, "nocull"},
4156         {InstanceCullFlags::ALL, "ccw_nocull"},
4157     };
4158 
4159     const struct
4160     {
4161         TopTestType topType;
4162         std::string name;
4163     } topType[] = {
4164         {TopTestType::DIFFERENT_INSTANCES, "transformed"}, // Each instance has its own transformation matrix.
4165         {TopTestType::IDENTICAL_INSTANCES, "notransform"}, // "Identical" instances, different geometries.
4166     };
4167 
4168     const struct
4169     {
4170         vk::VkAccelerationStructureBuildTypeKHR buildType;
4171         std::string name;
4172     } buildTypes[] = {
4173         {VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built"},
4174         {VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built"},
4175     };
4176 
4177     const struct
4178     {
4179         VkIndexType indexType;
4180         std::string name;
4181     } indexFormats[] = {
4182         {VK_INDEX_TYPE_NONE_KHR, "index_none"},
4183         {VK_INDEX_TYPE_UINT16, "index_uint16"},
4184         {VK_INDEX_TYPE_UINT32, "index_uint32"},
4185     };
4186 
4187     auto &ctx = group->getTestContext();
4188 
4189     for (int shaderSourceIdx = 0; shaderSourceIdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceIdx)
4190     {
4191         de::MovePtr<tcu::TestCaseGroup> shaderSourceGroup(
4192             new tcu::TestCaseGroup(ctx, shaderSourceTypes[shaderSourceIdx].name.c_str()));
4193 
4194         for (int buildTypeIdx = 0; buildTypeIdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeIdx)
4195         {
4196             de::MovePtr<tcu::TestCaseGroup> buildTypeGroup(
4197                 new tcu::TestCaseGroup(ctx, buildTypes[buildTypeIdx].name.c_str()));
4198 
4199             for (int indexFormatIdx = 0; indexFormatIdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatIdx)
4200             {
4201                 de::MovePtr<tcu::TestCaseGroup> indexTypeGroup(
4202                     new tcu::TestCaseGroup(ctx, indexFormats[indexFormatIdx].name.c_str()));
4203 
4204                 for (int topTypeIdx = 0; topTypeIdx < DE_LENGTH_OF_ARRAY(topType); ++topTypeIdx)
4205                 {
4206                     for (int cullFlagsIdx = 0; cullFlagsIdx < DE_LENGTH_OF_ARRAY(cullFlags); ++cullFlagsIdx)
4207                     {
4208                         const std::string testName = topType[topTypeIdx].name + "_" + cullFlags[cullFlagsIdx].name;
4209 
4210                         TestParams testParams{
4211                             shaderSourceTypes[shaderSourceIdx].shaderSourceType,
4212                             shaderSourceTypes[shaderSourceIdx].shaderSourcePipeline,
4213                             buildTypes[buildTypeIdx].buildType,
4214                             VK_FORMAT_R32G32B32_SFLOAT,
4215                             false,
4216                             indexFormats[indexFormatIdx].indexType,
4217                             BottomTestType::TRIANGLES,
4218                             cullFlags[cullFlagsIdx].cullFlags,
4219                             false,
4220                             false,
4221                             false,
4222                             topType[topTypeIdx].topType,
4223                             false,
4224                             false,
4225                             false,
4226                             VkBuildAccelerationStructureFlagsKHR(0u),
4227                             OT_NONE,
4228                             OP_NONE,
4229                             TEST_WIDTH,
4230                             TEST_HEIGHT,
4231                             0u,
4232                             EmptyAccelerationStructureCase::NOT_EMPTY,
4233                         };
4234                         indexTypeGroup->addChild(new RayQueryASBasicTestCase(ctx, testName.c_str(), testParams));
4235                     }
4236                 }
4237                 buildTypeGroup->addChild(indexTypeGroup.release());
4238             }
4239             shaderSourceGroup->addChild(buildTypeGroup.release());
4240         }
4241         group->addChild(shaderSourceGroup.release());
4242     }
4243 }
4244 
addInstanceUpdateTests(tcu::TestCaseGroup * group)4245 void addInstanceUpdateTests(tcu::TestCaseGroup *group)
4246 {
4247     const struct
4248     {
4249         vk::VkAccelerationStructureBuildTypeKHR buildType;
4250         std::string name;
4251     } buildTypes[] = {
4252         {VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built"},
4253         {VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built"},
4254     };
4255 
4256     struct
4257     {
4258         OperationType operationType;
4259         const char *name;
4260     } operationTypes[] = {
4261         {OP_UPDATE, "update"},
4262         {OP_UPDATE_IN_PLACE, "update_in_place"},
4263     };
4264 
4265     auto &ctx = group->getTestContext();
4266 
4267     for (int buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
4268     {
4269         de::MovePtr<tcu::TestCaseGroup> buildTypeGroup(
4270             new tcu::TestCaseGroup(ctx, buildTypes[buildTypeNdx].name.c_str()));
4271 
4272         for (int operationTypesIdx = 0; operationTypesIdx < DE_LENGTH_OF_ARRAY(operationTypes); ++operationTypesIdx)
4273         {
4274             TestParams testParams{
4275                 SST_COMPUTE_SHADER,
4276                 SSP_COMPUTE_PIPELINE,
4277                 buildTypes[buildTypeNdx].buildType,
4278                 VK_FORMAT_R32G32B32_SFLOAT,
4279                 false,
4280                 VK_INDEX_TYPE_NONE_KHR,
4281                 BottomTestType::TRIANGLES,
4282                 InstanceCullFlags::NONE,
4283                 false,
4284                 false,
4285                 false,
4286                 TopTestType::IDENTICAL_INSTANCES,
4287                 false,
4288                 false,
4289                 false,
4290                 VkBuildAccelerationStructureFlagsKHR(0u),
4291                 OT_NONE,
4292                 OP_NONE,
4293                 TEST_WIDTH,
4294                 TEST_HEIGHT,
4295                 0u,
4296                 EmptyAccelerationStructureCase::NOT_EMPTY,
4297             };
4298 
4299             buildTypeGroup->addChild(
4300                 new RayQueryASFuncArgTestCase(ctx, operationTypes[operationTypesIdx].name, testParams));
4301         }
4302         group->addChild(buildTypeGroup.release());
4303     }
4304 }
4305 
addDynamicIndexingTests(tcu::TestCaseGroup * group)4306 void addDynamicIndexingTests(tcu::TestCaseGroup *group)
4307 {
4308     auto &ctx = group->getTestContext();
4309     group->addChild(new RayQueryASDynamicIndexingTestCase(ctx, "dynamic_indexing"));
4310 }
4311 
addEmptyAccelerationStructureTests(tcu::TestCaseGroup * group)4312 void addEmptyAccelerationStructureTests(tcu::TestCaseGroup *group)
4313 {
4314     const struct
4315     {
4316         ShaderSourceType shaderSourceType;
4317         ShaderSourcePipeline shaderSourcePipeline;
4318         std::string name;
4319     } shaderSourceTypes[] = {
4320         {SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader"},
4321         {SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader"},
4322         {SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader"},
4323         {
4324             SST_GEOMETRY_SHADER,
4325             SSP_GRAPHICS_PIPELINE,
4326             "geometry_shader",
4327         },
4328         {
4329             SST_FRAGMENT_SHADER,
4330             SSP_GRAPHICS_PIPELINE,
4331             "fragment_shader",
4332         },
4333         {
4334             SST_COMPUTE_SHADER,
4335             SSP_COMPUTE_PIPELINE,
4336             "compute_shader",
4337         },
4338         {
4339             SST_RAY_GENERATION_SHADER,
4340             SSP_RAY_TRACING_PIPELINE,
4341             "rgen_shader",
4342         },
4343         {
4344             SST_INTERSECTION_SHADER,
4345             SSP_RAY_TRACING_PIPELINE,
4346             "isect_shader",
4347         },
4348         {
4349             SST_ANY_HIT_SHADER,
4350             SSP_RAY_TRACING_PIPELINE,
4351             "ahit_shader",
4352         },
4353         {
4354             SST_CLOSEST_HIT_SHADER,
4355             SSP_RAY_TRACING_PIPELINE,
4356             "chit_shader",
4357         },
4358         {
4359             SST_MISS_SHADER,
4360             SSP_RAY_TRACING_PIPELINE,
4361             "miss_shader",
4362         },
4363         {
4364             SST_CALLABLE_SHADER,
4365             SSP_RAY_TRACING_PIPELINE,
4366             "call_shader",
4367         },
4368     };
4369 
4370     const struct
4371     {
4372         vk::VkAccelerationStructureBuildTypeKHR buildType;
4373         std::string name;
4374     } buildTypes[] = {
4375         {VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, "cpu_built"},
4376         {VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR, "gpu_built"},
4377     };
4378 
4379     const struct
4380     {
4381         VkIndexType indexType;
4382         std::string name;
4383     } indexFormats[] = {
4384         {VK_INDEX_TYPE_NONE_KHR, "index_none"},
4385         {VK_INDEX_TYPE_UINT16, "index_uint16"},
4386         {VK_INDEX_TYPE_UINT32, "index_uint32"},
4387     };
4388 
4389     const struct
4390     {
4391         EmptyAccelerationStructureCase emptyASCase;
4392         std::string name;
4393     } emptyCases[] = {
4394         {EmptyAccelerationStructureCase::INACTIVE_TRIANGLES, "inactive_triangles"},
4395         {EmptyAccelerationStructureCase::INACTIVE_INSTANCES, "inactive_instances"},
4396         {EmptyAccelerationStructureCase::NO_GEOMETRIES_BOTTOM, "no_geometries_bottom"},
4397         {EmptyAccelerationStructureCase::NO_PRIMITIVES_TOP, "no_primitives_top"},
4398         {EmptyAccelerationStructureCase::NO_PRIMITIVES_BOTTOM, "no_primitives_bottom"},
4399     };
4400 
4401     auto &ctx = group->getTestContext();
4402 
4403     for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
4404     {
4405         de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(
4406             new tcu::TestCaseGroup(ctx, shaderSourceTypes[shaderSourceNdx].name.c_str()));
4407 
4408         for (int buildTypeIdx = 0; buildTypeIdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeIdx)
4409         {
4410             de::MovePtr<tcu::TestCaseGroup> buildTypeGroup(
4411                 new tcu::TestCaseGroup(ctx, buildTypes[buildTypeIdx].name.c_str()));
4412 
4413             for (int indexFormatIdx = 0; indexFormatIdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatIdx)
4414             {
4415                 de::MovePtr<tcu::TestCaseGroup> indexTypeGroup(
4416                     new tcu::TestCaseGroup(ctx, indexFormats[indexFormatIdx].name.c_str()));
4417 
4418                 for (int emptyCaseIdx = 0; emptyCaseIdx < DE_LENGTH_OF_ARRAY(emptyCases); ++emptyCaseIdx)
4419                 {
4420                     TestParams testParams{
4421                         shaderSourceTypes[shaderSourceNdx].shaderSourceType,
4422                         shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
4423                         buildTypes[buildTypeIdx].buildType,
4424                         VK_FORMAT_R32G32B32_SFLOAT,
4425                         false,
4426                         indexFormats[indexFormatIdx].indexType,
4427                         BottomTestType::TRIANGLES,
4428                         InstanceCullFlags::NONE,
4429                         false,
4430                         false,
4431                         false,
4432                         TopTestType::IDENTICAL_INSTANCES,
4433                         false,
4434                         false,
4435                         false,
4436                         VkBuildAccelerationStructureFlagsKHR(0u),
4437                         OT_NONE,
4438                         OP_NONE,
4439                         TEST_WIDTH,
4440                         TEST_HEIGHT,
4441                         0u,
4442                         emptyCases[emptyCaseIdx].emptyASCase,
4443                     };
4444                     indexTypeGroup->addChild(
4445                         new RayQueryASBasicTestCase(ctx, emptyCases[emptyCaseIdx].name.c_str(), testParams));
4446                 }
4447                 buildTypeGroup->addChild(indexTypeGroup.release());
4448             }
4449             sourceTypeGroup->addChild(buildTypeGroup.release());
4450         }
4451         group->addChild(sourceTypeGroup.release());
4452     }
4453 }
4454 
createAccelerationStructuresTests(tcu::TestContext & testCtx)4455 tcu::TestCaseGroup *createAccelerationStructuresTests(tcu::TestContext &testCtx)
4456 {
4457     // Acceleration structure tests using rayQuery feature
4458     de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "acceleration_structures"));
4459 
4460     // Test building AS with different build types, build flags and geometries/instances using arrays or arrays of pointers
4461     addTestGroup(group.get(), "flags", addBasicBuildingTests);
4462     // Test building AS with different vertex and index formats
4463     addTestGroup(group.get(), "format", addVertexIndexFormatsTests);
4464     // Test copying, compaction and serialization of AS
4465     addTestGroup(group.get(), "operations", addOperationTests);
4466     // Test host threading operations
4467     addTestGroup(group.get(), "host_threading", addHostThreadingOperationTests);
4468     // Test using AS as function argument using both pointers and bare values
4469     addTestGroup(group.get(), "function_argument", addFuncArgTests);
4470     // Test building AS with counterclockwise triangles and/or disabling face culling
4471     addTestGroup(group.get(), "instance_triangle_culling", addInstanceTriangleCullingTests);
4472     // Test updating instance index using both in-place and separate src/dst acceleration structures
4473     addTestGroup(group.get(), "instance_update", addInstanceUpdateTests);
4474     // Exercise dynamic indexing of acceleration structures
4475     addTestGroup(group.get(), "dynamic_indexing", addDynamicIndexingTests);
4476     // Test building empty acceleration structures using different methods
4477     addTestGroup(group.get(), "empty", addEmptyAccelerationStructureTests);
4478 
4479     return group.release();
4480 }
4481 
4482 } // namespace RayQuery
4483 
4484 } // namespace vkt
4485