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