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