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 cull ray flags in ray query extension
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktRayQueryCullRayFlagsTests.hpp"
25 
26 #include <array>
27 
28 #include "vkDefs.hpp"
29 
30 #include "vktTestCase.hpp"
31 #include "vktTestGroupUtil.hpp"
32 #include "vkCmdUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkBarrierUtil.hpp"
36 #include "vkBufferWithMemory.hpp"
37 #include "vkImageWithMemory.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkImageUtil.hpp"
40 #include "deRandom.hpp"
41 #include "tcuTexture.hpp"
42 #include "tcuTextureUtil.hpp"
43 #include "tcuTestLog.hpp"
44 #include "tcuImageCompare.hpp"
45 
46 #include "vkRayTracingUtil.hpp"
47 
48 namespace vkt
49 {
50 namespace RayQuery
51 {
52 namespace
53 {
54 using namespace vk;
55 using namespace vkt;
56 
57 static const VkFlags ALL_RAY_TRACING_STAGES = VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
58                                               VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR |
59                                               VK_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
60 
61 enum ShaderSourcePipeline
62 {
63     SSP_GRAPHICS_PIPELINE,
64     SSP_COMPUTE_PIPELINE,
65     SSP_RAY_TRACING_PIPELINE
66 };
67 
68 enum ShaderSourceType
69 {
70     SST_VERTEX_SHADER,
71     SST_TESSELATION_CONTROL_SHADER,
72     SST_TESSELATION_EVALUATION_SHADER,
73     SST_GEOMETRY_SHADER,
74     SST_FRAGMENT_SHADER,
75     SST_COMPUTE_SHADER,
76     SST_RAY_GENERATION_SHADER,
77     SST_INTERSECTION_SHADER,
78     SST_ANY_HIT_SHADER,
79     SST_CLOSEST_HIT_SHADER,
80     SST_MISS_SHADER,
81     SST_CALLABLE_SHADER,
82 };
83 
84 enum ShaderTestType
85 {
86     STT_OPACITY                = 0,
87     STT_TERMINATE_ON_FIRST_HIT = 1,
88     STT_FACE_CULLING           = 2,
89     STT_SKIP_GEOMETRY          = 3,
90 };
91 
92 enum RayFlags
93 {
94     RF_None                     = 0U,
95     RF_Opaque                   = 1U,
96     RF_NoOpaque                 = 2U,
97     RF_TerminateOnFirstHit      = 4U,
98     RF_SkipClosestHitShader     = 8U,
99     RF_CullBackFacingTriangles  = 16U,
100     RF_CullFrontFacingTriangles = 32U,
101     RF_CullOpaque               = 64U,
102     RF_CullNoOpaque             = 128U,
103     RF_SkipTriangles            = 256U,
104     RF_SkipAABB                 = 512U,
105 };
106 
107 enum BottomTestType
108 {
109     BTT_TRIANGLES = 0,
110     BTT_AABBS     = 1,
111 };
112 
113 const uint32_t TEST_WIDTH  = 8;
114 const uint32_t TEST_HEIGHT = 8;
115 
116 struct TestParams;
117 
getRayFlagTestName(const RayFlags & flag)118 std::string getRayFlagTestName(const RayFlags &flag)
119 {
120     switch (flag)
121     {
122     case RF_None:
123         return std::string("none");
124     case RF_Opaque:
125         return std::string("opaque");
126     case RF_NoOpaque:
127         return std::string("noopaque");
128     case RF_TerminateOnFirstHit:
129         return std::string("terminateonfirsthit");
130     case RF_SkipClosestHitShader:
131         return std::string("skipclosesthitshader");
132     case RF_CullBackFacingTriangles:
133         return std::string("cullbackfacingtriangles");
134     case RF_CullFrontFacingTriangles:
135         return std::string("cullfrontfacingtriangles");
136     case RF_CullOpaque:
137         return std::string("cullopaque");
138     case RF_CullNoOpaque:
139         return std::string("cullnoopaque");
140     case RF_SkipTriangles:
141         return std::string("skiptriangles");
142     case RF_SkipAABB:
143         return std::string("skipaabb");
144     default:
145         TCU_THROW(InternalError, "Wrong flag");
146     }
147     return std::string();
148 }
149 
150 class TestConfiguration
151 {
152 public:
153     virtual ~TestConfiguration();
154     virtual void initConfiguration(Context &context, TestParams &testParams) = 0;
155     virtual void fillCommandBuffer(
156         Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
157         const VkWriteDescriptorSetAccelerationStructureKHR &rayQueryAccelerationStructureWriteDescriptorSet,
158         const VkDescriptorBufferInfo &paramBufferDescriptorInfo, const VkDescriptorImageInfo &resultImageInfo) = 0;
159     virtual bool verifyImage(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams)         = 0;
160     virtual VkFormat getResultImageFormat()                                                                    = 0;
161     virtual size_t getResultImageFormatSize()                                                                  = 0;
162     virtual VkClearValue getClearValue()                                                                       = 0;
163 };
164 
~TestConfiguration()165 TestConfiguration::~TestConfiguration()
166 {
167 }
168 
169 struct TestParams
170 {
171     uint32_t width;
172     uint32_t height;
173     ShaderSourceType shaderSourceType;
174     ShaderSourcePipeline shaderSourcePipeline;
175     ShaderTestType shaderTestType;
176     RayFlags flag0;
177     RayFlags flag1;
178     BottomTestType bottomType;
179 };
180 
getShaderGroupHandleSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)181 uint32_t getShaderGroupHandleSize(const InstanceInterface &vki, const VkPhysicalDevice physicalDevice)
182 {
183     de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
184 
185     rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
186     return rayTracingPropertiesKHR->getShaderGroupHandleSize();
187 }
188 
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)189 uint32_t getShaderGroupBaseAlignment(const InstanceInterface &vki, const VkPhysicalDevice physicalDevice)
190 {
191     de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
192 
193     rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
194     return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
195 }
196 
makeImageCreateInfo(uint32_t width,uint32_t height,uint32_t depth,VkFormat format)197 VkImageCreateInfo makeImageCreateInfo(uint32_t width, uint32_t height, uint32_t depth, VkFormat format)
198 {
199     const VkImageCreateInfo imageCreateInfo = {
200         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
201         DE_NULL,                             // const void* pNext;
202         (VkImageCreateFlags)0u,              // VkImageCreateFlags flags;
203         VK_IMAGE_TYPE_3D,                    // VkImageType imageType;
204         format,                              // VkFormat format;
205         makeExtent3D(width, height, depth),  // VkExtent3D extent;
206         1u,                                  // uint32_t mipLevels;
207         1u,                                  // uint32_t arrayLayers;
208         VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits samples;
209         VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling tiling;
210         VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
211             VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
212         VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode sharingMode;
213         0u,                                  // uint32_t queueFamilyIndexCount;
214         DE_NULL,                             // const uint32_t* pQueueFamilyIndices;
215         VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout initialLayout;
216     };
217 
218     return imageCreateInfo;
219 }
220 
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)221 bool registerShaderModule(const DeviceInterface &vkd, const VkDevice device, Context &context,
222                           std::vector<de::SharedPtr<Move<VkShaderModule>>> &shaderModules,
223                           std::vector<VkPipelineShaderStageCreateInfo> &shaderCreateInfos, VkShaderStageFlagBits stage,
224                           const std::string &externalNamePart, const std::string &internalNamePart)
225 {
226     char fullShaderName[40];
227     snprintf(fullShaderName, 40, externalNamePart.c_str(), internalNamePart.c_str());
228     std::string fsn = fullShaderName;
229     if (fsn.empty())
230         return false;
231 
232     shaderModules.push_back(
233         makeVkSharedPtr(createShaderModule(vkd, device, context.getBinaryCollection().get(fsn), 0)));
234 
235     shaderCreateInfos.push_back({
236         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, DE_NULL, (VkPipelineShaderStageCreateFlags)0,
237         stage,                       // stage
238         shaderModules.back()->get(), // shader
239         "main",
240         DE_NULL, // pSpecializationInfo
241     });
242 
243     return true;
244 }
245 
registerShaderModule(const DeviceInterface & vkd,const VkDevice device,Context & context,RayTracingPipeline & rayTracingPipeline,VkShaderStageFlagBits shaderStage,const std::string & externalNamePart,const std::string & internalNamePart,uint32_t groupIndex)246 bool registerShaderModule(const DeviceInterface &vkd, const VkDevice device, Context &context,
247                           RayTracingPipeline &rayTracingPipeline, VkShaderStageFlagBits shaderStage,
248                           const std::string &externalNamePart, const std::string &internalNamePart, uint32_t groupIndex)
249 {
250     char fullShaderName[40];
251     snprintf(fullShaderName, 40, externalNamePart.c_str(), internalNamePart.c_str());
252     std::string fsn = fullShaderName;
253     if (fsn.empty())
254         return false;
255     Move<VkShaderModule> shaderModule = createShaderModule(vkd, device, context.getBinaryCollection().get(fsn), 0);
256     if (*shaderModule == DE_NULL)
257         return false;
258     rayTracingPipeline.addShader(shaderStage, shaderModule, groupIndex);
259     return true;
260 }
261 
getHitResult(const TestParams & testParams)262 std::vector<uint32_t> getHitResult(const TestParams &testParams)
263 {
264     uint32_t rayFlags               = testParams.flag0 | testParams.flag1;
265     std::vector<uint32_t> hitResult = {2, 1, 2, 1};
266     switch (testParams.shaderTestType)
267     {
268     case STT_OPACITY:
269     {
270         if (rayFlags & RF_Opaque)
271             hitResult = {2, 2, 2, 2};
272         if (rayFlags & RF_NoOpaque)
273             hitResult = {1, 1, 1, 1};
274         if (rayFlags & RF_CullOpaque)
275             std::replace(std::begin(hitResult), std::end(hitResult), 2, 0);
276         if (rayFlags & RF_CullNoOpaque)
277             std::replace(std::begin(hitResult), std::end(hitResult), 1, 0);
278         break;
279     }
280     case STT_TERMINATE_ON_FIRST_HIT:
281     {
282         // all triangles should be hit
283         break;
284     }
285     case STT_FACE_CULLING:
286     {
287         if (testParams.bottomType == BTT_AABBS)
288             break;
289         if (rayFlags & RF_CullBackFacingTriangles)
290             hitResult = {2, 1, 0, 0};
291         if (rayFlags & RF_CullFrontFacingTriangles)
292             hitResult = {0, 0, 2, 1};
293         break;
294     }
295     case STT_SKIP_GEOMETRY:
296     {
297         if (testParams.bottomType == BTT_TRIANGLES && rayFlags & RF_SkipTriangles)
298             hitResult = {0, 0, 0, 0};
299         if (testParams.bottomType == BTT_AABBS && rayFlags & RF_SkipAABB)
300             hitResult = {0, 0, 0, 0};
301         break;
302     }
303     default:
304         TCU_THROW(InternalError, "Wrong shader test type");
305     }
306     return hitResult;
307 }
308 
309 class GraphicsConfiguration : public TestConfiguration
310 {
311 public:
312     virtual ~GraphicsConfiguration();
313     void initConfiguration(Context &context, TestParams &testParams) override;
314     void fillCommandBuffer(
315         Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
316         const VkWriteDescriptorSetAccelerationStructureKHR &rayQueryAccelerationStructureWriteDescriptorSet,
317         const VkDescriptorBufferInfo &paramBufferDescriptorInfo, const VkDescriptorImageInfo &resultImageInfo) override;
318     bool verifyImage(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams) override;
319     VkFormat getResultImageFormat() override;
320     size_t getResultImageFormatSize() override;
321     VkClearValue getClearValue() override;
322 
323 protected:
324     Move<VkDescriptorSetLayout> descriptorSetLayout;
325     Move<VkDescriptorPool> descriptorPool;
326     Move<VkDescriptorSet> descriptorSet;
327     Move<VkPipelineLayout> pipelineLayout;
328     Move<VkRenderPass> renderPass;
329     Move<VkFramebuffer> framebuffer;
330     std::vector<de::SharedPtr<Move<VkShaderModule>>> shaderModules;
331     Move<VkPipeline> pipeline;
332     std::vector<tcu::Vec3> vertices;
333     Move<VkBuffer> vertexBuffer;
334     de::MovePtr<Allocation> vertexAlloc;
335 };
336 
~GraphicsConfiguration()337 GraphicsConfiguration::~GraphicsConfiguration()
338 {
339     shaderModules.clear();
340 }
341 
initConfiguration(Context & context,TestParams & testParams)342 void GraphicsConfiguration::initConfiguration(Context &context, TestParams &testParams)
343 {
344     const DeviceInterface &vkd      = context.getDeviceInterface();
345     const VkDevice device           = context.getDevice();
346     const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
347     Allocator &allocator            = context.getDefaultAllocator();
348 
349     descriptorSetLayout =
350         DescriptorSetLayoutBuilder()
351             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL_GRAPHICS)
352             .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL_GRAPHICS)
353             .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_ALL_GRAPHICS)
354             .build(vkd, device);
355     descriptorPool = DescriptorPoolBuilder()
356                          .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
357                          .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
358                          .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
359                          .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
360     descriptorSet  = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
361     pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
362 
363     std::vector<std::string> rayQueryTestName;
364     rayQueryTestName.push_back("rayflags_triangle");
365     rayQueryTestName.push_back("rayflags_aabb");
366 
367     const std::map<ShaderSourceType, std::vector<std::string>> shaderNames = {
368         //idx: 0                1                2                3                4
369         //shader: vert, tesc, tese, geom, frag,
370         {SST_VERTEX_SHADER,
371          {
372              "vert_%s",
373              "",
374              "",
375              "",
376              "",
377          }},
378         {SST_TESSELATION_CONTROL_SHADER,
379          {
380              "vert",
381              "tesc_%s",
382              "tese",
383              "",
384              "",
385          }},
386         {SST_TESSELATION_EVALUATION_SHADER,
387          {
388              "vert",
389              "tesc",
390              "tese_%s",
391              "",
392              "",
393          }},
394         {SST_GEOMETRY_SHADER,
395          {
396              "vert_vid",
397              "",
398              "",
399              "geom_%s",
400              "",
401          }},
402         {SST_FRAGMENT_SHADER,
403          {
404              "vert",
405              "",
406              "",
407              "",
408              "frag_%s",
409          }},
410     };
411 
412     auto shaderNameIt = shaderNames.find(testParams.shaderSourceType);
413     if (shaderNameIt == end(shaderNames))
414         TCU_THROW(InternalError, "Wrong shader source type");
415 
416     std::vector<VkPipelineShaderStageCreateInfo> shaderCreateInfos;
417     bool tescX, teseX, fragX;
418     registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_VERTEX_BIT,
419                          shaderNameIt->second[0], rayQueryTestName[testParams.bottomType]);
420     tescX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos,
421                                  VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, shaderNameIt->second[1],
422                                  rayQueryTestName[testParams.bottomType]);
423     teseX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos,
424                                  VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, shaderNameIt->second[2],
425                                  rayQueryTestName[testParams.bottomType]);
426     registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_GEOMETRY_BIT,
427                          shaderNameIt->second[3], rayQueryTestName[testParams.bottomType]);
428     fragX = registerShaderModule(vkd, device, context, shaderModules, shaderCreateInfos, VK_SHADER_STAGE_FRAGMENT_BIT,
429                                  shaderNameIt->second[4], rayQueryTestName[testParams.bottomType]);
430 
431     const vk::VkSubpassDescription subpassDesc = {
432         (vk::VkSubpassDescriptionFlags)0,
433         vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
434         0u,                                  // inputCount
435         DE_NULL,                             // pInputAttachments
436         0u,                                  // colorCount
437         DE_NULL,                             // pColorAttachments
438         DE_NULL,                             // pResolveAttachments
439         DE_NULL,                             // depthStencilAttachment
440         0u,                                  // preserveCount
441         DE_NULL,                             // pPreserveAttachments
442     };
443     const vk::VkRenderPassCreateInfo renderPassParams = {
444         vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // sType
445         DE_NULL,                                       // pNext
446         (vk::VkRenderPassCreateFlags)0,
447         0u,           // attachmentCount
448         DE_NULL,      // pAttachments
449         1u,           // subpassCount
450         &subpassDesc, // pSubpasses
451         0u,           // dependencyCount
452         DE_NULL,      // pDependencies
453     };
454 
455     renderPass = createRenderPass(vkd, device, &renderPassParams);
456 
457     const vk::VkFramebufferCreateInfo framebufferParams = {
458         vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // sType
459         DE_NULL,                                       // pNext
460         (vk::VkFramebufferCreateFlags)0,
461         *renderPass,       // renderPass
462         0u,                // attachmentCount
463         DE_NULL,           // pAttachments
464         testParams.width,  // width
465         testParams.height, // height
466         1u,                // layers
467     };
468 
469     framebuffer = createFramebuffer(vkd, device, &framebufferParams);
470 
471     VkPrimitiveTopology testTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
472     tcu::Vec3 v0(2.0f, 2.0f, 0.0f);
473     tcu::Vec3 v1(float(testParams.width) - 2.0f, 2.0f, 0.0f);
474     tcu::Vec3 v2(2.0f, float(testParams.height) - 2.0f, 0.0f);
475     tcu::Vec3 v3(float(testParams.width) - 2.0f, float(testParams.height) - 2.0f, 0.0f);
476 
477     switch (testParams.shaderSourceType)
478     {
479     case SST_TESSELATION_CONTROL_SHADER:
480     case SST_TESSELATION_EVALUATION_SHADER:
481         testTopology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
482         vertices.push_back(v0);
483         vertices.push_back(v1);
484         vertices.push_back(v2);
485         vertices.push_back(v1);
486         vertices.push_back(v3);
487         vertices.push_back(v2);
488         break;
489     case SST_VERTEX_SHADER:
490     case SST_GEOMETRY_SHADER:
491         vertices.push_back(v0);
492         vertices.push_back(v1);
493         vertices.push_back(v2);
494         vertices.push_back(v3);
495         break;
496     case SST_FRAGMENT_SHADER:
497         vertices.push_back(tcu::Vec3(-1.0f, 1.0f, 0.0f));
498         vertices.push_back(tcu::Vec3(-1.0f, -1.0f, 0.0f));
499         vertices.push_back(tcu::Vec3(1.0f, 1.0f, 0.0f));
500         vertices.push_back(tcu::Vec3(1.0f, -1.0f, 0.0f));
501         break;
502     default:
503         TCU_THROW(InternalError, "Wrong shader source type");
504     }
505 
506     const VkVertexInputBindingDescription vertexInputBindingDescription = {
507         0u,                          // uint32_t binding;
508         sizeof(tcu::Vec3),           // uint32_t stride;
509         VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
510     };
511 
512     const VkVertexInputAttributeDescription vertexInputAttributeDescription = {
513         0u,                         // uint32_t location;
514         0u,                         // uint32_t binding;
515         VK_FORMAT_R32G32B32_SFLOAT, // VkFormat format;
516         0u,                         // uint32_t offset;
517     };
518 
519     const VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo = {
520         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
521         DE_NULL,                                                   // const void* pNext;
522         (VkPipelineVertexInputStateCreateFlags)0,                  // VkPipelineVertexInputStateCreateFlags flags;
523         1u,                                                        // uint32_t vertexBindingDescriptionCount;
524         &vertexInputBindingDescription,  // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
525         1u,                              // uint32_t vertexAttributeDescriptionCount;
526         &vertexInputAttributeDescription // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
527     };
528 
529     const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateCreateInfo = {
530         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
531         DE_NULL,                                                     // const void* pNext;
532         (VkPipelineInputAssemblyStateCreateFlags)0,                  // VkPipelineInputAssemblyStateCreateFlags flags;
533         testTopology,                                                // VkPrimitiveTopology topology;
534         VK_FALSE                                                     // VkBool32 primitiveRestartEnable;
535     };
536 
537     const VkPipelineTessellationStateCreateInfo tessellationStateCreateInfo = {
538         VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
539         DE_NULL,                                                   // const void* pNext;
540         VkPipelineTessellationStateCreateFlags(0u),                // VkPipelineTessellationStateCreateFlags flags;
541         3u                                                         // uint32_t patchControlPoints;
542     };
543 
544     VkViewport viewport = makeViewport(testParams.width, testParams.height);
545     VkRect2D scissor    = makeRect2D(testParams.width, testParams.height);
546 
547     const VkPipelineViewportStateCreateInfo viewportStateCreateInfo = {
548         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType                                    sType
549         DE_NULL,                               // const void*                                        pNext
550         (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags                flags
551         1u,                                    // uint32_t                                            viewportCount
552         &viewport,                             // const VkViewport*                                pViewports
553         1u,                                    // uint32_t                                            scissorCount
554         &scissor                               // const VkRect2D*                                    pScissors
555     };
556 
557     const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo = {
558         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
559         DE_NULL,                                                    // const void* pNext;
560         (VkPipelineRasterizationStateCreateFlags)0,                 // VkPipelineRasterizationStateCreateFlags flags;
561         VK_FALSE,                                                   // VkBool32 depthClampEnable;
562         fragX ? VK_FALSE : VK_TRUE,                                 // VkBool32 rasterizerDiscardEnable;
563         VK_POLYGON_MODE_FILL,                                       // VkPolygonMode polygonMode;
564         VK_CULL_MODE_NONE,                                          // VkCullModeFlags cullMode;
565         VK_FRONT_FACE_CLOCKWISE,                                    // VkFrontFace frontFace;
566         VK_FALSE,                                                   // VkBool32 depthBiasEnable;
567         0.0f,                                                       // float depthBiasConstantFactor;
568         0.0f,                                                       // float depthBiasClamp;
569         0.0f,                                                       // float depthBiasSlopeFactor;
570         1.0f                                                        // float lineWidth;
571     };
572 
573     const VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo = {
574         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
575         DE_NULL,                                                  // const void* pNext;
576         (VkPipelineMultisampleStateCreateFlags)0,                 // VkPipelineMultisampleStateCreateFlags flags;
577         VK_SAMPLE_COUNT_1_BIT,                                    // VkSampleCountFlagBits rasterizationSamples;
578         VK_FALSE,                                                 // VkBool32 sampleShadingEnable;
579         0.0f,                                                     // float minSampleShading;
580         DE_NULL,                                                  // const VkSampleMask* pSampleMask;
581         VK_FALSE,                                                 // VkBool32 alphaToCoverageEnable;
582         VK_FALSE                                                  // VkBool32 alphaToOneEnable;
583     };
584 
585     const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = {
586         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
587         DE_NULL,                                                  // const void* pNext;
588         (VkPipelineColorBlendStateCreateFlags)0,                  // VkPipelineColorBlendStateCreateFlags flags;
589         false,                                                    // VkBool32 logicOpEnable;
590         VK_LOGIC_OP_CLEAR,                                        // VkLogicOp logicOp;
591         0,                                                        // uint32_t attachmentCount;
592         DE_NULL,                 // const VkPipelineColorBlendAttachmentState* pAttachments;
593         {1.0f, 1.0f, 1.0f, 1.0f} // float blendConstants[4];
594     };
595 
596     const VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {
597         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
598         DE_NULL,                                         // const void* pNext;
599         (VkPipelineCreateFlags)0,                        // VkPipelineCreateFlags flags;
600         static_cast<uint32_t>(shaderCreateInfos.size()), // uint32_t stageCount;
601         shaderCreateInfos.data(),                        // const VkPipelineShaderStageCreateInfo* pStages;
602         &vertexInputStateCreateInfo,   // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
603         &inputAssemblyStateCreateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
604         (tescX || teseX) ? &tessellationStateCreateInfo :
605                            DE_NULL,                 // const VkPipelineTessellationStateCreateInfo* pTessellationState;
606         fragX ? &viewportStateCreateInfo : DE_NULL, // const VkPipelineViewportStateCreateInfo* pViewportState;
607         &rasterizationStateCreateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
608         fragX ? &multisampleStateCreateInfo : DE_NULL, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
609         DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
610         fragX ? &colorBlendStateCreateInfo : DE_NULL, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
611         DE_NULL,                                      // const VkPipelineDynamicStateCreateInfo* pDynamicState;
612         pipelineLayout.get(),                         // VkPipelineLayout layout;
613         renderPass.get(),                             // VkRenderPass renderPass;
614         0u,                                           // uint32_t subpass;
615         DE_NULL,                                      // VkPipeline basePipelineHandle;
616         0                                             // int basePipelineIndex;
617     };
618 
619     pipeline = createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineCreateInfo);
620 
621     const VkBufferCreateInfo vertexBufferParams = {
622         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                 // VkStructureType sType;
623         DE_NULL,                                                              // const void* pNext;
624         0u,                                                                   // VkBufferCreateFlags flags;
625         VkDeviceSize(sizeof(tcu::Vec3) * vertices.size()),                    // VkDeviceSize size;
626         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
627         VK_SHARING_MODE_EXCLUSIVE,                                            // VkSharingMode sharingMode;
628         1u,                                                                   // uint32_t queueFamilyIndexCount;
629         &queueFamilyIndex                                                     // const uint32_t* pQueueFamilyIndices;
630     };
631 
632     vertexBuffer = createBuffer(vkd, device, &vertexBufferParams);
633     vertexAlloc =
634         allocator.allocate(getBufferMemoryRequirements(vkd, device, *vertexBuffer), MemoryRequirement::HostVisible);
635     VK_CHECK(vkd.bindBufferMemory(device, *vertexBuffer, vertexAlloc->getMemory(), vertexAlloc->getOffset()));
636 
637     // Upload vertex data
638     deMemcpy(vertexAlloc->getHostPtr(), vertices.data(), vertices.size() * sizeof(tcu::Vec3));
639     flushAlloc(vkd, device, *vertexAlloc);
640 }
641 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorBufferInfo & paramBufferDescriptorInfo,const VkDescriptorImageInfo & resultImageInfo)642 void GraphicsConfiguration::fillCommandBuffer(
643     Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
644     const VkWriteDescriptorSetAccelerationStructureKHR &rayQueryAccelerationStructureWriteDescriptorSet,
645     const VkDescriptorBufferInfo &paramBufferDescriptorInfo, const VkDescriptorImageInfo &resultImageInfo)
646 {
647     const DeviceInterface &vkd = context.getDeviceInterface();
648     const VkDevice device      = context.getDevice();
649 
650     DescriptorSetUpdateBuilder()
651         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
652                      VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
653         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
654                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
655         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u),
656                      VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &paramBufferDescriptorInfo)
657         .update(vkd, device);
658 
659     const VkRenderPassBeginInfo renderPassBeginInfo = {
660         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,        // VkStructureType sType;
661         DE_NULL,                                         // const void* pNext;
662         *renderPass,                                     // VkRenderPass renderPass;
663         *framebuffer,                                    // VkFramebuffer framebuffer;
664         makeRect2D(testParams.width, testParams.height), // VkRect2D renderArea;
665         0u,                                              // uint32_t clearValueCount;
666         DE_NULL                                          // const VkClearValue* pClearValues;
667     };
668     VkDeviceSize vertexBufferOffset = 0u;
669 
670     vkd.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
671     vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
672     vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u,
673                               &descriptorSet.get(), 0u, DE_NULL);
674     vkd.cmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
675     vkd.cmdDraw(commandBuffer, uint32_t(vertices.size()), 1, 0, 0);
676     vkd.cmdEndRenderPass(commandBuffer);
677 }
678 
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)679 bool GraphicsConfiguration::verifyImage(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams)
680 {
681     // create result image
682     tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat());
683     tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2,
684                                              resultBuffer->getAllocation().getHostPtr());
685 
686     // create reference image
687     std::vector<uint32_t> reference(testParams.width * testParams.height * 2);
688     tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
689 
690     // 4 squares have characteristics: (front, opaque), (front, no_opaque), (back, opaque), (back, no_opaque)
691     // First we calculate test results for each square
692     std::vector<uint32_t> hitResult = getHitResult(testParams);
693 
694     std::vector<std::vector<tcu::UVec2>> squares = {
695         {{1, 1}, {4, 4}},
696         {{4, 1}, {7, 4}},
697         {{1, 4}, {4, 7}},
698         {{4, 4}, {7, 7}},
699     };
700     std::vector<std::vector<uint32_t>> primitives = {{0, 1, 2}, {1, 3, 2}};
701 
702     tcu::UVec4 missValue(0, 0, 0, 0);
703     tcu::UVec4 clearValue(0xFF, 0, 0, 0);
704 
705     switch (testParams.shaderSourceType)
706     {
707     case SST_VERTEX_SHADER:
708         tcu::clear(referenceAccess, clearValue);
709         for (uint32_t vNdx = 0; vNdx < 4; ++vNdx)
710         {
711             tcu::UVec4 hitValue(hitResult[vNdx], 0, 0, 0);
712             referenceAccess.setPixel(hitValue, vNdx, 0, 0);
713             referenceAccess.setPixel(hitValue, vNdx, 0, 1);
714         }
715         break;
716     case SST_TESSELATION_CONTROL_SHADER:
717     case SST_TESSELATION_EVALUATION_SHADER:
718     case SST_GEOMETRY_SHADER:
719         tcu::clear(referenceAccess, clearValue);
720         for (uint32_t primitiveNdx = 0; primitiveNdx < primitives.size(); ++primitiveNdx)
721             for (uint32_t vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
722             {
723                 uint32_t vNdx = primitives[primitiveNdx][vertexNdx];
724                 tcu::UVec4 hitValue(hitResult[vNdx], 0, 0, 0);
725                 referenceAccess.setPixel(hitValue, primitiveNdx, vertexNdx, 0);
726                 referenceAccess.setPixel(hitValue, primitiveNdx, vertexNdx, 1);
727             }
728         break;
729     case SST_FRAGMENT_SHADER:
730         tcu::clear(referenceAccess, missValue);
731         for (uint32_t squareNdx = 0; squareNdx < squares.size(); ++squareNdx)
732         {
733             tcu::UVec4 hitValue(hitResult[squareNdx], 0, 0, 0);
734             for (uint32_t y = squares[squareNdx][0].y(); y < squares[squareNdx][1].y(); ++y)
735                 for (uint32_t x = squares[squareNdx][0].x(); x < squares[squareNdx][1].x(); ++x)
736                 {
737                     referenceAccess.setPixel(hitValue, x, y, 0);
738                     referenceAccess.setPixel(hitValue, x, y, 1);
739                 }
740         }
741         break;
742     default:
743         TCU_THROW(InternalError, "Wrong shader source type");
744     }
745 
746     // compare result and reference
747     return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess,
748                                     resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
749 }
750 
getResultImageFormat()751 VkFormat GraphicsConfiguration::getResultImageFormat()
752 {
753     return VK_FORMAT_R32_UINT;
754 }
755 
getResultImageFormatSize()756 size_t GraphicsConfiguration::getResultImageFormatSize()
757 {
758     return sizeof(uint32_t);
759 }
760 
getClearValue()761 VkClearValue GraphicsConfiguration::getClearValue()
762 {
763     return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
764 }
765 
766 class ComputeConfiguration : public TestConfiguration
767 {
768 public:
769     virtual ~ComputeConfiguration();
770     void initConfiguration(Context &context, TestParams &testParams) override;
771     void fillCommandBuffer(
772         Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
773         const VkWriteDescriptorSetAccelerationStructureKHR &rayQueryAccelerationStructureWriteDescriptorSet,
774         const VkDescriptorBufferInfo &paramBufferDescriptorInfo, const VkDescriptorImageInfo &resultImageInfo) override;
775     bool verifyImage(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams) override;
776     VkFormat getResultImageFormat() override;
777     size_t getResultImageFormatSize() override;
778     VkClearValue getClearValue() override;
779 
780 protected:
781     Move<VkDescriptorSetLayout> descriptorSetLayout;
782     Move<VkDescriptorPool> descriptorPool;
783     Move<VkDescriptorSet> descriptorSet;
784     Move<VkPipelineLayout> pipelineLayout;
785     Move<VkShaderModule> shaderModule;
786     Move<VkPipeline> pipeline;
787 };
788 
~ComputeConfiguration()789 ComputeConfiguration::~ComputeConfiguration()
790 {
791 }
792 
initConfiguration(Context & context,TestParams & testParams)793 void ComputeConfiguration::initConfiguration(Context &context, TestParams &testParams)
794 {
795     const DeviceInterface &vkd = context.getDeviceInterface();
796     const VkDevice device      = context.getDevice();
797 
798     descriptorSetLayout =
799         DescriptorSetLayoutBuilder()
800             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
801             .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_COMPUTE_BIT)
802             .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
803             .build(vkd, device);
804     descriptorPool = DescriptorPoolBuilder()
805                          .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
806                          .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
807                          .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
808                          .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
809     descriptorSet  = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
810     pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
811 
812     std::vector<std::string> rayQueryTestName;
813     rayQueryTestName.push_back("comp_rayflags_triangle");
814     rayQueryTestName.push_back("comp_rayflags_aabb");
815 
816     shaderModule =
817         createShaderModule(vkd, device, context.getBinaryCollection().get(rayQueryTestName[testParams.bottomType]), 0u);
818     const VkPipelineShaderStageCreateInfo pipelineShaderStageParams = {
819         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
820         DE_NULL,                                             // const void* pNext;
821         0u,                                                  // VkPipelineShaderStageCreateFlags flags;
822         VK_SHADER_STAGE_COMPUTE_BIT,                         // VkShaderStageFlagBits stage;
823         *shaderModule,                                       // VkShaderModule module;
824         "main",                                              // const char* pName;
825         DE_NULL,                                             // const VkSpecializationInfo* pSpecializationInfo;
826     };
827     const VkComputePipelineCreateInfo pipelineCreateInfo = {
828         VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
829         DE_NULL,                                        // const void* pNext;
830         0u,                                             // VkPipelineCreateFlags flags;
831         pipelineShaderStageParams,                      // VkPipelineShaderStageCreateInfo stage;
832         *pipelineLayout,                                // VkPipelineLayout layout;
833         DE_NULL,                                        // VkPipeline basePipelineHandle;
834         0,                                              // int32_t basePipelineIndex;
835     };
836 
837     pipeline = createComputePipeline(vkd, device, DE_NULL, &pipelineCreateInfo);
838 }
839 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorBufferInfo & paramBufferDescriptorInfo,const VkDescriptorImageInfo & resultImageInfo)840 void ComputeConfiguration::fillCommandBuffer(
841     Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
842     const VkWriteDescriptorSetAccelerationStructureKHR &rayQueryAccelerationStructureWriteDescriptorSet,
843     const VkDescriptorBufferInfo &paramBufferDescriptorInfo, const VkDescriptorImageInfo &resultImageInfo)
844 {
845     const DeviceInterface &vkd = context.getDeviceInterface();
846     const VkDevice device      = context.getDevice();
847 
848     DescriptorSetUpdateBuilder()
849         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
850                      VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
851         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
852                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
853         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u),
854                      VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &paramBufferDescriptorInfo)
855         .update(vkd, device);
856 
857     vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
858 
859     vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u,
860                               &descriptorSet.get(), 0u, DE_NULL);
861 
862     vkd.cmdDispatch(commandBuffer, testParams.width, testParams.height, 1);
863 }
864 
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)865 bool ComputeConfiguration::verifyImage(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams)
866 {
867     // create result image
868     tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat());
869     tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2,
870                                              resultBuffer->getAllocation().getHostPtr());
871 
872     // create reference image
873     std::vector<uint32_t> reference(testParams.width * testParams.height * 2);
874     tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
875 
876     // 4 squares have characteristics: (front, opaque), (front, no_opaque), (back, opaque), (back, no_opaque)
877     // First we calculate test results for each square
878     std::vector<uint32_t> hitResult = getHitResult(testParams);
879 
880     std::vector<std::vector<tcu::UVec2>> squares = {
881         {{1, 1}, {4, 4}},
882         {{4, 1}, {7, 4}},
883         {{1, 4}, {4, 7}},
884         {{4, 4}, {7, 7}},
885     };
886 
887     tcu::UVec4 missValue(0, 0, 0, 0);
888     tcu::clear(referenceAccess, missValue);
889 
890     for (uint32_t squareNdx = 0; squareNdx < squares.size(); ++squareNdx)
891     {
892         tcu::UVec4 hitValue(hitResult[squareNdx], 0, 0, 0);
893         for (uint32_t y = squares[squareNdx][0].y(); y < squares[squareNdx][1].y(); ++y)
894             for (uint32_t x = squares[squareNdx][0].x(); x < squares[squareNdx][1].x(); ++x)
895             {
896                 referenceAccess.setPixel(hitValue, x, y, 0);
897                 referenceAccess.setPixel(hitValue, x, y, 1);
898             }
899     }
900 
901     // compare result and reference
902     return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess,
903                                     resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
904 }
905 
getResultImageFormat()906 VkFormat ComputeConfiguration::getResultImageFormat()
907 {
908     return VK_FORMAT_R32_UINT;
909 }
910 
getResultImageFormatSize()911 size_t ComputeConfiguration::getResultImageFormatSize()
912 {
913     return sizeof(uint32_t);
914 }
915 
getClearValue()916 VkClearValue ComputeConfiguration::getClearValue()
917 {
918     return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
919 }
920 
921 class RayTracingConfiguration : public TestConfiguration
922 {
923 public:
924     virtual ~RayTracingConfiguration();
925     void initConfiguration(Context &context, TestParams &testParams) override;
926     void fillCommandBuffer(
927         Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
928         const VkWriteDescriptorSetAccelerationStructureKHR &rayQueryAccelerationStructureWriteDescriptorSet,
929         const VkDescriptorBufferInfo &paramBufferDescriptorInfo, const VkDescriptorImageInfo &resultImageInfo) override;
930     bool verifyImage(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams) override;
931     VkFormat getResultImageFormat() override;
932     size_t getResultImageFormatSize() override;
933     VkClearValue getClearValue() override;
934 
935 protected:
936     Move<VkDescriptorSetLayout> descriptorSetLayout;
937     Move<VkDescriptorPool> descriptorPool;
938     Move<VkDescriptorSet> descriptorSet;
939     Move<VkPipelineLayout> pipelineLayout;
940 
941     de::MovePtr<RayTracingPipeline> rayTracingPipeline;
942     Move<VkPipeline> rtPipeline;
943 
944     de::MovePtr<BufferWithMemory> raygenShaderBindingTable;
945     de::MovePtr<BufferWithMemory> hitShaderBindingTable;
946     de::MovePtr<BufferWithMemory> missShaderBindingTable;
947     de::MovePtr<BufferWithMemory> callableShaderBindingTable;
948 
949     std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> bottomLevelAccelerationStructures;
950     de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure;
951 };
952 
~RayTracingConfiguration()953 RayTracingConfiguration::~RayTracingConfiguration()
954 {
955 }
956 
initConfiguration(Context & context,TestParams & testParams)957 void RayTracingConfiguration::initConfiguration(Context &context, TestParams &testParams)
958 {
959     const InstanceInterface &vki          = context.getInstanceInterface();
960     const DeviceInterface &vkd            = context.getDeviceInterface();
961     const VkDevice device                 = context.getDevice();
962     const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
963     Allocator &allocator                  = context.getDefaultAllocator();
964 
965     descriptorSetLayout = DescriptorSetLayoutBuilder()
966                               .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
967                               .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
968                               .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
969                               .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, ALL_RAY_TRACING_STAGES)
970                               .build(vkd, device);
971     descriptorPool = DescriptorPoolBuilder()
972                          .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
973                          .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
974                          .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
975                          .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
976                          .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
977     descriptorSet  = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
978     pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
979 
980     rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
981 
982     const std::map<ShaderSourceType, std::vector<std::string>> shaderNames = {
983         //idx: 0                1                2                3                4                5
984         //shader: rgen, isect, ahit, chit, miss, call
985         //group: 0                1                1                1                2                3
986         {SST_RAY_GENERATION_SHADER, {"rgen_%s", "", "", "", "", ""}},
987         {SST_INTERSECTION_SHADER, {"rgen", "isect_%s", "", "chit_isect", "miss", ""}},
988         {SST_ANY_HIT_SHADER, {"rgen", "isect", "ahit_%s", "", "miss", ""}},
989         {SST_CLOSEST_HIT_SHADER, {"rgen", "isect", "", "chit_%s", "miss", ""}},
990         {SST_MISS_SHADER, {"rgen", "isect", "", "chit", "miss_%s", ""}},
991         {SST_CALLABLE_SHADER, {"rgen_call", "", "", "chit", "miss", "call_%s"}},
992     };
993 
994     std::vector<std::string> rayQueryTestName;
995     rayQueryTestName.push_back("rayflags_triangle");
996     rayQueryTestName.push_back("rayflags_aabb");
997 
998     auto shaderNameIt = shaderNames.find(testParams.shaderSourceType);
999     if (shaderNameIt == end(shaderNames))
1000         TCU_THROW(InternalError, "Wrong shader source type");
1001 
1002     bool rgenX, isectX, ahitX, chitX, missX, callX;
1003     rgenX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_RAYGEN_BIT_KHR,
1004                                  shaderNameIt->second[0], rayQueryTestName[testParams.bottomType], 0);
1005     if (testParams.shaderSourceType == SST_INTERSECTION_SHADER)
1006         isectX = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_INTERSECTION_BIT_KHR,
1007                                       shaderNameIt->second[1], rayQueryTestName[testParams.bottomType], 1);
1008     else
1009         isectX = false;
1010     ahitX     = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_ANY_HIT_BIT_KHR,
1011                                      shaderNameIt->second[2], rayQueryTestName[testParams.bottomType], 1);
1012     chitX     = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,
1013                                      shaderNameIt->second[3], rayQueryTestName[testParams.bottomType], 1);
1014     missX     = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_MISS_BIT_KHR,
1015                                      shaderNameIt->second[4], rayQueryTestName[testParams.bottomType], 2);
1016     callX     = registerShaderModule(vkd, device, context, *rayTracingPipeline, VK_SHADER_STAGE_CALLABLE_BIT_KHR,
1017                                      shaderNameIt->second[5], rayQueryTestName[testParams.bottomType], 3);
1018     bool hitX = isectX || ahitX || chitX;
1019 
1020     rtPipeline = rayTracingPipeline->createPipeline(vkd, device, *pipelineLayout);
1021 
1022     uint32_t shaderGroupHandleSize    = getShaderGroupHandleSize(vki, physicalDevice);
1023     uint32_t shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice);
1024 
1025     if (rgenX)
1026         raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(
1027             vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
1028     if (hitX)
1029         hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(
1030             vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
1031     if (missX)
1032         missShaderBindingTable = rayTracingPipeline->createShaderBindingTable(
1033             vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1);
1034     if (callX)
1035         callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(
1036             vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 3, 1);
1037 }
1038 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorBufferInfo & paramBufferDescriptorInfo,const VkDescriptorImageInfo & resultImageInfo)1039 void RayTracingConfiguration::fillCommandBuffer(
1040     Context &context, TestParams &testParams, VkCommandBuffer commandBuffer,
1041     const VkWriteDescriptorSetAccelerationStructureKHR &rayQueryAccelerationStructureWriteDescriptorSet,
1042     const VkDescriptorBufferInfo &paramBufferDescriptorInfo, const VkDescriptorImageInfo &resultImageInfo)
1043 {
1044     const InstanceInterface &vki          = context.getInstanceInterface();
1045     const DeviceInterface &vkd            = context.getDeviceInterface();
1046     const VkDevice device                 = context.getDevice();
1047     const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1048     Allocator &allocator                  = context.getDefaultAllocator();
1049 
1050     {
1051         de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure =
1052             makeBottomLevelAccelerationStructure();
1053         bottomLevelAccelerationStructure->setGeometryCount(1);
1054 
1055         de::SharedPtr<RaytracedGeometryBase> geometry;
1056         if (testParams.shaderSourceType != SST_INTERSECTION_SHADER)
1057         {
1058             tcu::Vec3 v0(0.0f, 0.0f, 0.0f);
1059             tcu::Vec3 v1(float(testParams.width), 0.0f, 0.0f);
1060             tcu::Vec3 v2(0.0f, float(testParams.height), 0.0f);
1061             tcu::Vec3 v3(float(testParams.width), float(testParams.height), 0.0f);
1062             tcu::Vec3 missOffset(0.0f, 0.0f, 0.0f);
1063             if (testParams.shaderSourceType == SST_MISS_SHADER)
1064                 missOffset = tcu::Vec3(1.0f + float(testParams.width), 0.0f, 0.0f);
1065 
1066             geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_FORMAT_R32G32B32_SFLOAT,
1067                                              VK_INDEX_TYPE_NONE_KHR);
1068             geometry->addVertex(v0 + missOffset);
1069             geometry->addVertex(v1 + missOffset);
1070             geometry->addVertex(v2 + missOffset);
1071             geometry->addVertex(v2 + missOffset);
1072             geometry->addVertex(v1 + missOffset);
1073             geometry->addVertex(v3 + missOffset);
1074         }
1075         else // testParams.shaderSourceType == SST_INTERSECTION_SHADER
1076         {
1077             tcu::Vec3 v0(0.0f, 0.0f, -0.1f);
1078             tcu::Vec3 v1(float(testParams.width), float(testParams.height), 0.1f);
1079 
1080             geometry =
1081                 makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1082             geometry->addVertex(v0);
1083             geometry->addVertex(v1);
1084         }
1085         bottomLevelAccelerationStructure->addGeometry(geometry);
1086         bottomLevelAccelerationStructures.push_back(
1087             de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1088 
1089         for (auto &blas : bottomLevelAccelerationStructures)
1090             blas->createAndBuild(vkd, device, commandBuffer, allocator);
1091     }
1092 
1093     topLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1094     topLevelAccelerationStructure->setInstanceCount(1);
1095     topLevelAccelerationStructure->addInstance(bottomLevelAccelerationStructures[0]);
1096     topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1097 
1098     const TopLevelAccelerationStructure *topLevelAccelerationStructurePtr = topLevelAccelerationStructure.get();
1099     VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = {
1100         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, //  VkStructureType sType;
1101         DE_NULL,                                                           //  const void* pNext;
1102         1u,                                                                //  uint32_t accelerationStructureCount;
1103         topLevelAccelerationStructurePtr->getPtr(), //  const VkAccelerationStructureKHR* pAccelerationStructures;
1104     };
1105 
1106     DescriptorSetUpdateBuilder()
1107         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
1108                      VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
1109         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u),
1110                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1111         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u),
1112                      VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
1113         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(3u),
1114                      VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &paramBufferDescriptorInfo)
1115         .update(vkd, device);
1116 
1117     vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1,
1118                               &descriptorSet.get(), 0, DE_NULL);
1119 
1120     vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *rtPipeline);
1121 
1122     uint32_t shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice);
1123     VkStridedDeviceAddressRegionKHR raygenShaderBindingTableRegion =
1124         raygenShaderBindingTable.get() != DE_NULL ?
1125             makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0),
1126                                               shaderGroupHandleSize, shaderGroupHandleSize) :
1127             makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1128     VkStridedDeviceAddressRegionKHR hitShaderBindingTableRegion =
1129         hitShaderBindingTable.get() != DE_NULL ?
1130             makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0),
1131                                               shaderGroupHandleSize, shaderGroupHandleSize) :
1132             makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1133     VkStridedDeviceAddressRegionKHR missShaderBindingTableRegion =
1134         missShaderBindingTable.get() != DE_NULL ?
1135             makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0),
1136                                               shaderGroupHandleSize, shaderGroupHandleSize) :
1137             makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1138     VkStridedDeviceAddressRegionKHR callableShaderBindingTableRegion =
1139         callableShaderBindingTable.get() != DE_NULL ?
1140             makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0),
1141                                               shaderGroupHandleSize, shaderGroupHandleSize) :
1142             makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1143 
1144     cmdTraceRays(vkd, commandBuffer, &raygenShaderBindingTableRegion, &missShaderBindingTableRegion,
1145                  &hitShaderBindingTableRegion, &callableShaderBindingTableRegion, testParams.width, testParams.height,
1146                  1);
1147 }
1148 
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)1149 bool RayTracingConfiguration::verifyImage(BufferWithMemory *resultBuffer, Context &context, TestParams &testParams)
1150 {
1151     // create result image
1152     tcu::TextureFormat imageFormat = vk::mapVkFormat(getResultImageFormat());
1153     tcu::ConstPixelBufferAccess resultAccess(imageFormat, testParams.width, testParams.height, 2,
1154                                              resultBuffer->getAllocation().getHostPtr());
1155 
1156     // create reference image
1157     std::vector<uint32_t> reference(testParams.width * testParams.height * 2);
1158     tcu::PixelBufferAccess referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
1159 
1160     // 4 squares have characteristics: (front, opaque), (front, no_opaque), (back, opaque), (back, no_opaque)
1161     // First we calculate test results for each square
1162     std::vector<uint32_t> hitResult = getHitResult(testParams);
1163 
1164     std::vector<std::vector<tcu::UVec2>> squares = {
1165         {{1, 1}, {4, 4}},
1166         {{4, 1}, {7, 4}},
1167         {{1, 4}, {4, 7}},
1168         {{4, 4}, {7, 7}},
1169     };
1170 
1171     tcu::UVec4 missValue(0, 0, 0, 0);
1172     tcu::clear(referenceAccess, missValue);
1173 
1174     for (uint32_t squareNdx = 0; squareNdx < squares.size(); ++squareNdx)
1175     {
1176         tcu::UVec4 hitValue(hitResult[squareNdx], 0, 0, 0);
1177         for (uint32_t y = squares[squareNdx][0].y(); y < squares[squareNdx][1].y(); ++y)
1178             for (uint32_t x = squares[squareNdx][0].x(); x < squares[squareNdx][1].x(); ++x)
1179             {
1180                 referenceAccess.setPixel(hitValue, x, y, 0);
1181                 referenceAccess.setPixel(hitValue, x, y, 1);
1182             }
1183     }
1184 
1185     // compare result and reference
1186     return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess,
1187                                     resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
1188 }
1189 
getResultImageFormat()1190 VkFormat RayTracingConfiguration::getResultImageFormat()
1191 {
1192     return VK_FORMAT_R32_UINT;
1193 }
1194 
getResultImageFormatSize()1195 size_t RayTracingConfiguration::getResultImageFormatSize()
1196 {
1197     return sizeof(uint32_t);
1198 }
1199 
getClearValue()1200 VkClearValue RayTracingConfiguration::getClearValue()
1201 {
1202     return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
1203 }
1204 
1205 class RayQueryCullRayFlagsTestCase : public TestCase
1206 {
1207 public:
1208     RayQueryCullRayFlagsTestCase(tcu::TestContext &context, const char *name, const TestParams data);
1209     ~RayQueryCullRayFlagsTestCase(void);
1210 
1211     virtual void checkSupport(Context &context) const;
1212     virtual void initPrograms(SourceCollections &programCollection) const;
1213     virtual TestInstance *createInstance(Context &context) const;
1214 
1215 private:
1216     TestParams m_data;
1217 };
1218 
1219 class TraversalControlTestInstance : public TestInstance
1220 {
1221 public:
1222     TraversalControlTestInstance(Context &context, const TestParams &data);
1223     ~TraversalControlTestInstance(void);
1224     tcu::TestStatus iterate(void);
1225 
1226 private:
1227     TestParams m_data;
1228 };
1229 
RayQueryCullRayFlagsTestCase(tcu::TestContext & context,const char * name,const TestParams data)1230 RayQueryCullRayFlagsTestCase::RayQueryCullRayFlagsTestCase(tcu::TestContext &context, const char *name,
1231                                                            const TestParams data)
1232     : vkt::TestCase(context, name)
1233     , m_data(data)
1234 {
1235 }
1236 
~RayQueryCullRayFlagsTestCase(void)1237 RayQueryCullRayFlagsTestCase::~RayQueryCullRayFlagsTestCase(void)
1238 {
1239 }
1240 
checkSupport(Context & context) const1241 void RayQueryCullRayFlagsTestCase::checkSupport(Context &context) const
1242 {
1243     context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
1244     context.requireDeviceFunctionality("VK_KHR_ray_query");
1245 
1246     const VkPhysicalDeviceRayQueryFeaturesKHR &rayQueryFeaturesKHR = context.getRayQueryFeatures();
1247     if (rayQueryFeaturesKHR.rayQuery == false)
1248         TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");
1249 
1250     const VkPhysicalDeviceAccelerationStructureFeaturesKHR &accelerationStructureFeaturesKHR =
1251         context.getAccelerationStructureFeatures();
1252     if (accelerationStructureFeaturesKHR.accelerationStructure == false)
1253         TCU_THROW(TestError,
1254                   "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
1255 
1256     const VkPhysicalDeviceFeatures2 &features2 = context.getDeviceFeatures2();
1257 
1258     if ((m_data.shaderSourceType == SST_TESSELATION_CONTROL_SHADER ||
1259          m_data.shaderSourceType == SST_TESSELATION_EVALUATION_SHADER) &&
1260         features2.features.tessellationShader == false)
1261         TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.tessellationShader");
1262 
1263     if (m_data.shaderSourceType == SST_GEOMETRY_SHADER && features2.features.geometryShader == false)
1264         TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.geometryShader");
1265 
1266     switch (m_data.shaderSourceType)
1267     {
1268     case SST_VERTEX_SHADER:
1269     case SST_TESSELATION_CONTROL_SHADER:
1270     case SST_TESSELATION_EVALUATION_SHADER:
1271     case SST_GEOMETRY_SHADER:
1272         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
1273         break;
1274     default:
1275         break;
1276     }
1277 
1278     if (m_data.shaderSourceType == SST_RAY_GENERATION_SHADER || m_data.shaderSourceType == SST_INTERSECTION_SHADER ||
1279         m_data.shaderSourceType == SST_ANY_HIT_SHADER || m_data.shaderSourceType == SST_CLOSEST_HIT_SHADER ||
1280         m_data.shaderSourceType == SST_MISS_SHADER || m_data.shaderSourceType == SST_CALLABLE_SHADER)
1281     {
1282         context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1283 
1284         const VkPhysicalDeviceRayTracingPipelineFeaturesKHR &rayTracingPipelineFeaturesKHR =
1285             context.getRayTracingPipelineFeatures();
1286 
1287         if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == false)
1288             TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1289     }
1290 }
1291 
initPrograms(SourceCollections & programCollection) const1292 void RayQueryCullRayFlagsTestCase::initPrograms(SourceCollections &programCollection) const
1293 {
1294     const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1295 
1296     // create parts of programs responsible for test execution
1297     std::vector<std::string> rayQueryTest;
1298     std::vector<std::string> rayQueryTestName;
1299     rayQueryTestName.push_back("rayflags_triangle");
1300     rayQueryTestName.push_back("rayflags_aabb");
1301 
1302     {
1303         // All of the tests use the same shader for triangles
1304         std::stringstream css;
1305         css << "  float tmin     = 0.0;\n"
1306                "  float tmax     = 1.0;\n"
1307                "  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1308                "  rayQueryEXT rq;\n"
1309                "  rayQueryInitializeEXT(rq, rqTopLevelAS, rqFlags, 0xFF, origin, tmin, direct, tmax);\n"
1310                "  if(rayQueryProceedEXT(rq))\n"
1311                "  {\n"
1312                "    if (rayQueryGetRayFlagsEXT(rq) == rqFlags)\n"
1313                "    {\n"
1314                "      if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT)"
1315                "      {\n"
1316                "        hitValue.x = 1;\n"
1317                "        hitValue.y = 1;\n"
1318                "      }\n"
1319                "    }\n"
1320                "  }\n"
1321                "  else\n"
1322                "  {\n"
1323                "    if (rayQueryGetRayFlagsEXT(rq) == rqFlags)\n"
1324                "    {\n"
1325                "      if (rayQueryGetIntersectionTypeEXT(rq, true)==gl_RayQueryCommittedIntersectionTriangleEXT)\n"
1326                "      {\n"
1327                "        hitValue.x = 2;\n"
1328                "        hitValue.y = 2;\n"
1329                "      }\n"
1330                "    }\n"
1331                "  }\n";
1332         rayQueryTest.push_back(css.str());
1333     }
1334 
1335     {
1336         // All of the tests use the same shader for aabbss
1337         std::stringstream css;
1338         css << "  float tmin     = 0.0;\n"
1339                "  float tmax     = 1.0;\n"
1340                "  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1341                "  rayQueryEXT rq;\n"
1342                "  rayQueryInitializeEXT(rq, rqTopLevelAS, rqFlags, 0xFF, origin, tmin, direct, tmax);\n"
1343                "  if(rayQueryProceedEXT(rq))\n"
1344                "  {\n"
1345                "    if (rayQueryGetRayFlagsEXT(rq) == rqFlags)\n"
1346                "    {\n"
1347                "      if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionAABBEXT)\n"
1348                "      {\n"
1349                "        if(rayQueryGetIntersectionCandidateAABBOpaqueEXT(rq))\n"
1350                "        {\n"
1351                "          hitValue.x = 2;\n"
1352                "          hitValue.y = 2;\n"
1353                "        }\n"
1354                "        else\n"
1355                "        {\n"
1356                "          hitValue.x = 1;\n"
1357                "          hitValue.y = 1;\n"
1358                "        }\n"
1359                "      }\n"
1360                "    }\n"
1361                "  }\n";
1362         rayQueryTest.push_back(css.str());
1363     }
1364 
1365     // create all programs
1366     if (m_data.shaderSourcePipeline == SSP_GRAPHICS_PIPELINE)
1367     {
1368         {
1369             std::stringstream css;
1370             css << "#version 460 core\n"
1371                    "layout (location = 0) in vec3 position;\n"
1372                    "out gl_PerVertex\n"
1373                    "{\n"
1374                    "  vec4 gl_Position;\n"
1375                    "};\n"
1376                    "void main()\n"
1377                    "{\n"
1378                    "  gl_Position = vec4(position, 1.0);\n"
1379                    "}\n";
1380             programCollection.glslSources.add("vert") << glu::VertexSource(css.str());
1381         }
1382 
1383         {
1384             std::stringstream css;
1385             css << "#version 460 core\n"
1386                    "layout (location = 0) in vec3 position;\n"
1387                    "out gl_PerVertex\n"
1388                    "{\n"
1389                    "  vec4 gl_Position;\n"
1390                    "};\n"
1391                    "layout(location = 0) out int vertexIndex;\n"
1392                    "void main()\n"
1393                    "{\n"
1394                    "  gl_Position = vec4(position, 1.0);\n"
1395                    "  vertexIndex = gl_VertexIndex;\n"
1396                    "}\n";
1397             programCollection.glslSources.add("vert_vid") << glu::VertexSource(css.str());
1398         }
1399 
1400         {
1401             std::stringstream css;
1402             css << "#version 460 core\n"
1403                    "#extension GL_EXT_ray_query : require\n"
1404                    "layout (location = 0) in vec3 position;\n"
1405                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1406                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1407                    "layout(set = 0, binding = 2) uniform params { uvec4 rayFlags; };\n"
1408                    "void main()\n"
1409                    "{\n"
1410                    "  vec3  origin   = vec3(float(position.x), float(position.y), 0.5f);\n"
1411                    "  uvec4 hitValue = uvec4(0,0,0,0);\n"
1412                    "  uint  rqFlags  = rayFlags.x;\n"
1413                 << rayQueryTest[m_data.bottomType]
1414                 << "  imageStore(result, ivec3(gl_VertexIndex, 0, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1415                    "  imageStore(result, ivec3(gl_VertexIndex, 0, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1416                    "  gl_Position = vec4(position,1);\n"
1417                    "}\n";
1418             std::stringstream cssName;
1419             cssName << "vert_" << rayQueryTestName[m_data.bottomType];
1420 
1421             programCollection.glslSources.add(cssName.str()) << glu::VertexSource(css.str()) << buildOptions;
1422         }
1423 
1424         {
1425             std::stringstream css;
1426             css << "#version 460 core\n"
1427                    "#extension GL_EXT_tessellation_shader : require\n"
1428                    "in gl_PerVertex {\n"
1429                    "  vec4  gl_Position;\n"
1430                    "} gl_in[];\n"
1431                    "layout(vertices = 3) out;\n"
1432                    "void main (void)\n"
1433                    "{\n"
1434                    "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1435                    "  gl_TessLevelInner[0] = 1;\n"
1436                    "  gl_TessLevelOuter[0] = 1;\n"
1437                    "  gl_TessLevelOuter[1] = 1;\n"
1438                    "  gl_TessLevelOuter[2] = 1;\n"
1439                    "}\n";
1440             programCollection.glslSources.add("tesc") << glu::TessellationControlSource(css.str());
1441         }
1442 
1443         {
1444             std::stringstream css;
1445             css << "#version 460 core\n"
1446                    "#extension GL_EXT_tessellation_shader : require\n"
1447                    "#extension GL_EXT_ray_query : require\n"
1448                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1449                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1450                    "layout(set = 0, binding = 2) uniform params { uvec4 rayFlags; };\n"
1451                    "in gl_PerVertex {\n"
1452                    "  vec4  gl_Position;\n"
1453                    "} gl_in[];\n"
1454                    "layout(vertices = 3) out;\n"
1455                    "void main (void)\n"
1456                    "{\n"
1457                    "  vec3  origin   = vec3(gl_in[gl_InvocationID].gl_Position.x, "
1458                    "gl_in[gl_InvocationID].gl_Position.y, 0.5f);\n"
1459                    "  uvec4 hitValue = uvec4(0,0,0,0);\n"
1460                    "  uint  rqFlags  = rayFlags.x;\n"
1461                 << rayQueryTest[m_data.bottomType]
1462                 << "  imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1463                    "  imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1464                    "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1465                    "  gl_TessLevelInner[0] = 1;\n"
1466                    "  gl_TessLevelOuter[0] = 1;\n"
1467                    "  gl_TessLevelOuter[1] = 1;\n"
1468                    "  gl_TessLevelOuter[2] = 1;\n"
1469                    "}\n";
1470             std::stringstream cssName;
1471             cssName << "tesc_" << rayQueryTestName[m_data.bottomType];
1472 
1473             programCollection.glslSources.add(cssName.str())
1474                 << glu::TessellationControlSource(css.str()) << buildOptions;
1475         }
1476 
1477         {
1478             std::stringstream css;
1479             css << "#version 460 core\n"
1480                    "#extension GL_EXT_tessellation_shader : require\n"
1481                    "#extension GL_EXT_ray_query : require\n"
1482                    "layout(triangles, equal_spacing, ccw) in;\n"
1483                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1484                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1485                    "layout(set = 0, binding = 2) uniform params { uvec4 rayFlags; };\n"
1486                    "void main (void)\n"
1487                    "{\n"
1488                    "  for (int i = 0; i < 3; ++i)\n"
1489                    "  {\n"
1490                    "    vec3  origin   = vec3(gl_in[i].gl_Position.x, gl_in[i].gl_Position.y, 0.5f);\n"
1491                    "    uvec4 hitValue = uvec4(0,0,0,0);\n"
1492                    "    uint  rqFlags  = rayFlags.x;\n"
1493                 << rayQueryTest[m_data.bottomType]
1494                 << "    imageStore(result, ivec3(gl_PrimitiveID, i, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1495                    "    imageStore(result, ivec3(gl_PrimitiveID, i, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1496                    "  }\n"
1497                    "  gl_Position = gl_in[0].gl_Position;\n"
1498                    "}\n";
1499             std::stringstream cssName;
1500             cssName << "tese_" << rayQueryTestName[m_data.bottomType];
1501 
1502             programCollection.glslSources.add(cssName.str())
1503                 << glu::TessellationEvaluationSource(css.str()) << buildOptions;
1504         }
1505 
1506         {
1507             std::stringstream css;
1508             css << "#version 460 core\n"
1509                    "#extension GL_EXT_tessellation_shader : require\n"
1510                    "layout(triangles, equal_spacing, ccw) in;\n"
1511                    "void main (void)\n"
1512                    "{\n"
1513                    "  gl_Position = gl_in[0].gl_Position;\n"
1514                    "}\n";
1515 
1516             programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(css.str());
1517         }
1518 
1519         {
1520             std::stringstream css;
1521             css << "#version 460 core\n"
1522                    "#extension GL_EXT_ray_query : require\n"
1523                    "layout(triangles) in;\n"
1524                    "layout (triangle_strip, max_vertices = 4) out;\n"
1525                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1526                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1527                    "layout(set = 0, binding = 2) uniform params { uvec4 rayFlags; };\n"
1528                    "\n"
1529                    "in gl_PerVertex {\n"
1530                    "  vec4  gl_Position;\n"
1531                    "} gl_in[];\n"
1532                    "layout(location = 0) in int vertexIndex[];\n"
1533                    "out gl_PerVertex {\n"
1534                    "  vec4 gl_Position;\n"
1535                    "};\n"
1536                    "void main (void)\n"
1537                    "{\n"
1538                    "  // geometry shader may reorder the vertices, keeping only the winding of the triangles.\n"
1539                    "  // To iterate from the 'first vertex' of the triangle we need to find it first by looking for\n"
1540                    "  // smallest vertex index value.\n"
1541                    "  int minVertexIndex = 10000;"
1542                    "  int firstVertex;"
1543                    "  for (int i = 0; i < gl_in.length(); ++i)\n"
1544                    "  {\n"
1545                    "    if (minVertexIndex > vertexIndex[i])\n"
1546                    "    {\n"
1547                    "      minVertexIndex = vertexIndex[i];\n"
1548                    "      firstVertex    = i;\n"
1549                    "    }\n"
1550                    "  }\n"
1551                    "  for (int j = 0; j < gl_in.length(); ++j)\n"
1552                    "  {\n"
1553                    "    // iterate starting at firstVertex, possibly wrapping around, so the triangle is\n"
1554                    "    // always iterated starting from the smallest vertex index, as found above.\n"
1555                    "    int i = (firstVertex + j) % gl_in.length();\n"
1556                    "    vec3  origin   = vec3(gl_in[i].gl_Position.x, gl_in[i].gl_Position.y, 0.5f);\n"
1557                    "    uvec4 hitValue = uvec4(0,0,0,0);\n"
1558                    "    uint  rqFlags  = rayFlags.x;\n"
1559                 << rayQueryTest[m_data.bottomType]
1560                 << "    imageStore(result, ivec3(gl_PrimitiveIDIn, j, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1561                    "    imageStore(result, ivec3(gl_PrimitiveIDIn, j, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1562                    "    gl_Position      = gl_in[i].gl_Position;\n"
1563                    "    EmitVertex();\n"
1564                    "  }\n"
1565                    "  EndPrimitive();\n"
1566                    "}\n";
1567             std::stringstream cssName;
1568             cssName << "geom_" << rayQueryTestName[m_data.bottomType];
1569 
1570             programCollection.glslSources.add(cssName.str()) << glu::GeometrySource(css.str()) << buildOptions;
1571         }
1572 
1573         {
1574             std::stringstream css;
1575             css << "#version 460 core\n"
1576                    "#extension GL_EXT_ray_query : require\n"
1577                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1578                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1579                    "layout(set = 0, binding = 2) uniform params { uvec4 rayFlags; };\n"
1580                    "void main()\n"
1581                    "{\n"
1582                    "  vec3  origin   = vec3(gl_FragCoord.x, gl_FragCoord.y, 0.5f);\n"
1583                    "  uvec4 hitValue = uvec4(0,0,0,0);\n"
1584                    "  uint  rqFlags  = rayFlags.x;\n"
1585                 << rayQueryTest[m_data.bottomType]
1586                 << "  imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 0), uvec4(hitValue.x, 0, 0, 0));\n"
1587                    "  imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 1), uvec4(hitValue.y, 0, 0, 0));\n"
1588                    "}\n";
1589             std::stringstream cssName;
1590             cssName << "frag_" << rayQueryTestName[m_data.bottomType];
1591 
1592             programCollection.glslSources.add(cssName.str()) << glu::FragmentSource(css.str()) << buildOptions;
1593         }
1594     }
1595     else if (m_data.shaderSourcePipeline == SSP_COMPUTE_PIPELINE)
1596     {
1597         {
1598             std::stringstream css;
1599             css << "#version 460 core\n"
1600                    "#extension GL_EXT_ray_query : require\n"
1601                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1602                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1603                    "layout(set = 0, binding = 2) uniform params { uvec4 rayFlags; };\n"
1604                    "void main()\n"
1605                    "{\n"
1606                    "  vec3  origin   = vec3(float(gl_GlobalInvocationID.x) + 0.5f, float(gl_GlobalInvocationID.y) + "
1607                    "0.5f, 0.5f);\n"
1608                    "  uvec4 hitValue = uvec4(0,0,0,0);\n"
1609                    "  uint  rqFlags  = rayFlags.x;\n"
1610                 << rayQueryTest[m_data.bottomType]
1611                 << "  imageStore(result, ivec3(gl_GlobalInvocationID.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1612                    "  imageStore(result, ivec3(gl_GlobalInvocationID.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1613                    "}\n";
1614             std::stringstream cssName;
1615             cssName << "comp_" << rayQueryTestName[m_data.bottomType];
1616 
1617             programCollection.glslSources.add(cssName.str()) << glu::ComputeSource(css.str()) << buildOptions;
1618         }
1619     }
1620     else if (m_data.shaderSourcePipeline == SSP_RAY_TRACING_PIPELINE)
1621     {
1622 
1623         {
1624             std::stringstream css;
1625             css << "#version 460 core\n"
1626                    "#extension GL_EXT_ray_tracing : require\n"
1627                    "layout(location = 0) rayPayloadEXT uvec4 hitValue;\n"
1628                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1629                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1630                    "void main()\n"
1631                    "{\n"
1632                    "  float tmin     = 0.0;\n"
1633                    "  float tmax     = 1.0;\n"
1634                    "  vec3  origin   = vec3(float(gl_LaunchIDEXT.x) + 0.5f, float(gl_LaunchIDEXT.y) + 0.5f, 0.5f);\n"
1635                    "  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1636                    "  hitValue       = uvec4(0,0,0,0);\n"
1637                    "  traceRayEXT(topLevelAS, 0, 0xFF, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
1638                    "  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1639                    "  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1640                    "}\n";
1641             programCollection.glslSources.add("rgen")
1642                 << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1643         }
1644 
1645         {
1646             std::stringstream css;
1647             css << "#version 460 core\n"
1648                    "#extension GL_EXT_ray_tracing : require\n"
1649                    "#extension GL_EXT_ray_query : require\n"
1650                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1651                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1652                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1653                    "layout(set = 0, binding = 3) uniform params { uvec4 rayFlags; };\n"
1654                    "void main()\n"
1655                    "{\n"
1656                    "  vec3  origin   = vec3(float(gl_LaunchIDEXT.x) + 0.5f, float(gl_LaunchIDEXT.y) + 0.5f, 0.5f);\n"
1657                    "  uvec4 hitValue = uvec4(0,0,0,0);\n"
1658                    "  uint  rqFlags  = rayFlags.x;\n"
1659                 << rayQueryTest[m_data.bottomType]
1660                 << "  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1661                    "  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1662                    "}\n";
1663             std::stringstream cssName;
1664             cssName << "rgen_" << rayQueryTestName[m_data.bottomType];
1665 
1666             programCollection.glslSources.add(cssName.str())
1667                 << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1668         }
1669 
1670         {
1671             std::stringstream css;
1672             css << "#version 460 core\n"
1673                    "#extension GL_EXT_ray_tracing : require\n"
1674                    "struct CallValue\n{\n"
1675                    "  vec3  origin;\n"
1676                    "  uvec4 hitValue;\n"
1677                    "  uint  rqFlags;\n"
1678                    "};\n"
1679                    "layout(location = 0) callableDataEXT CallValue param;\n"
1680                    "layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1681                    "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1682                    "layout(set = 0, binding = 3) uniform params { uvec4 rayFlags; };\n"
1683                    "void main()\n"
1684                    "{\n"
1685                    "  param.origin   = vec3(float(gl_LaunchIDEXT.x) + 0.5f, float(gl_LaunchIDEXT.y) + 0.5f, 0.5f);\n"
1686                    "  param.hitValue = uvec4(0, 0, 0, 0);\n"
1687                    "  param.rqFlags  = rayFlags.x;\n"
1688                    "  executeCallableEXT(0, 0);\n"
1689                    "  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(param.hitValue.x, 0, 0, 0));\n"
1690                    "  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(param.hitValue.y, 0, 0, 0));\n"
1691                    "}\n";
1692             programCollection.glslSources.add("rgen_call")
1693                 << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1694         }
1695 
1696         {
1697             std::stringstream css;
1698             css << "#version 460 core\n"
1699                    "#extension GL_EXT_ray_tracing : require\n"
1700                    "hitAttributeEXT uvec4 hitValue;\n"
1701                    "void main()\n"
1702                    "{\n"
1703                    "  reportIntersectionEXT(0.5f, 0);\n"
1704                    "}\n";
1705 
1706             programCollection.glslSources.add("isect")
1707                 << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1708         }
1709 
1710         {
1711             std::stringstream css;
1712             css << "#version 460 core\n"
1713                    "#extension GL_EXT_ray_tracing : require\n"
1714                    "#extension GL_EXT_ray_query : require\n"
1715                    "hitAttributeEXT uvec4 hitValue;\n"
1716                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1717                    "layout(set = 0, binding = 3) uniform params { uvec4 rayFlags; };\n"
1718                    "void main()\n"
1719                    "{\n"
1720                    "  vec3 origin   = gl_WorldRayOriginEXT;\n"
1721                    "  hitValue      = uvec4(0,0,0,0);\n"
1722                    "  uint rqFlags  = rayFlags.x;\n"
1723                 << rayQueryTest[m_data.bottomType]
1724                 << "  reportIntersectionEXT(0.5f, 0);\n"
1725                    "}\n";
1726             std::stringstream cssName;
1727             cssName << "isect_" << rayQueryTestName[m_data.bottomType];
1728 
1729             programCollection.glslSources.add(cssName.str())
1730                 << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1731         }
1732 
1733         {
1734             std::stringstream css;
1735             css << "#version 460 core\n"
1736                    "#extension GL_EXT_ray_tracing : require\n"
1737                    "#extension GL_EXT_ray_query : require\n"
1738                    "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1739                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1740                    "layout(set = 0, binding = 3) uniform params { uvec4 rayFlags; };\n"
1741                    "void main()\n"
1742                    "{\n"
1743                    "  vec3 origin  = gl_WorldRayOriginEXT;\n"
1744                    "  uint rqFlags = rayFlags.x;\n"
1745                 << rayQueryTest[m_data.bottomType] << "}\n";
1746             std::stringstream cssName;
1747             cssName << "ahit_" << rayQueryTestName[m_data.bottomType];
1748 
1749             programCollection.glslSources.add(cssName.str())
1750                 << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1751         }
1752 
1753         {
1754             std::stringstream css;
1755             css << "#version 460 core\n"
1756                    "#extension GL_EXT_ray_tracing : require\n"
1757                    "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1758                    "void main()\n"
1759                    "{\n"
1760                    "  hitValue.y = 3;\n"
1761                    "}\n";
1762 
1763             programCollection.glslSources.add("chit")
1764                 << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1765         }
1766 
1767         {
1768             std::stringstream css;
1769             css << "#version 460 core\n"
1770                    "#extension GL_EXT_ray_tracing : require\n"
1771                    "#extension GL_EXT_ray_query : require\n"
1772                    "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1773                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1774                    "layout(set = 0, binding = 3) uniform params { uvec4 rayFlags; };\n"
1775                    "void main()\n"
1776                    "{\n"
1777                    "  vec3 origin  = gl_WorldRayOriginEXT;\n"
1778                    "  uint rqFlags = rayFlags.x;\n"
1779                 << rayQueryTest[m_data.bottomType] << "}\n";
1780             std::stringstream cssName;
1781             cssName << "chit_" << rayQueryTestName[m_data.bottomType];
1782 
1783             programCollection.glslSources.add(cssName.str())
1784                 << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1785         }
1786 
1787         {
1788             std::stringstream css;
1789             css << "#version 460 core\n"
1790                    "#extension GL_EXT_ray_tracing : require\n"
1791                    "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1792                    "hitAttributeEXT uvec4 hitAttrib;\n"
1793                    "void main()\n"
1794                    "{\n"
1795                    "  hitValue = hitAttrib;\n"
1796                    "}\n";
1797 
1798             programCollection.glslSources.add("chit_isect")
1799                 << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1800         }
1801 
1802         {
1803             std::stringstream css;
1804             css << "#version 460 core\n"
1805                    "#extension GL_EXT_ray_tracing : require\n"
1806                    "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1807                    "void main()\n"
1808                    "{\n"
1809                    "  hitValue.x = 4;\n"
1810                    "}\n";
1811 
1812             programCollection.glslSources.add("miss")
1813                 << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1814         }
1815 
1816         {
1817             std::stringstream css;
1818             css << "#version 460 core\n"
1819                    "#extension GL_EXT_ray_tracing : require\n"
1820                    "#extension GL_EXT_ray_query : require\n"
1821                    "layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1822                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1823                    "layout(set = 0, binding = 3) uniform params { uvec4 rayFlags; };\n"
1824                    "void main()\n"
1825                    "{\n"
1826                    "  vec3 origin  = gl_WorldRayOriginEXT;\n"
1827                    "  uint rqFlags = rayFlags.x;\n"
1828                 << rayQueryTest[m_data.bottomType] << "}\n";
1829             std::stringstream cssName;
1830             cssName << "miss_" << rayQueryTestName[m_data.bottomType];
1831 
1832             programCollection.glslSources.add(cssName.str())
1833                 << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1834         }
1835 
1836         {
1837             std::stringstream css;
1838             css << "#version 460 core\n"
1839                    "#extension GL_EXT_ray_tracing : require\n"
1840                    "#extension GL_EXT_ray_query : require\n"
1841                    "struct CallValue\n{\n"
1842                    "  vec3  origin;\n"
1843                    "  uvec4 hitValue;\n"
1844                    "  uint  rqFlags;\n"
1845                    "};\n"
1846                    "layout(location = 0) callableDataInEXT CallValue result;\n"
1847                    "layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1848                    "void main()\n"
1849                    "{\n"
1850                    "  vec3  origin   = result.origin;\n"
1851                    "  uvec4 hitValue = uvec4(0,0,0,0);\n"
1852                    "  uint  rqFlags  = result.rqFlags;\n"
1853                 << rayQueryTest[m_data.bottomType]
1854                 << "  result.hitValue = hitValue;\n"
1855                    "}\n";
1856             std::stringstream cssName;
1857             cssName << "call_" << rayQueryTestName[m_data.bottomType];
1858 
1859             programCollection.glslSources.add(cssName.str())
1860                 << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
1861         }
1862     }
1863 }
1864 
createInstance(Context & context) const1865 TestInstance *RayQueryCullRayFlagsTestCase::createInstance(Context &context) const
1866 {
1867     return new TraversalControlTestInstance(context, m_data);
1868 }
1869 
TraversalControlTestInstance(Context & context,const TestParams & data)1870 TraversalControlTestInstance::TraversalControlTestInstance(Context &context, const TestParams &data)
1871     : vkt::TestInstance(context)
1872     , m_data(data)
1873 {
1874 }
1875 
~TraversalControlTestInstance(void)1876 TraversalControlTestInstance::~TraversalControlTestInstance(void)
1877 {
1878 }
1879 
iterate(void)1880 tcu::TestStatus TraversalControlTestInstance::iterate(void)
1881 {
1882     de::SharedPtr<TestConfiguration> testConfiguration;
1883 
1884     switch (m_data.shaderSourcePipeline)
1885     {
1886     case SSP_GRAPHICS_PIPELINE:
1887         testConfiguration = de::SharedPtr<TestConfiguration>(new GraphicsConfiguration());
1888         break;
1889     case SSP_COMPUTE_PIPELINE:
1890         testConfiguration = de::SharedPtr<TestConfiguration>(new ComputeConfiguration());
1891         break;
1892     case SSP_RAY_TRACING_PIPELINE:
1893         testConfiguration = de::SharedPtr<TestConfiguration>(new RayTracingConfiguration());
1894         break;
1895     default:
1896         TCU_THROW(InternalError, "Wrong shader source pipeline");
1897     }
1898 
1899     testConfiguration->initConfiguration(m_context, m_data);
1900 
1901     const DeviceInterface &vkd      = m_context.getDeviceInterface();
1902     const VkDevice device           = m_context.getDevice();
1903     const VkQueue queue             = m_context.getUniversalQueue();
1904     Allocator &allocator            = m_context.getDefaultAllocator();
1905     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1906 
1907     const VkFormat imageFormat              = testConfiguration->getResultImageFormat();
1908     const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_data.width, m_data.height, 2, imageFormat);
1909     const VkImageSubresourceRange imageSubresourceRange =
1910         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1911     const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(
1912         new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1913     const Move<VkImageView> imageView =
1914         makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, imageFormat, imageSubresourceRange);
1915 
1916     const VkBufferCreateInfo paramBufferCreateInfo =
1917         makeBufferCreateInfo(sizeof(tcu::UVec4), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
1918     de::MovePtr<BufferWithMemory> paramBuffer = de::MovePtr<BufferWithMemory>(
1919         new BufferWithMemory(vkd, device, allocator, paramBufferCreateInfo, MemoryRequirement::HostVisible));
1920     tcu::UVec4 paramData(m_data.flag0 | m_data.flag1, 0, 0, 0);
1921     deMemcpy(paramBuffer->getAllocation().getHostPtr(), &paramData, sizeof(tcu::UVec4));
1922     flushAlloc(vkd, device, paramBuffer->getAllocation());
1923 
1924     const VkDescriptorBufferInfo paramBufferDescriptorInfo =
1925         makeDescriptorBufferInfo(paramBuffer->get(), paramBuffer->getAllocation().getOffset(), sizeof(tcu::UVec4));
1926 
1927     const VkBufferCreateInfo resultBufferCreateInfo =
1928         makeBufferCreateInfo(m_data.width * m_data.height * 2 * testConfiguration->getResultImageFormatSize(),
1929                              VK_BUFFER_USAGE_TRANSFER_DST_BIT);
1930     const VkImageSubresourceLayers resultBufferImageSubresourceLayers =
1931         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1932     const VkBufferImageCopy resultBufferImageRegion =
1933         makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, 2), resultBufferImageSubresourceLayers);
1934     de::MovePtr<BufferWithMemory> resultBuffer = de::MovePtr<BufferWithMemory>(
1935         new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
1936 
1937     const VkDescriptorImageInfo resultImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
1938 
1939     const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
1940     const Move<VkCommandBuffer> cmdBuffer =
1941         allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1942 
1943     std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> rayQueryBottomLevelAccelerationStructures;
1944     de::MovePtr<TopLevelAccelerationStructure> rayQueryTopLevelAccelerationStructure;
1945 
1946     beginCommandBuffer(vkd, *cmdBuffer, 0u);
1947     {
1948         const VkImageMemoryBarrier preImageBarrier =
1949             makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
1950                                    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, **image, imageSubresourceRange);
1951         cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1952                                       VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
1953 
1954         const VkClearValue clearValue = testConfiguration->getClearValue();
1955         vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1,
1956                                &imageSubresourceRange);
1957 
1958         const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(
1959             VK_ACCESS_TRANSFER_WRITE_BIT,
1960             VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
1961             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, **image, imageSubresourceRange);
1962         cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT,
1963                                       VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
1964 
1965         rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1966         // In case of triangle AS consists of 4 squares:
1967         // - left squares are marked as opaque, right squares - as nonopaque
1968         // - higher squares are front facing, lower - back facing
1969         // In case of AABBs - it's just 2 rectangles ( no face culling idea in AABBs )
1970         // - left rectangle is marked as opaque, right rectangle - as nonopaque
1971         {
1972             tcu::Vec3 v[3][3];
1973             for (uint32_t y = 0; y < 3; ++y)
1974                 for (uint32_t x = 0; x < 3; ++x)
1975                     v[x][y] = tcu::Vec3(1.0f + 0.5f * (float(m_data.width) - 2.0f) * float(x),
1976                                         1.0f + 0.5f * (float(m_data.height) - 2.0f) * float(y), 0.0f);
1977             VkTransformMatrixKHR identityMatrix = {
1978                 {{1.0f, 0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 0.0f}}};
1979 
1980             if (m_data.bottomType == BTT_TRIANGLES)
1981             {
1982                 // offsets taking front facing into account
1983                 std::vector<std::vector<tcu::UVec2>> faceCullingOffsets = {
1984                     {{0, 0}, {1, 0}, {0, 1}, {0, 1}, {1, 0}, {1, 1}},
1985                     {{0, 0}, {0, 1}, {1, 0}, {1, 0}, {0, 1}, {1, 1}},
1986                 };
1987 
1988                 rayQueryTopLevelAccelerationStructure->setInstanceCount(4);
1989 
1990                 for (uint32_t y = 0; y < 2; ++y)
1991                     for (uint32_t x = 0; x < 2; ++x)
1992                     {
1993                         de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure =
1994                             makeBottomLevelAccelerationStructure();
1995                         bottomLevelAccelerationStructure->setGeometryCount(1);
1996                         de::SharedPtr<RaytracedGeometryBase> geometry = makeRaytracedGeometry(
1997                             VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1998 
1999                         uint32_t faceCullingNdx                  = y % 2;
2000                         VkGeometryInstanceFlagsKHR instanceFlags = (x % 2) ?
2001                                                                        VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR :
2002                                                                        VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR;
2003 
2004                         for (size_t vNdx = 0; vNdx < faceCullingOffsets[faceCullingNdx].size(); vNdx++)
2005                         {
2006                             tcu::UVec2 &off = faceCullingOffsets[faceCullingNdx][vNdx];
2007                             geometry->addVertex(v[x + off.x()][y + off.y()]);
2008                         }
2009                         bottomLevelAccelerationStructure->addGeometry(geometry);
2010 
2011                         rayQueryBottomLevelAccelerationStructures.push_back(
2012                             de::SharedPtr<BottomLevelAccelerationStructure>(
2013                                 bottomLevelAccelerationStructure.release()));
2014                         rayQueryBottomLevelAccelerationStructures.back()->createAndBuild(vkd, device, *cmdBuffer,
2015                                                                                          allocator);
2016 
2017                         rayQueryTopLevelAccelerationStructure->addInstance(
2018                             rayQueryBottomLevelAccelerationStructures.back(), identityMatrix, 0u, 0xFF, 0u,
2019                             instanceFlags);
2020                     }
2021             }
2022             else // testParams.bottomType != BTT_TRIANGLES
2023             {
2024                 std::vector<std::vector<tcu::Vec3>> aabbCoords = {
2025                     {v[0][0] + tcu::Vec3(0.0f, 0.0f, -0.1f), v[1][2] + tcu::Vec3(0.0f, 0.0f, 0.1f)},
2026                     {v[1][0] + tcu::Vec3(0.0f, 0.0f, -0.1f), v[2][2] + tcu::Vec3(0.0f, 0.0f, 0.1f)},
2027                 };
2028 
2029                 rayQueryTopLevelAccelerationStructure->setInstanceCount(aabbCoords.size());
2030 
2031                 for (size_t aNdx = 0; aNdx < aabbCoords.size(); aNdx++)
2032                 {
2033                     de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure =
2034                         makeBottomLevelAccelerationStructure();
2035                     bottomLevelAccelerationStructure->setGeometryCount(1);
2036                     de::SharedPtr<RaytracedGeometryBase> geometry = makeRaytracedGeometry(
2037                         VK_GEOMETRY_TYPE_AABBS_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
2038 
2039                     VkGeometryInstanceFlagsKHR instanceFlags = (aNdx % 2) ?
2040                                                                    VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR :
2041                                                                    VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR;
2042 
2043                     geometry->addVertex(aabbCoords[aNdx][0]);
2044                     geometry->addVertex(aabbCoords[aNdx][1]);
2045 
2046                     bottomLevelAccelerationStructure->addGeometry(geometry);
2047 
2048                     rayQueryBottomLevelAccelerationStructures.push_back(
2049                         de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
2050                     rayQueryBottomLevelAccelerationStructures.back()->createAndBuild(vkd, device, *cmdBuffer,
2051                                                                                      allocator);
2052 
2053                     rayQueryTopLevelAccelerationStructure->addInstance(rayQueryBottomLevelAccelerationStructures.back(),
2054                                                                        identityMatrix, 0u, 0xFF, 0u, instanceFlags);
2055                 }
2056             }
2057         }
2058 
2059         rayQueryTopLevelAccelerationStructure->createAndBuild(vkd, device, *cmdBuffer, allocator);
2060 
2061         const TopLevelAccelerationStructure *rayQueryTopLevelAccelerationStructurePtr =
2062             rayQueryTopLevelAccelerationStructure.get();
2063         VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet = {
2064             VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, //  VkStructureType sType;
2065             DE_NULL,                                                           //  const void* pNext;
2066             1u,                                                                //  uint32_t accelerationStructureCount;
2067             rayQueryTopLevelAccelerationStructurePtr
2068                 ->getPtr(), //  const VkAccelerationStructureKHR* pAccelerationStructures;
2069         };
2070 
2071         testConfiguration->fillCommandBuffer(m_context, m_data, *cmdBuffer, accelerationStructureWriteDescriptorSet,
2072                                              paramBufferDescriptorInfo, resultImageInfo);
2073 
2074         const VkMemoryBarrier postTestMemoryBarrier = makeMemoryBarrier(
2075             VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
2076             VK_ACCESS_TRANSFER_READ_BIT);
2077         const VkMemoryBarrier postCopyMemoryBarrier =
2078             makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
2079         cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
2080                                  &postTestMemoryBarrier);
2081 
2082         vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u,
2083                                  &resultBufferImageRegion);
2084 
2085         cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
2086                                  &postCopyMemoryBarrier);
2087     }
2088     endCommandBuffer(vkd, *cmdBuffer);
2089 
2090     submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2091 
2092     invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(),
2093                                 resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
2094 
2095     bool result = testConfiguration->verifyImage(resultBuffer.get(), m_context, m_data);
2096 
2097     if (!result)
2098         return tcu::TestStatus::fail("Fail");
2099     return tcu::TestStatus::pass("Pass");
2100 }
2101 
2102 } // namespace
2103 
createCullRayFlagsTests(tcu::TestContext & testCtx)2104 tcu::TestCaseGroup *createCullRayFlagsTests(tcu::TestContext &testCtx)
2105 {
2106     // Tests verifying ray flags in ray query extension
2107     de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "ray_flags"));
2108 
2109     struct ShaderSourceTypeData
2110     {
2111         ShaderSourceType shaderSourceType;
2112         ShaderSourcePipeline shaderSourcePipeline;
2113         const char *name;
2114     } shaderSourceTypes[] = {
2115         {SST_VERTEX_SHADER, SSP_GRAPHICS_PIPELINE, "vertex_shader"},
2116         {SST_TESSELATION_CONTROL_SHADER, SSP_GRAPHICS_PIPELINE, "tess_control_shader"},
2117         {SST_TESSELATION_EVALUATION_SHADER, SSP_GRAPHICS_PIPELINE, "tess_evaluation_shader"},
2118         {
2119             SST_GEOMETRY_SHADER,
2120             SSP_GRAPHICS_PIPELINE,
2121             "geometry_shader",
2122         },
2123         {
2124             SST_FRAGMENT_SHADER,
2125             SSP_GRAPHICS_PIPELINE,
2126             "fragment_shader",
2127         },
2128         {
2129             SST_COMPUTE_SHADER,
2130             SSP_COMPUTE_PIPELINE,
2131             "compute_shader",
2132         },
2133         {
2134             SST_RAY_GENERATION_SHADER,
2135             SSP_RAY_TRACING_PIPELINE,
2136             "rgen_shader",
2137         },
2138         {
2139             SST_INTERSECTION_SHADER,
2140             SSP_RAY_TRACING_PIPELINE,
2141             "isect_shader",
2142         },
2143         {
2144             SST_ANY_HIT_SHADER,
2145             SSP_RAY_TRACING_PIPELINE,
2146             "ahit_shader",
2147         },
2148         {
2149             SST_CLOSEST_HIT_SHADER,
2150             SSP_RAY_TRACING_PIPELINE,
2151             "chit_shader",
2152         },
2153         {
2154             SST_MISS_SHADER,
2155             SSP_RAY_TRACING_PIPELINE,
2156             "miss_shader",
2157         },
2158         {
2159             SST_CALLABLE_SHADER,
2160             SSP_RAY_TRACING_PIPELINE,
2161             "call_shader",
2162         },
2163     };
2164 
2165     struct ShaderTestTypeData
2166     {
2167         ShaderTestType shaderTestType;
2168         const char *name;
2169         std::vector<std::vector<RayFlags>> flag; // bottom test type, flag0, flag1
2170     } shaderTestTypes[] = {
2171         {STT_OPACITY,
2172          "opacity",
2173          {
2174              {RF_None, RF_Opaque, RF_NoOpaque, RF_CullOpaque, RF_CullNoOpaque},
2175              {RF_None, RF_Opaque, RF_NoOpaque, RF_CullOpaque, RF_CullNoOpaque},
2176          }},
2177         {STT_TERMINATE_ON_FIRST_HIT,
2178          "terminate_on_first_hit",
2179          {
2180              {RF_TerminateOnFirstHit},
2181              {RF_TerminateOnFirstHit},
2182          }},
2183         {STT_FACE_CULLING,
2184          "face_culling",
2185          {
2186              {RF_CullBackFacingTriangles, RF_CullFrontFacingTriangles},
2187              {},
2188          }},
2189         {STT_SKIP_GEOMETRY,
2190          "skip_geometry",
2191          {
2192              {RF_SkipTriangles, RF_SkipAABB},
2193              {RF_SkipTriangles, RF_SkipAABB},
2194          }},
2195     };
2196 
2197     struct
2198     {
2199         BottomTestType testType;
2200         const char *name;
2201     } bottomTestTypes[] = {
2202         {BTT_TRIANGLES, "triangles"},
2203         {BTT_AABBS, "aabbs"},
2204     };
2205 
2206     for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
2207     {
2208         de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(
2209             new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name));
2210 
2211         for (size_t shaderTestNdx = 0; shaderTestNdx < DE_LENGTH_OF_ARRAY(shaderTestTypes); ++shaderTestNdx)
2212         {
2213             de::MovePtr<tcu::TestCaseGroup> testTypeGroup(
2214                 new tcu::TestCaseGroup(group->getTestContext(), shaderTestTypes[shaderTestNdx].name));
2215 
2216             for (size_t testTypeNdx = 0; testTypeNdx < shaderTestTypes[shaderTestNdx].flag.size(); ++testTypeNdx)
2217             {
2218                 de::MovePtr<tcu::TestCaseGroup> bottomTestTypeGroup(
2219                     new tcu::TestCaseGroup(group->getTestContext(), bottomTestTypes[testTypeNdx].name));
2220 
2221                 const auto &flags = shaderTestTypes[shaderTestNdx].flag[testTypeNdx];
2222 
2223                 for (size_t flagNdx = 0; flagNdx < flags.size(); ++flagNdx)
2224                 {
2225                     std::stringstream testName;
2226                     testName << getRayFlagTestName(flags[flagNdx]);
2227 
2228                     TestParams testParams{TEST_WIDTH,
2229                                           TEST_HEIGHT,
2230                                           shaderSourceTypes[shaderSourceNdx].shaderSourceType,
2231                                           shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
2232                                           shaderTestTypes[shaderTestNdx].shaderTestType,
2233                                           flags[flagNdx],
2234                                           RF_None,
2235                                           bottomTestTypes[testTypeNdx].testType};
2236                     bottomTestTypeGroup->addChild(
2237                         new RayQueryCullRayFlagsTestCase(group->getTestContext(), testName.str().c_str(), testParams));
2238                 }
2239 
2240                 std::vector<tcu::TestNode *> tests;
2241                 bottomTestTypeGroup->getChildren(tests);
2242                 if (!tests.empty())
2243                     testTypeGroup->addChild(bottomTestTypeGroup.release());
2244             }
2245             sourceTypeGroup->addChild(testTypeGroup.release());
2246         }
2247         group->addChild(sourceTypeGroup.release());
2248     }
2249 
2250     return group.release();
2251 }
2252 
2253 } // namespace RayQuery
2254 
2255 } // namespace vkt
2256