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