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