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 Tracing Builtin and specialization constant tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktRayTracingBuiltinTests.hpp"
25
26 #include "vkDefs.hpp"
27
28 #include "vktTestCase.hpp"
29 #include "vkCmdUtil.hpp"
30 #include "vkObjUtil.hpp"
31 #include "vkBuilderUtil.hpp"
32 #include "vkBarrierUtil.hpp"
33 #include "vkBufferWithMemory.hpp"
34 #include "vkImageWithMemory.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkPipelineConstructionUtil.hpp"
38
39 #include "vkRayTracingUtil.hpp"
40
41 #include "tcuTestLog.hpp"
42 #include "tcuMatrix.hpp"
43
44 #include "deMath.h"
45
46 namespace vkt
47 {
48 namespace RayTracing
49 {
50 namespace
51 {
52 using namespace vk;
53 using namespace std;
54
55 static const VkFlags ALL_RAY_TRACING_STAGES = VK_SHADER_STAGE_RAYGEN_BIT_KHR
56 | VK_SHADER_STAGE_ANY_HIT_BIT_KHR
57 | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
58 | VK_SHADER_STAGE_MISS_BIT_KHR
59 | VK_SHADER_STAGE_INTERSECTION_BIT_KHR
60 | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
61
62 enum GeomType
63 {
64 GEOM_TYPE_TRIANGLES,
65 GEOM_TYPE_AABBS,
66 };
67
68 enum TestId
69 {
70 TEST_ID_LAUNCH_ID_EXT = 0,
71 TEST_ID_LAUNCH_SIZE_EXT,
72 TEST_ID_PRIMITIVE_ID,
73 TEST_ID_INSTANCE_ID,
74 TEST_ID_INSTANCE_CUSTOM_INDEX_EXT,
75 TEST_ID_GEOMETRY_INDEX_EXT,
76 TEST_ID_WORLD_RAY_ORIGIN_EXT,
77 TEST_ID_WORLD_RAY_DIRECTION_EXT,
78 TEST_ID_OBJECT_RAY_ORIGIN_EXT,
79 TEST_ID_OBJECT_RAY_DIRECTION_EXT,
80 TEST_ID_RAY_T_MIN_EXT,
81 TEST_ID_RAY_T_MAX_EXT,
82 TEST_ID_INCOMING_RAY_FLAGS_EXT,
83 TEST_ID_HIT_T_EXT,
84 TEST_ID_HIT_KIND_EXT,
85 TEST_ID_OBJECT_TO_WORLD_EXT,
86 TEST_ID_OBJECT_TO_WORLD_3X4_EXT,
87 TEST_ID_WORLD_TO_OBJECT_EXT,
88 TEST_ID_WORLD_TO_OBJECT_3X4_EXT,
89 TEST_ID_INDICES_INDIRECT,
90 TEST_ID_TRANSFORMS_INDIRECT,
91 TEST_ID_TMINMAX_INDIRECT,
92 TEST_ID_INCOMING_RAY_FLAGS_INDIRECT,
93 TEST_ID_HIT_KIND_INDIRECT,
94 TEST_ID_LAST
95 };
96
97 enum RayFlagBits
98 {
99 RAY_FLAG_BIT_OPAQUE_EXT = 0, // const uint gl_RayFlagsOpaqueEXT = 1U;
100 RAY_FLAG_BIT_NO_OPAQUE_EXT = 1, // const uint gl_RayFlagsNoOpaqueEXT = 2U;
101 RAY_FLAG_BIT_TERMINATE_ON_FIRST_HIT_EXT = 2, // const uint gl_RayFlagsTerminateOnFirstHitEXT = 4U;
102 RAY_FLAG_BIT_SKIP_CLOSEST_HIT_SHADER_EXT = 3, // const uint gl_RayFlagsSkipClosestHitShaderEXT = 8U;
103 RAY_FLAG_BIT_CULL_BACK_FACING_TRIANGLES_EXT = 4, // const uint gl_RayFlagsCullBackFacingTrianglesEXT = 16U;
104 RAY_FLAG_BIT_CULL_FRONT_FACING_TRIANGLES_EXT = 5, // const uint gl_RayFlagsCullFrontFacingTrianglesEXT = 32U;
105 RAY_FLAG_BIT_CULL_OPAQUE_EXT = 6, // const uint gl_RayFlagsCullOpaqueEXT = 64U;
106 RAY_FLAG_BIT_CULL_NO_OPAQUE_EXT = 7, // const uint gl_RayFlagsCullNoOpaqueEXT = 128U;
107 RAY_FLAG_BIT_LAST_PER_TEST,
108 RAY_FLAG_BIT_SKIP_TRIANGLES_EXT = 8, // const uint gl_RayFlagsSkipTrianglesEXT = 256U;
109 RAY_FLAG_BIT_SKIP_AABB_EXT = 9, // const uint gl_RayFlagsSkipAABBEXT = 512U;
110 RAY_FLAG_BIT_LAST
111 };
112
113 struct CaseDef
114 {
115 TestId id;
116 const char* name;
117 deUint32 width;
118 deUint32 height;
119 deUint32 depth;
120 deUint32 raysDepth;
121 VkFormat format;
122 bool fixedPointScalarOutput;
123 bool fixedPointVectorOutput;
124 bool fixedPointMatrixOutput;
125 GeomType geomType;
126 deUint32 squaresGroupCount;
127 deUint32 geometriesGroupCount;
128 deUint32 instancesGroupCount;
129 VkShaderStageFlagBits stage;
130 bool rayFlagSkipTriangles;
131 bool rayFlagSkipAABSs;
132 bool opaque;
133 bool frontFace;
134 VkPipelineCreateFlags pipelineCreateFlags;
135 bool useSpecConstants;
136 bool skipClosestHit;
137 bool useMaintenance5;
138 };
139
140 const deUint32 DEFAULT_UINT_CLEAR_VALUE = 0x8000;
141 const deUint32 FIXED_POINT_DIVISOR = 1024 * 1024;
142 const deUint32 FIXED_POINT_ALLOWED_ERROR = 4;
143
isPlain(const deUint32 width, const deUint32 height, const deUint32 depth)144 bool isPlain (const deUint32 width, const deUint32 height, const deUint32 depth)
145 {
146 return (width == 1 || height == 1 || depth == 1);
147 }
148
getShaderGroupSize(const InstanceInterface& vki, const VkPhysicalDevice physicalDevice)149 deUint32 getShaderGroupSize (const InstanceInterface& vki,
150 const VkPhysicalDevice physicalDevice)
151 {
152 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
153
154 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
155 return rayTracingPropertiesKHR->getShaderGroupHandleSize();
156 }
157
getShaderGroupBaseAlignment(const InstanceInterface& vki, const VkPhysicalDevice physicalDevice)158 deUint32 getShaderGroupBaseAlignment (const InstanceInterface& vki,
159 const VkPhysicalDevice physicalDevice)
160 {
161 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
162
163 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
164 return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
165 }
166
makeImageCreateInfo(deUint32 width, deUint32 height, deUint32 depth, VkFormat format)167 VkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, deUint32 depth, VkFormat format)
168 {
169 const VkImageType imageType = VK_IMAGE_TYPE_3D;
170 const VkImageUsageFlags usage = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
171 const VkImageCreateInfo imageCreateInfo =
172 {
173 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
174 DE_NULL, // const void* pNext;
175 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
176 imageType, // VkImageType imageType;
177 format, // VkFormat format;
178 makeExtent3D(width, height, depth), // VkExtent3D extent;
179 1u, // deUint32 mipLevels;
180 1u, // deUint32 arrayLayers;
181 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
182 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
183 usage, // VkImageUsageFlags usage;
184 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
185 0u, // deUint32 queueFamilyIndexCount;
186 DE_NULL, // const deUint32* pQueueFamilyIndices;
187 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
188 };
189
190 return imageCreateInfo;
191 }
192
193 class RayTracingBuiltinLaunchTestInstance : public TestInstance
194 {
195 public:
196 RayTracingBuiltinLaunchTestInstance (Context& context, const CaseDef& data);
197 ~RayTracingBuiltinLaunchTestInstance (void);
198 tcu::TestStatus iterate (void);
199
200 protected:
201 void checkSupportInInstance (void) const;
202 Move<VkPipeline> makePipeline (de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
203 VkPipelineLayout pipelineLayout,
204 const VkSpecializationInfo* specializationInfo);
205 std::vector<deInt32> expectedIntValuesBuffer (void);
206 std::vector<float> expectedFloatValuesBuffer (void);
207 std::vector<float> expectedVectorValuesBuffer (void);
208 std::vector<float> expectedMatrixValuesBuffer (void);
209 de::MovePtr<BufferWithMemory> runTest (void);
210 de::MovePtr<BufferWithMemory> createShaderBindingTable (const InstanceInterface& vki,
211 const DeviceInterface& vkd,
212 const VkDevice device,
213 const VkPhysicalDevice physicalDevice,
214 const VkPipeline pipeline,
215 Allocator& allocator,
216 de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
217 const deUint32 group);
218
219 bool validateIntBuffer (de::MovePtr<BufferWithMemory> buffer);
220 bool validateFloatBuffer (de::MovePtr<BufferWithMemory> buffer);
221 bool validateVectorBuffer (de::MovePtr<BufferWithMemory> buffer);
222 bool validateMatrixBuffer (de::MovePtr<BufferWithMemory> buffer);
223
224 de::MovePtr<TopLevelAccelerationStructure> initTopAccelerationStructure (VkCommandBuffer cmdBuffer,
225 vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures);
226 vector<de::SharedPtr<BottomLevelAccelerationStructure> > initBottomAccelerationStructures (VkCommandBuffer cmdBuffer);
227 de::MovePtr<BottomLevelAccelerationStructure> initBottomAccelerationStructure (VkCommandBuffer cmdBuffer,
228 tcu::UVec2& startPos);
229
230 private:
231 CaseDef m_data;
232 VkShaderStageFlags m_shaders;
233 deUint32 m_raygenShaderGroup;
234 deUint32 m_missShaderGroup;
235 deUint32 m_hitShaderGroup;
236 deUint32 m_callableShaderGroup;
237 deUint32 m_shaderGroupCount;
238 };
239
RayTracingBuiltinLaunchTestInstance(Context& context, const CaseDef& data)240 RayTracingBuiltinLaunchTestInstance::RayTracingBuiltinLaunchTestInstance (Context& context, const CaseDef& data)
241 : vkt::TestInstance (context)
242 , m_data (data)
243 , m_shaders (0)
244 , m_raygenShaderGroup (~0u)
245 , m_missShaderGroup (~0u)
246 , m_hitShaderGroup (~0u)
247 , m_callableShaderGroup (~0u)
248 , m_shaderGroupCount (0)
249 {
250 const VkShaderStageFlags hitStages = VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
251 BinaryCollection& collection = m_context.getBinaryCollection();
252 deUint32 group = 0;
253 deUint32 shaderCount = 0;
254
255 if (collection.contains("rgen")) m_shaders |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
256 if (collection.contains("ahit")) m_shaders |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
257 if (collection.contains("chit")) m_shaders |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
258 if (collection.contains("miss")) m_shaders |= VK_SHADER_STAGE_MISS_BIT_KHR;
259 if (collection.contains("sect")) m_shaders |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
260 if (collection.contains("call")) m_shaders |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
261
262 for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
263 shaderCount++;
264
265 if (shaderCount != (deUint32)dePop32(m_shaders))
266 TCU_THROW(InternalError, "Unused shaders detected in the collection");
267
268 if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))
269 m_raygenShaderGroup = group++;
270
271 if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))
272 m_missShaderGroup = group++;
273
274 if (0 != (m_shaders & hitStages))
275 m_hitShaderGroup = group++;
276
277 if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))
278 m_callableShaderGroup = group++;
279
280 m_shaderGroupCount = group;
281 }
282
~RayTracingBuiltinLaunchTestInstance(void)283 RayTracingBuiltinLaunchTestInstance::~RayTracingBuiltinLaunchTestInstance (void)
284 {
285 }
286
287 class RayTracingTestCase : public TestCase
288 {
289 public:
290 RayTracingTestCase (tcu::TestContext& context, const char* name, const CaseDef data);
291 ~RayTracingTestCase (void);
292
293 virtual void initPrograms (SourceCollections& programCollection) const;
294 virtual TestInstance* createInstance (Context& context) const;
295 virtual void checkSupport (Context& context) const;
296
297 private:
298 static inline const std::string getIntersectionPassthrough (void);
299 static inline const std::string getMissPassthrough (void);
300 static inline const std::string getHitPassthrough (void);
301
302 CaseDef m_data;
303 };
304
RayTracingTestCase(tcu::TestContext& context, const char* name, const CaseDef data)305 RayTracingTestCase::RayTracingTestCase (tcu::TestContext& context, const char* name, const CaseDef data)
306 : vkt::TestCase (context, name)
307 , m_data (data)
308 {
309 }
310
~RayTracingTestCase(void)311 RayTracingTestCase::~RayTracingTestCase (void)
312 {
313 }
314
checkSupport(Context& context) const315 void RayTracingTestCase::checkSupport(Context& context) const
316 {
317 const bool pipelineFlagSkipTriangles = ((m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR) != 0);
318 const bool pipelineFlagSkipAABSs = ((m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR) != 0);
319 const bool cullingFlags = m_data.rayFlagSkipTriangles
320 || m_data.rayFlagSkipAABSs
321 || pipelineFlagSkipTriangles
322 || pipelineFlagSkipAABSs;
323
324 context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
325 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
326
327 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
328 if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE )
329 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
330
331 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
332 if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
333 TCU_THROW(TestError, "VK_KHR_ray_tracing_pipeline requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
334
335 if (cullingFlags && rayTracingPipelineFeaturesKHR.rayTraversalPrimitiveCulling == DE_FALSE)
336 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTraversalPrimitiveCulling");
337
338 if (m_data.useMaintenance5)
339 context.requireDeviceFunctionality("VK_KHR_maintenance5");
340 }
341
getIntersectionPassthrough(void)342 const std::string RayTracingTestCase::getIntersectionPassthrough (void)
343 {
344 const std::string intersectionPassthrough =
345 "#version 460 core\n"
346 "#extension GL_EXT_ray_tracing : require\n"
347 "hitAttributeEXT vec3 hitAttribute;\n"
348 "\n"
349 "void main()\n"
350 "{\n"
351 " reportIntersectionEXT(0.95f, 0x7Eu);\n"
352 "}\n";
353
354 return intersectionPassthrough;
355 }
356
getMissPassthrough(void)357 const std::string RayTracingTestCase::getMissPassthrough (void)
358 {
359 const std::string missPassthrough =
360 "#version 460 core\n"
361 "#extension GL_EXT_ray_tracing : require\n"
362 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
363 "\n"
364 "void main()\n"
365 "{\n"
366 "}\n";
367
368 return missPassthrough;
369 }
370
getHitPassthrough(void)371 const std::string RayTracingTestCase::getHitPassthrough (void)
372 {
373 const std::string hitPassthrough =
374 "#version 460 core\n"
375 "#extension GL_EXT_ray_tracing : require\n"
376 "hitAttributeEXT vec3 attribs;\n"
377 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
378 "\n"
379 "void main()\n"
380 "{\n"
381 "}\n";
382
383 return hitPassthrough;
384 }
385
initPrograms(SourceCollections& programCollection) const386 void RayTracingTestCase::initPrograms (SourceCollections& programCollection) const
387 {
388 const bool useSC = m_data.useSpecConstants;
389 DE_ASSERT(!useSC || m_data.id == TEST_ID_LAUNCH_ID_EXT);
390
391 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
392
393 if (m_data.id == TEST_ID_LAUNCH_ID_EXT || m_data.id == TEST_ID_LAUNCH_SIZE_EXT)
394 {
395 const std::string specConstants =
396 "layout (constant_id=0) const highp int factor1 = 1;\n"
397 "layout (constant_id=1) const highp float factor2 = 2.0;\n"
398 ;
399
400 const std::string updateImage =
401 " ivec3 p = ivec3(gl_LaunchIDEXT);\n"
402 " ivec3 v = ivec3(gl_" + std::string(m_data.name) + ");\n"
403 " int r = v.x + " + (useSC ? "factor1" : "256") + " * (v.y + " + (useSC ? "int(factor2)" : "256") + " * v.z) + 1;\n"
404 " ivec4 c = ivec4(r,0,0,1);\n"
405 " imageStore(result, p, c);\n";
406
407 switch (m_data.stage)
408 {
409 case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
410 {
411 std::stringstream css;
412 css <<
413 "#version 460 core\n"
414 "#extension GL_EXT_ray_tracing : require\n"
415 << (useSC ? specConstants : "") <<
416 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
417 "\n"
418 "void main()\n"
419 "{\n"
420 << updateImage <<
421 "}\n";
422
423 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
424
425 break;
426 }
427
428 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
429 {
430 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
431
432 {
433 std::stringstream css;
434 css <<
435 "#version 460 core\n"
436 "#extension GL_EXT_ray_tracing : require\n"
437 << (useSC ? specConstants : "") <<
438 "hitAttributeEXT vec3 attribs;\n"
439 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
440 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
441 "\n"
442 "void main()\n"
443 "{\n"
444 << updateImage <<
445 "}\n";
446
447 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
448 }
449
450 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
451 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
452
453 break;
454 }
455
456 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
457 {
458 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
459
460 {
461 std::stringstream css;
462 css <<
463 "#version 460 core\n"
464 "#extension GL_EXT_ray_tracing : require\n"
465 << (useSC ? specConstants : "") <<
466 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
467 "hitAttributeEXT vec3 attribs;\n"
468 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
469 "\n"
470 "void main()\n"
471 "{\n"
472 << updateImage <<
473 "}\n";
474
475 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
476 }
477
478 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
479 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
480
481 break;
482 }
483
484 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
485 {
486 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
487
488 {
489 std::stringstream css;
490 css <<
491 "#version 460 core\n"
492 "#extension GL_EXT_ray_tracing : require\n"
493 << (useSC ? specConstants : "") <<
494 "hitAttributeEXT vec3 hitAttribute;\n"
495 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
496 "\n"
497 "void main()\n"
498 "{\n"
499 << updateImage <<
500 " hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n"
501 " reportIntersectionEXT(1.0f, 0);\n"
502 "}\n";
503
504 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
505 }
506
507 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
508 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
509 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
510
511 break;
512 }
513
514 case VK_SHADER_STAGE_MISS_BIT_KHR:
515 {
516 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
517
518 {
519 std::stringstream css;
520 css <<
521 "#version 460 core\n"
522 "#extension GL_EXT_ray_tracing : require\n"
523 << (useSC ? specConstants : "") <<
524 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
525 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
526 "\n"
527 "void main()\n"
528 "{\n"
529 << updateImage <<
530 "}\n";
531
532 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
533 }
534
535 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
536 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
537
538 break;
539 }
540
541 case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
542 {
543 {
544 std::stringstream css;
545 css <<
546 "#version 460 core\n"
547 "#extension GL_EXT_ray_tracing : require\n"
548 "layout(location = 0) callableDataEXT float dummy;"
549 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
550 "\n"
551 "void main()\n"
552 "{\n"
553 " executeCallableEXT(0, 0);\n"
554 "}\n";
555
556 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
557 }
558
559 {
560 std::stringstream css;
561 css <<
562 "#version 460 core\n"
563 "#extension GL_EXT_ray_tracing : require\n"
564 << (useSC ? specConstants : "") <<
565 "layout(location = 0) callableDataInEXT float dummy;"
566 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
567 "\n"
568 "void main()\n"
569 "{\n"
570 << updateImage <<
571 "}\n";
572
573 programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
574 }
575
576 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
577 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
578 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
579
580 break;
581 }
582
583 default:
584 TCU_THROW(InternalError, "Unknown stage");
585 }
586 }
587 else if (m_data.id == TEST_ID_GEOMETRY_INDEX_EXT ||
588 m_data.id == TEST_ID_PRIMITIVE_ID ||
589 m_data.id == TEST_ID_INSTANCE_ID ||
590 m_data.id == TEST_ID_INSTANCE_CUSTOM_INDEX_EXT ||
591 m_data.id == TEST_ID_HIT_KIND_EXT )
592 {
593 const std::string conditionGeometryIndex = " int n = int(gl_LaunchIDEXT.x + gl_LaunchSizeEXT.x * (gl_LaunchIDEXT.y + gl_LaunchSizeEXT.y * gl_LaunchIDEXT.z));\n"
594 " int m = (n / " + de::toString(m_data.squaresGroupCount) + ") % " + de::toString(m_data.geometriesGroupCount) + ";\n"
595 " if (r == m)";
596 const std::string conditionPrimitiveId = " int n = int(gl_LaunchIDEXT.x + gl_LaunchSizeEXT.x * (gl_LaunchIDEXT.y + gl_LaunchSizeEXT.y * gl_LaunchIDEXT.z));\n"
597 " int m = n % " + de::toString(m_data.squaresGroupCount) + ";\n"
598 " if (r == m)";
599 const std::string condition = (m_data.id == TEST_ID_GEOMETRY_INDEX_EXT) && (m_data.geomType == GEOM_TYPE_AABBS) ? conditionGeometryIndex
600 : (m_data.id == TEST_ID_PRIMITIVE_ID) && (m_data.geomType == GEOM_TYPE_AABBS) ? conditionPrimitiveId
601 : "";
602 const std::string updateImage =
603 " ivec3 p = ivec3(gl_LaunchIDEXT);\n"
604 " int r = int(gl_" + std::string(m_data.name) + ");\n"
605 " ivec4 c = ivec4(r,0,0,1);\n"
606 + condition + " imageStore(result, p, c);\n";
607
608 switch (m_data.stage)
609 {
610 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
611 {
612 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
613
614 {
615 std::stringstream css;
616 css <<
617 "#version 460 core\n"
618 "#extension GL_EXT_ray_tracing : require\n"
619 "hitAttributeEXT vec3 attribs;\n"
620 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
621 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
622 "\n"
623 "void main()\n"
624 "{\n"
625 << updateImage <<
626 "}\n";
627
628 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
629 }
630
631 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
632 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
633
634 if (m_data.geomType == GEOM_TYPE_AABBS)
635 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(getIntersectionPassthrough())) << buildOptions;
636
637 break;
638 }
639
640 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
641 {
642 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
643
644 {
645 std::stringstream css;
646 css <<
647 "#version 460 core\n"
648 "#extension GL_EXT_ray_tracing : require\n"
649 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
650 "hitAttributeEXT vec3 attribs;\n"
651 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
652 "\n"
653 "void main()\n"
654 "{\n"
655 << updateImage <<
656 "}\n";
657
658 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
659 }
660
661 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
662 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
663
664 if (m_data.geomType == GEOM_TYPE_AABBS)
665 {
666 const std::string intersectionShaderSingle =
667 "#version 460 core\n"
668 "#extension GL_EXT_ray_tracing : require\n"
669 "hitAttributeEXT vec3 hitAttribute;\n"
670 "\n"
671 "void main()\n"
672 "{\n"
673 " int r = int(gl_" + std::string(m_data.name) + ");\n"
674 + condition + " reportIntersectionEXT(0.95f, 0x7Eu);\n"
675 "}\n";
676 const std::string intersectionShader = condition.empty() ? getIntersectionPassthrough() : intersectionShaderSingle;
677
678 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
679 }
680
681 break;
682 }
683
684 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
685 {
686 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
687
688 {
689 std::stringstream css;
690 css <<
691 "#version 460 core\n"
692 "#extension GL_EXT_ray_tracing : require\n"
693 "hitAttributeEXT vec3 hitAttribute;\n"
694 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
695 "\n"
696 "void main()\n"
697 "{\n"
698 << updateImage <<
699 " reportIntersectionEXT(0.95f, 0);\n"
700 "}\n";
701
702 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
703 }
704
705 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
706 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
707 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
708
709 break;
710 }
711
712 default:
713 TCU_THROW(InternalError, "Unknown stage");
714 }
715 }
716 else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_EXT)
717 {
718 const bool cullingFlags = m_data.rayFlagSkipTriangles || m_data.rayFlagSkipAABSs;
719 const std::string cullingFlagsInit = (m_data.rayFlagSkipTriangles && m_data.rayFlagSkipAABSs) ? "gl_RayFlagsSkipTrianglesEXT|gl_RayFlagsSkipAABBEXT"
720 : m_data.rayFlagSkipTriangles ? "gl_RayFlagsSkipTrianglesEXT"
721 : m_data.rayFlagSkipAABSs ? "gl_RayFlagsSkipAABBEXT"
722 : "gl_RayFlagsNoneEXT";
723 const std::string updateImage =
724 " ivec3 p = ivec3(gl_LaunchIDEXT);\n"
725 " int r = int(gl_" + std::string(m_data.name) + ");\n"
726 " ivec4 c = ivec4(r,0,0,1);\n"
727 " imageStore(result, p, c);\n";
728 const std::string intersectionShader =
729 "#version 460 core\n"
730 "#extension GL_EXT_ray_tracing : require\n"
731 "hitAttributeEXT vec3 hitAttribute;\n"
732 "\n"
733 "void main()\n"
734 "{\n"
735 " uint hitKind = " + std::string(m_data.frontFace ? "0x7Eu" : "0x7Fu") + ";\n"
736 " reportIntersectionEXT(0.95f, hitKind);\n"
737 "}\n";
738 const std::string raygenFlagsFragment =
739 "\n"
740 " if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_OPAQUE_EXT ) + "))) f = f | gl_RayFlagsOpaqueEXT;\n"
741 " else if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_NO_OPAQUE_EXT ) + "))) f = f | gl_RayFlagsNoOpaqueEXT;\n"
742 " else if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_CULL_OPAQUE_EXT ) + "))) f = f | gl_RayFlagsCullOpaqueEXT;\n"
743 " else if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_CULL_NO_OPAQUE_EXT ) + "))) f = f | gl_RayFlagsCullNoOpaqueEXT;\n"
744 "\n"
745 " if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_CULL_BACK_FACING_TRIANGLES_EXT ) + "))) f = f | gl_RayFlagsCullBackFacingTrianglesEXT;\n"
746 " else if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_CULL_FRONT_FACING_TRIANGLES_EXT) + "))) f = f | gl_RayFlagsCullFrontFacingTrianglesEXT;\n"
747 "\n"
748 " if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_TERMINATE_ON_FIRST_HIT_EXT ) + "))) f = f | gl_RayFlagsTerminateOnFirstHitEXT;\n"
749 " if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_SKIP_CLOSEST_HIT_SHADER_EXT ) + "))) f = f | gl_RayFlagsSkipClosestHitShaderEXT;\n"
750 "\n";
751 const std::string raygenShader =
752 "#version 460 core\n"
753 "#extension GL_EXT_ray_tracing : require\n"
754 + (cullingFlags ? std::string("#extension GL_EXT_ray_flags_primitive_culling : require\n") : "") +
755 "layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
756 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
757 "\n"
758 "void main()\n"
759 "{\n"
760 " uint n = gl_LaunchIDEXT.x + gl_LaunchSizeEXT.x * (gl_LaunchIDEXT.y + gl_LaunchSizeEXT.y * gl_LaunchIDEXT.z);\n"
761 " uint f = " + cullingFlagsInit + ";\n"
762 + raygenFlagsFragment +
763 " uint rayFlags = f;\n"
764 " uint cullMask = 0xFF;\n"
765 " float tmin = 0.0;\n"
766 " float tmax = 9.0;\n"
767 " vec3 origin = vec3((float(gl_LaunchIDEXT.x) + 0.5f) / float(gl_LaunchSizeEXT.x), (float(gl_LaunchIDEXT.y) + 0.5f) / float(gl_LaunchSizeEXT.y), 0.0);\n"
768 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
769 " traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
770 "}\n";
771
772 switch (m_data.stage)
773 {
774 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
775 {
776 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
777
778 {
779 std::stringstream css;
780 css <<
781 "#version 460 core\n"
782 "#extension GL_EXT_ray_tracing : require\n"
783 "hitAttributeEXT vec3 hitAttribute;\n"
784 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
785 "\n"
786 "void main()\n"
787 "{\n"
788 << updateImage <<
789 "}\n";
790
791 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
792 }
793
794 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
795 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
796 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
797
798 break;
799 }
800
801 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
802 {
803 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
804
805 {
806 std::stringstream css;
807 css <<
808 "#version 460 core\n"
809 "#extension GL_EXT_ray_tracing : require\n"
810 "hitAttributeEXT vec3 attribs;\n"
811 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
812 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
813 "\n"
814 "void main()\n"
815 "{\n"
816 << updateImage <<
817 "}\n";
818
819 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
820 }
821
822 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
823 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
824
825 if (m_data.geomType == GEOM_TYPE_AABBS)
826 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
827
828 break;
829 }
830
831 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
832 {
833 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
834
835 {
836 std::stringstream css;
837 css <<
838 "#version 460 core\n"
839 "#extension GL_EXT_ray_tracing : require\n"
840 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
841 "hitAttributeEXT vec3 attribs;\n"
842 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
843 "\n"
844 "void main()\n"
845 "{\n"
846 << updateImage <<
847 "}\n";
848
849 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
850 }
851
852 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
853 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
854
855 if (m_data.geomType == GEOM_TYPE_AABBS)
856 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
857
858 break;
859 }
860
861 case VK_SHADER_STAGE_MISS_BIT_KHR:
862 {
863 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
864
865 {
866 std::stringstream css;
867 css <<
868 "#version 460 core\n"
869 "#extension GL_EXT_ray_tracing : require\n"
870 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
871 "\n"
872 "void main()\n"
873 "{\n"
874 << updateImage <<
875 "}\n";
876
877 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
878 }
879
880 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
881 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
882
883 if (m_data.geomType == GEOM_TYPE_AABBS)
884 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
885
886 break;
887 }
888
889 default:
890 TCU_THROW(InternalError, "Unknown stage");
891 }
892 }
893 else if (m_data.id == TEST_ID_HIT_T_EXT ||
894 m_data.id == TEST_ID_RAY_T_MIN_EXT ||
895 m_data.id == TEST_ID_RAY_T_MAX_EXT )
896 {
897 const std::string raygenShader =
898 "#version 460 core\n"
899 "#extension GL_EXT_ray_tracing : require\n"
900 "layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
901 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
902 "\n"
903 "void main()\n"
904 "{\n"
905 " uint cullMask = 0xFF;\n"
906 " float a = float(gl_LaunchIDEXT.x) / gl_LaunchSizeEXT.x;\n"
907 " float b = 1.0f + float(gl_LaunchIDEXT.y) / gl_LaunchSizeEXT.y;\n"
908 " float c = 0.25f * a / b;\n"
909 " float tmin = c;\n"
910 " float tmax = 0.75f + c;\n"
911 " vec3 origin = vec3((float(gl_LaunchIDEXT.x) + 0.5f) / float(gl_LaunchSizeEXT.x), (float(gl_LaunchIDEXT.y) + 0.5f) / float(gl_LaunchSizeEXT.y), 0.0);\n"
912 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
913 " traceRayEXT(topLevelAS, gl_RayFlagsNoneEXT, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
914 "}\n";
915 const std::string intersectionShader =
916 "#version 460 core\n"
917 "#extension GL_EXT_ray_tracing : require\n"
918 "hitAttributeEXT vec3 hitAttribute;\n"
919 "\n"
920 "void main()\n"
921 "{\n"
922 " float a = float(gl_LaunchIDEXT.x) / gl_LaunchSizeEXT.x;\n"
923 " float b = 1.0f + float(gl_LaunchIDEXT.y) / gl_LaunchSizeEXT.y;\n"
924 " float c = 0.25f * a / b;\n"
925 " reportIntersectionEXT(0.03125f + c, 0);\n"
926 "}\n";
927 const std::string updateImage =
928 " ivec3 p = ivec3(gl_LaunchIDEXT);\n"
929 " int r = int(" +de::toString(FIXED_POINT_DIVISOR) + ".0f * gl_" + std::string(m_data.name) + ");\n"
930 " ivec4 c = ivec4(r,0,0,1);\n"
931 " imageStore(result, p, c);\n";
932
933 switch (m_data.stage)
934 {
935 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
936 {
937 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
938
939 {
940 std::stringstream css;
941 css <<
942 "#version 460 core\n"
943 "#extension GL_EXT_ray_tracing : require\n"
944 "hitAttributeEXT vec3 attribs;\n"
945 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
946 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
947 "\n"
948 "void main()\n"
949 "{\n"
950 << updateImage <<
951 "}\n";
952
953 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
954 }
955
956 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
957 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
958
959 if (m_data.geomType == GEOM_TYPE_AABBS)
960 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
961
962 break;
963 }
964
965 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
966 {
967 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
968
969 {
970 std::stringstream css;
971 css <<
972 "#version 460 core\n"
973 "#extension GL_EXT_ray_tracing : require\n"
974 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
975 "hitAttributeEXT vec3 attribs;\n"
976 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
977 "\n"
978 "void main()\n"
979 "{\n"
980 << updateImage <<
981 "}\n";
982
983 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
984 }
985
986 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
987 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
988
989 if (m_data.geomType == GEOM_TYPE_AABBS)
990 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
991
992 break;
993 }
994
995 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
996 {
997 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
998
999 {
1000 std::stringstream css;
1001 css <<
1002 "#version 460 core\n"
1003 "#extension GL_EXT_ray_tracing : require\n"
1004 "hitAttributeEXT vec3 hitAttribute;\n"
1005 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1006 "\n"
1007 "void main()\n"
1008 "{\n"
1009 << updateImage <<
1010 "\n"
1011 " float a = float(gl_LaunchIDEXT.x) / gl_LaunchSizeEXT.x;\n"
1012 " float b = 1.0f + float(gl_LaunchIDEXT.y) / gl_LaunchSizeEXT.y;\n"
1013 " reportIntersectionEXT(0.4375f + 0.25f * a / b, 0x7Eu);\n"
1014 "}\n";
1015
1016 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1017 }
1018
1019 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1020 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1021 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1022
1023 break;
1024 }
1025
1026 case VK_SHADER_STAGE_MISS_BIT_KHR:
1027 {
1028 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
1029
1030 {
1031 std::stringstream css;
1032 css <<
1033 "#version 460 core\n"
1034 "#extension GL_EXT_ray_tracing : require\n"
1035 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1036 "\n"
1037 "void main()\n"
1038 "{\n"
1039 << updateImage <<
1040 "}\n";
1041
1042 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1043 }
1044
1045 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1046 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1047
1048 if (m_data.geomType == GEOM_TYPE_AABBS)
1049 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
1050
1051 break;
1052 }
1053
1054 default:
1055 TCU_THROW(InternalError, "Unknown stage");
1056 }
1057 }
1058 else if (m_data.id == TEST_ID_WORLD_RAY_ORIGIN_EXT ||
1059 m_data.id == TEST_ID_WORLD_RAY_DIRECTION_EXT ||
1060 m_data.id == TEST_ID_OBJECT_RAY_ORIGIN_EXT ||
1061 m_data.id == TEST_ID_OBJECT_RAY_DIRECTION_EXT ||
1062 m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT ||
1063 m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT ||
1064 m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT ||
1065 m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT )
1066 {
1067 const bool matrix4x3 = (m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT || m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT);
1068 const bool matrix3x4 = (m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT || m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT);
1069 const bool matrixOutput = matrix4x3 || matrix3x4;
1070 const std::string vectorLoop =
1071 " for (int ndx = 0; ndx < 3; ndx++)\n"
1072 " {\n";
1073 const std::string matrixLoop4x3 =
1074 " int ndx = -1;\n"
1075 " for (int row = 0; row < 3; row++)\n"
1076 " for (int col = 0; col < 4; col++)\n"
1077 " {\n"
1078 " ndx++;\n";
1079 const std::string matrixLoop3x4 =
1080 " int ndx = -1;\n"
1081 " for (int col = 0; col < 3; col++)\n"
1082 " for (int row = 0; row < 4; row++)\n"
1083 " {\n"
1084 " ndx++;\n";
1085 const std::string loop =
1086 matrix4x3 ? matrixLoop4x3 :
1087 matrix3x4 ? matrixLoop3x4 :
1088 vectorLoop;
1089 const std::string index =
1090 (matrixOutput ? "[col][row]" : "[ndx]");
1091 const std::string updateImage =
1092 " float k = " +de::toString(FIXED_POINT_DIVISOR) + ".0f;\n"
1093 + loop +
1094 " ivec3 p = ivec3(gl_LaunchIDEXT.xy, ndx);\n"
1095 " float r = k * gl_" + std::string(m_data.name) + index + ";\n"
1096 " ivec4 c = ivec4(int(r),0,0,1);\n"
1097 " imageStore(result, p, c);\n"
1098 " }\n";
1099
1100 switch (m_data.stage)
1101 {
1102 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
1103 {
1104 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1105
1106 {
1107 std::stringstream css;
1108 css <<
1109 "#version 460 core\n"
1110 "#extension GL_EXT_ray_tracing : require\n"
1111 "hitAttributeEXT vec3 attribs;\n"
1112 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1113 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1114 "\n"
1115 "void main()\n"
1116 "{\n"
1117 << updateImage <<
1118 "}\n";
1119
1120 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1121 }
1122
1123 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1124 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1125
1126 if (m_data.geomType == GEOM_TYPE_AABBS)
1127 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(getIntersectionPassthrough())) << buildOptions;
1128
1129 break;
1130 }
1131
1132 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
1133 {
1134 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1135
1136 {
1137 std::stringstream css;
1138 css <<
1139 "#version 460 core\n"
1140 "#extension GL_EXT_ray_tracing : require\n"
1141 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1142 "hitAttributeEXT vec3 attribs;\n"
1143 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1144 "\n"
1145 "void main()\n"
1146 "{\n"
1147 << updateImage <<
1148 "}\n";
1149
1150 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1151 }
1152
1153 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1154 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1155
1156 if (m_data.geomType == GEOM_TYPE_AABBS)
1157 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(getIntersectionPassthrough())) << buildOptions;
1158
1159 break;
1160 }
1161
1162 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
1163 {
1164 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1165
1166 {
1167 std::stringstream css;
1168 css <<
1169 "#version 460 core\n"
1170 "#extension GL_EXT_ray_tracing : require\n"
1171 "hitAttributeEXT vec3 hitAttribute;\n"
1172 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1173 "\n"
1174 "void main()\n"
1175 "{\n"
1176 << updateImage <<
1177 " reportIntersectionEXT(0.95f, 0);\n"
1178 "}\n";
1179
1180 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1181 }
1182
1183 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1184 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1185 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1186
1187 break;
1188 }
1189
1190 case VK_SHADER_STAGE_MISS_BIT_KHR:
1191 {
1192 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1193
1194 {
1195 std::stringstream css;
1196 css <<
1197 "#version 460 core\n"
1198 "#extension GL_EXT_ray_tracing : require\n"
1199 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1200 "\n"
1201 "void main()\n"
1202 "{\n"
1203 << updateImage <<
1204 "}\n";
1205
1206 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1207 }
1208
1209 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1210 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1211
1212 if (m_data.geomType == GEOM_TYPE_AABBS)
1213 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(getIntersectionPassthrough())) << buildOptions;
1214
1215 break;
1216 }
1217
1218 default:
1219 TCU_THROW(InternalError, "Unknown stage");
1220 }
1221 }
1222 else
1223 {
1224 TCU_THROW(InternalError, "Not implemented");
1225 }
1226 }
1227
createInstance(Context& context) const1228 TestInstance* RayTracingTestCase::createInstance (Context& context) const
1229 {
1230 return new RayTracingBuiltinLaunchTestInstance(context, m_data);
1231 }
1232
initTopAccelerationStructure(VkCommandBuffer cmdBuffer, vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures)1233 de::MovePtr<TopLevelAccelerationStructure> RayTracingBuiltinLaunchTestInstance::initTopAccelerationStructure (VkCommandBuffer cmdBuffer,
1234 vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures)
1235 {
1236 const DeviceInterface& vkd = m_context.getDeviceInterface();
1237 const VkDevice device = m_context.getDevice();
1238 Allocator& allocator = m_context.getDefaultAllocator();
1239 de::MovePtr<TopLevelAccelerationStructure> result = makeTopLevelAccelerationStructure();
1240 const bool transformTest = m_data.id == TEST_ID_WORLD_RAY_ORIGIN_EXT
1241 || m_data.id == TEST_ID_WORLD_RAY_DIRECTION_EXT
1242 || m_data.id == TEST_ID_OBJECT_RAY_ORIGIN_EXT
1243 || m_data.id == TEST_ID_OBJECT_RAY_DIRECTION_EXT
1244 || m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT
1245 || m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT
1246 || m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT
1247 || m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT;
1248
1249 result->setInstanceCount(bottomLevelAccelerationStructures.size());
1250
1251 for (size_t structNdx = 0; structNdx < bottomLevelAccelerationStructures.size(); ++structNdx)
1252 {
1253 VkTransformMatrixKHR transform = identityMatrix3x4;
1254
1255 if (transformTest)
1256 {
1257 if (structNdx & 1)
1258 transform.matrix[0][3] = (1.0f / 8.0f) / float(m_data.width);
1259
1260 if (structNdx & 2)
1261 transform.matrix[1][3] = (1.0f / 16.0f) / float(m_data.height);
1262 }
1263
1264 result->addInstance(bottomLevelAccelerationStructures[structNdx], transform, deUint32(2 * structNdx));
1265 }
1266
1267 result->createAndBuild(vkd, device, cmdBuffer, allocator);
1268
1269 return result;
1270 }
1271
initBottomAccelerationStructure(VkCommandBuffer cmdBuffer, tcu::UVec2& startPos)1272 de::MovePtr<BottomLevelAccelerationStructure> RayTracingBuiltinLaunchTestInstance::initBottomAccelerationStructure (VkCommandBuffer cmdBuffer,
1273 tcu::UVec2& startPos)
1274 {
1275 const DeviceInterface& vkd = m_context.getDeviceInterface();
1276 const VkDevice device = m_context.getDevice();
1277 Allocator& allocator = m_context.getDefaultAllocator();
1278 de::MovePtr<BottomLevelAccelerationStructure> result = makeBottomLevelAccelerationStructure();
1279
1280 result->setGeometryCount(m_data.geometriesGroupCount);
1281
1282 if (m_data.id == TEST_ID_LAUNCH_ID_EXT || m_data.id == TEST_ID_LAUNCH_SIZE_EXT)
1283 {
1284 result->setDefaultGeometryData(m_data.stage);
1285 }
1286 else if (m_data.id == TEST_ID_GEOMETRY_INDEX_EXT ||
1287 m_data.id == TEST_ID_PRIMITIVE_ID ||
1288 m_data.id == TEST_ID_INSTANCE_ID ||
1289 m_data.id == TEST_ID_INSTANCE_CUSTOM_INDEX_EXT )
1290 {
1291 const bool triangles = (m_data.geomType == GEOM_TYPE_TRIANGLES);
1292 const bool missShader = (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1293 const float z = !missShader ? -1.0f : -100.0f;
1294
1295 DE_ASSERT(m_data.squaresGroupCount != 1);
1296
1297 for (size_t geometryNdx = 0; geometryNdx < m_data.geometriesGroupCount; ++geometryNdx)
1298 {
1299 std::vector<tcu::Vec3> geometryData;
1300
1301 geometryData.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1302
1303 for (size_t squareNdx = 0; squareNdx < m_data.squaresGroupCount; ++squareNdx)
1304 {
1305 const deUint32 n = m_data.width * startPos.y() + startPos.x();
1306 const float x0 = float(startPos.x() + 0) / float(m_data.width);
1307 const float y0 = float(startPos.y() + 0) / float(m_data.height);
1308 const float x1 = float(startPos.x() + 1) / float(m_data.width);
1309 const float y1 = float(startPos.y() + 1) / float(m_data.height);
1310 const deUint32 m = n + 1;
1311
1312 if (triangles)
1313 {
1314 const float xm = (x0 + x1) / 2.0f;
1315 const float ym = (y0 + y1) / 2.0f;
1316
1317 geometryData.push_back(tcu::Vec3(x0, y0, z));
1318 geometryData.push_back(tcu::Vec3(xm, y1, z));
1319 geometryData.push_back(tcu::Vec3(x1, ym, z));
1320 }
1321 else
1322 {
1323 geometryData.push_back(tcu::Vec3(x0, y0, z));
1324 geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
1325 }
1326
1327 startPos.y() = m / m_data.width;
1328 startPos.x() = m % m_data.width;
1329 }
1330
1331 result->addGeometry(geometryData, triangles);
1332 }
1333 }
1334 else if (m_data.id == TEST_ID_HIT_KIND_EXT)
1335 {
1336 const bool triangles = (m_data.geomType == GEOM_TYPE_TRIANGLES);
1337 const bool missShader = (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1338 const float z = !missShader ? -1.0f : -100.0f;
1339
1340 DE_ASSERT(m_data.squaresGroupCount != 1);
1341 DE_ASSERT(m_data.geometriesGroupCount == 4);
1342
1343 std::vector<tcu::Vec3> geometryDataOpaque;
1344 std::vector<tcu::Vec3> geometryDataNonOpaque;
1345
1346 geometryDataOpaque.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1347 geometryDataNonOpaque.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1348
1349 for (size_t geometryNdx = 0; geometryNdx < m_data.geometriesGroupCount; ++geometryNdx)
1350 {
1351 const bool cw = ((geometryNdx & 1) == 0) ? true : false;
1352 std::vector<tcu::Vec3>& geometryData = ((geometryNdx & 2) == 0) ? geometryDataOpaque : geometryDataNonOpaque;
1353
1354 for (size_t squareNdx = 0; squareNdx < m_data.squaresGroupCount; ++squareNdx)
1355 {
1356 const deUint32 n = m_data.width * startPos.y() + startPos.x();
1357 const deUint32 m = n + 1;
1358 const float x0 = float(startPos.x() + 0) / float(m_data.width);
1359 const float y0 = float(startPos.y() + 0) / float(m_data.height);
1360 const float x1 = float(startPos.x() + 1) / float(m_data.width);
1361 const float y1 = float(startPos.y() + 1) / float(m_data.height);
1362
1363 if (triangles)
1364 {
1365 const float xm = (x0 + x1) / 2.0f;
1366 const float ym = (y0 + y1) / 2.0f;
1367
1368 if (cw)
1369 {
1370 geometryData.push_back(tcu::Vec3(x0, y0, z));
1371 geometryData.push_back(tcu::Vec3(x1, ym, z));
1372 geometryData.push_back(tcu::Vec3(xm, y1, z));
1373 }
1374 else
1375 {
1376 geometryData.push_back(tcu::Vec3(x0, y0, z));
1377 geometryData.push_back(tcu::Vec3(xm, y1, z));
1378 geometryData.push_back(tcu::Vec3(x1, ym, z));
1379 }
1380 }
1381 else
1382 {
1383 geometryData.push_back(tcu::Vec3(x0, y0, z));
1384 geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
1385 }
1386
1387 startPos.y() = m / m_data.width;
1388 startPos.x() = m % m_data.width;
1389 }
1390 }
1391
1392 DE_ASSERT(startPos.y() == m_data.height && startPos.x() == 0);
1393
1394 result->addGeometry(geometryDataOpaque, triangles, (VkGeometryFlagsKHR)VK_GEOMETRY_OPAQUE_BIT_KHR);
1395 result->addGeometry(geometryDataNonOpaque, triangles, (VkGeometryFlagsKHR)0);
1396 }
1397 else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_EXT)
1398 {
1399 const bool triangles = (m_data.geomType == GEOM_TYPE_TRIANGLES);
1400 const bool missShader = (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1401 const float z = !missShader ? -1.0f : -100.0f;
1402 const VkGeometryFlagsKHR geometryFlags = m_data.opaque ? static_cast<VkGeometryFlagsKHR>(VK_GEOMETRY_OPAQUE_BIT_KHR) : static_cast<VkGeometryFlagsKHR>(0);
1403 const bool cw = m_data.frontFace;
1404 std::vector<tcu::Vec3> geometryData;
1405
1406 DE_ASSERT(m_data.geometriesGroupCount == 1);
1407 DE_ASSERT(m_data.squaresGroupCount != 1);
1408
1409 geometryData.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1410
1411 for (size_t squareNdx = 0; squareNdx < m_data.squaresGroupCount; ++squareNdx)
1412 {
1413 const deUint32 n = m_data.width * startPos.y() + startPos.x();
1414 const deUint32 m = n + 1;
1415 const float x0 = float(startPos.x() + 0) / float(m_data.width);
1416 const float y0 = float(startPos.y() + 0) / float(m_data.height);
1417 const float x1 = float(startPos.x() + 1) / float(m_data.width);
1418 const float y1 = float(startPos.y() + 1) / float(m_data.height);
1419
1420 if (triangles)
1421 {
1422 const float xm = (x0 + x1) / 2.0f;
1423 const float ym = (y0 + y1) / 2.0f;
1424
1425 if (cw)
1426 {
1427 geometryData.push_back(tcu::Vec3(x0, y0, z));
1428 geometryData.push_back(tcu::Vec3(x1, ym, z));
1429 geometryData.push_back(tcu::Vec3(xm, y1, z));
1430 }
1431 else
1432 {
1433 geometryData.push_back(tcu::Vec3(x0, y0, z));
1434 geometryData.push_back(tcu::Vec3(xm, y1, z));
1435 geometryData.push_back(tcu::Vec3(x1, ym, z));
1436 }
1437 }
1438 else
1439 {
1440 geometryData.push_back(tcu::Vec3(x0, y0, z));
1441 geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
1442 }
1443
1444 startPos.y() = m / m_data.width;
1445 startPos.x() = m % m_data.width;
1446 }
1447
1448 DE_ASSERT(startPos.y() == m_data.height && startPos.x() == 0);
1449
1450 result->addGeometry(geometryData, triangles, geometryFlags);
1451 }
1452 else if (m_data.id == TEST_ID_HIT_T_EXT ||
1453 m_data.id == TEST_ID_RAY_T_MIN_EXT ||
1454 m_data.id == TEST_ID_RAY_T_MAX_EXT )
1455 {
1456 const bool triangles = (m_data.geomType == GEOM_TYPE_TRIANGLES);
1457 const bool missShader = (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1458 const bool sectShader = (m_data.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR);
1459 const bool maxTTest = (m_data.id == TEST_ID_RAY_T_MAX_EXT);
1460
1461 DE_ASSERT(m_data.squaresGroupCount != 1);
1462
1463 for (size_t geometryNdx = 0; geometryNdx < m_data.geometriesGroupCount; ++geometryNdx)
1464 {
1465 std::vector<tcu::Vec3> geometryData;
1466
1467 geometryData.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1468
1469 for (size_t squareNdx = 0; squareNdx < m_data.squaresGroupCount; ++squareNdx)
1470 {
1471 const deUint32 n = m_data.width * startPos.y() + startPos.x();
1472 const deUint32 m = n + 1;
1473 const bool shiftRight = sectShader && maxTTest && (0 == (startPos.y() & 1)) && (0 == (startPos.x() & 1));
1474 const deUint32 xo = shiftRight ? 1 : 0;
1475 const float x0 = float(startPos.x() + 0 + xo) / float(m_data.width);
1476 const float y0 = float(startPos.y() + 0) / float(m_data.height);
1477 const float x1 = float(startPos.x() + 1 + xo) / float(m_data.width);
1478 const float y1 = float(startPos.y() + 1) / float(m_data.height);
1479 const float a = x0;
1480 const float b = 1.0f + y0;
1481 const float c = 0.03125f + 0.25f * a / b;
1482 const float z = !missShader ? -c : -100.0f;
1483
1484 if (triangles)
1485 {
1486 const float xm = (x0 + x1) / 2.0f;
1487 const float ym = (y0 + y1) / 2.0f;
1488
1489 geometryData.push_back(tcu::Vec3(x0, y0, z));
1490 geometryData.push_back(tcu::Vec3(xm, y1, z));
1491 geometryData.push_back(tcu::Vec3(x1, ym, z));
1492 }
1493 else
1494 {
1495 geometryData.push_back(tcu::Vec3(x0, y0, z));
1496 geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
1497 }
1498
1499 startPos.y() = m / m_data.width;
1500 startPos.x() = m % m_data.width;
1501 }
1502
1503 result->addGeometry(geometryData, triangles);
1504 }
1505 }
1506 else if (m_data.id == TEST_ID_WORLD_RAY_ORIGIN_EXT ||
1507 m_data.id == TEST_ID_WORLD_RAY_DIRECTION_EXT ||
1508 m_data.id == TEST_ID_OBJECT_RAY_ORIGIN_EXT ||
1509 m_data.id == TEST_ID_OBJECT_RAY_DIRECTION_EXT ||
1510 m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT ||
1511 m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT ||
1512 m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT ||
1513 m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT )
1514 {
1515 const bool triangles = m_data.geomType == GEOM_TYPE_TRIANGLES;
1516 const float y0 = float(startPos.y() + 0) / float(m_data.height);
1517 const float y1 = float(startPos.y() + 1) / float(m_data.height);
1518 const bool missShader = (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1519 const float z = !missShader ? -1.0f : -100.0f;
1520 std::vector<tcu::Vec3> geometryData;
1521
1522 if (triangles)
1523 {
1524 geometryData.push_back(tcu::Vec3(-1.0f, y1, z));
1525 geometryData.push_back(tcu::Vec3(-1.0f, y0, z));
1526 geometryData.push_back(tcu::Vec3(+1.0f, y0, z));
1527 geometryData.push_back(tcu::Vec3(-1.0f, y1, z));
1528 geometryData.push_back(tcu::Vec3(+1.0f, y0, z));
1529 geometryData.push_back(tcu::Vec3(+1.0f, y1, z));
1530 }
1531 else
1532 {
1533 geometryData.reserve(2);
1534
1535 geometryData.push_back(tcu::Vec3(-1.0f, y0, z));
1536 geometryData.push_back(tcu::Vec3(+1.0f, y1, z));
1537 }
1538
1539 DE_ASSERT(startPos.y() < m_data.height);
1540
1541 startPos.y()++;
1542
1543 result->addGeometry(geometryData, triangles);
1544 }
1545 else
1546 {
1547 TCU_THROW(InternalError, "Not implemented");
1548 }
1549
1550 result->createAndBuild(vkd, device, cmdBuffer, allocator);
1551
1552 return result;
1553 }
1554
initBottomAccelerationStructures(VkCommandBuffer cmdBuffer)1555 vector<de::SharedPtr<BottomLevelAccelerationStructure> > RayTracingBuiltinLaunchTestInstance::initBottomAccelerationStructures (VkCommandBuffer cmdBuffer)
1556 {
1557 tcu::UVec2 startPos;
1558 vector<de::SharedPtr<BottomLevelAccelerationStructure> > result;
1559
1560 for (size_t instanceNdx = 0; instanceNdx < m_data.instancesGroupCount; ++instanceNdx)
1561 {
1562 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = initBottomAccelerationStructure(cmdBuffer, startPos);
1563
1564 result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1565 }
1566
1567 return result;
1568 }
1569
makePipeline(de::MovePtr<RayTracingPipeline>& rayTracingPipeline, VkPipelineLayout pipelineLayout, const VkSpecializationInfo* specializationInfo)1570 Move<VkPipeline> RayTracingBuiltinLaunchTestInstance::makePipeline (de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
1571 VkPipelineLayout pipelineLayout,
1572 const VkSpecializationInfo* specializationInfo)
1573 {
1574 const DeviceInterface& vkd = m_context.getDeviceInterface();
1575 const VkDevice device = m_context.getDevice();
1576 vk::BinaryCollection& collection = m_context.getBinaryCollection();
1577
1578 if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR)) rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR , createShaderModule(vkd, device, collection.get("rgen"), 0), m_raygenShaderGroup, specializationInfo);
1579 if (0 != (m_shaders & VK_SHADER_STAGE_ANY_HIT_BIT_KHR)) rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR , createShaderModule(vkd, device, collection.get("ahit"), 0), m_hitShaderGroup, specializationInfo);
1580 if (0 != (m_shaders & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)) rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR , createShaderModule(vkd, device, collection.get("chit"), 0), m_hitShaderGroup, specializationInfo);
1581 if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR)) rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR , createShaderModule(vkd, device, collection.get("miss"), 0), m_missShaderGroup, specializationInfo);
1582 if (0 != (m_shaders & VK_SHADER_STAGE_INTERSECTION_BIT_KHR)) rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR , createShaderModule(vkd, device, collection.get("sect"), 0), m_hitShaderGroup, specializationInfo);
1583 if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR)) rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR , createShaderModule(vkd, device, collection.get("call"), 0), m_callableShaderGroup, specializationInfo);
1584
1585 if (m_data.pipelineCreateFlags != 0)
1586 {
1587 rayTracingPipeline->setCreateFlags(m_data.pipelineCreateFlags);
1588 if (m_data.useMaintenance5)
1589 rayTracingPipeline->setCreateFlags2(translateCreateFlag(m_data.pipelineCreateFlags));
1590 }
1591
1592 Move<VkPipeline> pipeline = rayTracingPipeline->createPipeline(vkd, device, pipelineLayout);
1593
1594 return pipeline;
1595 }
1596
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)1597 de::MovePtr<BufferWithMemory> RayTracingBuiltinLaunchTestInstance::createShaderBindingTable (const InstanceInterface& vki,
1598 const DeviceInterface& vkd,
1599 const VkDevice device,
1600 const VkPhysicalDevice physicalDevice,
1601 const VkPipeline pipeline,
1602 Allocator& allocator,
1603 de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
1604 const deUint32 group)
1605 {
1606 de::MovePtr<BufferWithMemory> shaderBindingTable;
1607
1608 if (group < m_shaderGroupCount)
1609 {
1610 const deUint32 shaderGroupHandleSize = getShaderGroupSize(vki, physicalDevice);
1611 const deUint32 shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice);
1612
1613 shaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, group, 1u);
1614 }
1615
1616 return shaderBindingTable;
1617 }
1618
1619 // Provides two spec constants, one integer and one float, both with value 256.
1620 class SpecConstantsHelper
1621 {
1622 public:
1623 SpecConstantsHelper ();
1624 const VkSpecializationInfo& getSpecializationInfo (void) const;
1625 private:
1626 std::vector<deUint8> m_data;
1627 std::vector<VkSpecializationMapEntry> m_mapEntries;
1628 VkSpecializationInfo m_specInfo;
1629 };
1630
SpecConstantsHelper()1631 SpecConstantsHelper::SpecConstantsHelper ()
1632 : m_data ()
1633 , m_mapEntries ()
1634 {
1635 // To make things interesting, make both data unaligned and add some padding.
1636 const deInt32 value1 = 256;
1637 const float value2 = 256.0f;
1638
1639 const size_t offset1 = 1u; // Offset of 1 byte.
1640 const size_t offset2 = 1u + sizeof(value1) + 2u; // Offset of 3 bytes plus the size of value1.
1641
1642 m_data.resize(sizeof(value1) + sizeof(value2) + 5u); // Some extra padding at the end too.
1643 deMemcpy(&m_data[offset1], &value1, sizeof(value1));
1644 deMemcpy(&m_data[offset2], &value2, sizeof(value2));
1645
1646 // Map entries.
1647 m_mapEntries.reserve(2u);
1648 m_mapEntries.push_back({ 0u, static_cast<deUint32>(offset1), static_cast<deUintptr>(sizeof(value1)) });
1649 m_mapEntries.push_back({ 1u, static_cast<deUint32>(offset2), static_cast<deUintptr>(sizeof(value2)) });
1650
1651 // Specialization info.
1652 m_specInfo.mapEntryCount = static_cast<deUint32>(m_mapEntries.size());
1653 m_specInfo.pMapEntries = m_mapEntries.data();
1654 m_specInfo.dataSize = static_cast<deUintptr>(m_data.size());
1655 m_specInfo.pData = m_data.data();
1656 }
1657
getSpecializationInfo(void) const1658 const VkSpecializationInfo& SpecConstantsHelper::getSpecializationInfo (void) const
1659 {
1660 return m_specInfo;
1661 }
1662
runTest(void)1663 de::MovePtr<BufferWithMemory> RayTracingBuiltinLaunchTestInstance::runTest (void)
1664 {
1665 const InstanceInterface& vki = m_context.getInstanceInterface();
1666 const DeviceInterface& vkd = m_context.getDeviceInterface();
1667 const VkDevice device = m_context.getDevice();
1668 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1669 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1670 const VkQueue queue = m_context.getUniversalQueue();
1671 Allocator& allocator = m_context.getDefaultAllocator();
1672 const deUint32 shaderGroupHandleSize = getShaderGroupSize(vki, physicalDevice);
1673 const VkFormat format = m_data.format;
1674 const deUint32 pixelSize = tcu::getPixelSize(mapVkFormat(format));
1675 const deUint32 pixelCount = m_data.width * m_data.height * m_data.depth;
1676
1677 const Move<VkDescriptorSetLayout> descriptorSetLayout = DescriptorSetLayoutBuilder()
1678 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
1679 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1680 .build(vkd, device);
1681 const Move<VkDescriptorPool> descriptorPool = DescriptorPoolBuilder()
1682 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1683 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1684 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1685 const Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
1686 const Move<VkPipelineLayout> pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
1687 const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
1688 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1689
1690 de::MovePtr<RayTracingPipeline> rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
1691 const SpecConstantsHelper specConstantHelper;
1692 const VkSpecializationInfo* specializationInfo = (m_data.useSpecConstants ? &specConstantHelper.getSpecializationInfo() : nullptr);
1693 const Move<VkPipeline> pipeline = makePipeline(rayTracingPipeline, *pipelineLayout, specializationInfo);
1694 const de::MovePtr<BufferWithMemory> raygenShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *pipeline, allocator, rayTracingPipeline, m_raygenShaderGroup);
1695 const de::MovePtr<BufferWithMemory> missShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *pipeline, allocator, rayTracingPipeline, m_missShaderGroup);
1696 const de::MovePtr<BufferWithMemory> hitShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *pipeline, allocator, rayTracingPipeline, m_hitShaderGroup);
1697 const de::MovePtr<BufferWithMemory> callableShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *pipeline, allocator, rayTracingPipeline, m_callableShaderGroup);
1698
1699 const VkStridedDeviceAddressRegionKHR raygenShaderBindingTableRegion = raygenShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1700 const VkStridedDeviceAddressRegionKHR missShaderBindingTableRegion = missShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1701 const VkStridedDeviceAddressRegionKHR hitShaderBindingTableRegion = hitShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1702 const VkStridedDeviceAddressRegionKHR callableShaderBindingTableRegion = callableShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1703
1704 const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_data.width, m_data.height, m_data.depth, format);
1705 const VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0, 1u);
1706 const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1707 const Move<VkImageView> imageView = makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, format, imageSubresourceRange);
1708
1709 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(pixelCount * pixelSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
1710 const VkImageSubresourceLayers bufferImageSubresourceLayers = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1711 const VkBufferImageCopy bufferImageRegion = makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, m_data.depth), bufferImageSubresourceLayers);
1712 de::MovePtr<BufferWithMemory> buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
1713
1714 const VkDescriptorImageInfo descriptorImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
1715
1716 const VkImageMemoryBarrier preImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
1717 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1718 **image, imageSubresourceRange);
1719 const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
1720 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1721 **image, imageSubresourceRange);
1722 const VkMemoryBarrier postTraceMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
1723 const VkMemoryBarrier postCopyMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
1724 const VkClearValue clearValue = makeClearValueColorU32(DEFAULT_UINT_CLEAR_VALUE, DEFAULT_UINT_CLEAR_VALUE, DEFAULT_UINT_CLEAR_VALUE, 255u);
1725
1726 vector<de::SharedPtr<BottomLevelAccelerationStructure> > bottomLevelAccelerationStructures;
1727 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure;
1728
1729 beginCommandBuffer(vkd, *cmdBuffer, 0u);
1730 {
1731 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
1732 vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
1733 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
1734
1735 bottomLevelAccelerationStructures = initBottomAccelerationStructures(*cmdBuffer);
1736 topLevelAccelerationStructure = initTopAccelerationStructure(*cmdBuffer, bottomLevelAccelerationStructures);
1737
1738 const TopLevelAccelerationStructure* topLevelAccelerationStructurePtr = topLevelAccelerationStructure.get();
1739 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
1740 {
1741 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
1742 DE_NULL, // const void* pNext;
1743 1u, // deUint32 accelerationStructureCount;
1744 topLevelAccelerationStructurePtr->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures;
1745 };
1746
1747 DescriptorSetUpdateBuilder()
1748 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
1749 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1750 .update(vkd, device);
1751
1752 vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
1753
1754 vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipeline);
1755
1756 cmdTraceRays(vkd,
1757 *cmdBuffer,
1758 &raygenShaderBindingTableRegion,
1759 &missShaderBindingTableRegion,
1760 &hitShaderBindingTableRegion,
1761 &callableShaderBindingTableRegion,
1762 m_data.width, m_data.height, m_data.raysDepth);
1763
1764 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier);
1765
1766 vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **buffer, 1u, &bufferImageRegion);
1767
1768 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
1769 }
1770 endCommandBuffer(vkd, *cmdBuffer);
1771
1772 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1773
1774 invalidateMappedMemoryRange(vkd, device, buffer->getAllocation().getMemory(), buffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
1775
1776 return buffer;
1777 }
1778
checkFormatSupported(Context& context, VkFormat format, VkImageUsageFlags usage, const VkExtent3D& extent)1779 void checkFormatSupported(Context& context, VkFormat format, VkImageUsageFlags usage, const VkExtent3D& extent)
1780 {
1781 VkResult result;
1782 VkImageFormatProperties properties;
1783
1784 result = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(), format, VK_IMAGE_TYPE_3D, VK_IMAGE_TILING_OPTIMAL, usage, 0, &properties);
1785
1786 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
1787 {
1788 std::ostringstream msg;
1789
1790 msg << "Format " << format << " not supported for usage flags 0x" << std::hex << usage;
1791
1792 TCU_THROW(NotSupportedError, msg.str());
1793 }
1794
1795 if (properties.maxExtent.width < extent.width || properties.maxExtent.height < extent.height || properties.maxExtent.depth < extent.depth)
1796 TCU_THROW(NotSupportedError, "Image size is too large for this format");
1797
1798 VK_CHECK(result);
1799 }
1800
checkSupportInInstance(void) const1801 void RayTracingBuiltinLaunchTestInstance::checkSupportInInstance (void) const
1802 {
1803 const InstanceInterface& vki = m_context.getInstanceInterface();
1804 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1805 const vk::VkPhysicalDeviceProperties& properties = m_context.getDeviceProperties();
1806 const deUint32 requiredAllocations = 8u
1807 + TopLevelAccelerationStructure::getRequiredAllocationCount()
1808 + m_data.instancesGroupCount * BottomLevelAccelerationStructure::getRequiredAllocationCount();
1809 const de::MovePtr<RayTracingProperties> rayTracingProperties = makeRayTracingProperties(vki, physicalDevice);
1810 const VkExtent3D extent = makeExtent3D(m_data.width, m_data.height, m_data.depth);
1811
1812 checkFormatSupported(m_context, m_data.format, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, extent);
1813
1814 if (rayTracingProperties->getMaxPrimitiveCount() < 2 * m_data.squaresGroupCount)
1815 TCU_THROW(NotSupportedError, "Triangles required more than supported");
1816
1817 if (rayTracingProperties->getMaxGeometryCount() < m_data.geometriesGroupCount)
1818 TCU_THROW(NotSupportedError, "Geometries required more than supported");
1819
1820 if (rayTracingProperties->getMaxInstanceCount() < m_data.instancesGroupCount)
1821 TCU_THROW(NotSupportedError, "Instances required more than supported");
1822
1823 if (properties.limits.maxMemoryAllocationCount < requiredAllocations)
1824 TCU_THROW(NotSupportedError, "Test requires more allocations allowed");
1825 }
1826
expectedIntValuesBuffer(void)1827 std::vector<deInt32> RayTracingBuiltinLaunchTestInstance::expectedIntValuesBuffer (void)
1828 {
1829 deUint32 pos = 0;
1830 std::vector<deInt32> result;
1831
1832 result.reserve(m_data.depth * m_data.height * m_data.width);
1833
1834 if (m_data.id == TEST_ID_LAUNCH_ID_EXT)
1835 {
1836 for (deUint32 z = 0; z < m_data.depth; ++z)
1837 for (deUint32 y = 0; y < m_data.height; ++y)
1838 for (deUint32 x = 0; x < m_data.width; ++x)
1839 result.push_back(deInt32(x + 256 * (y + 256 * z)) + 1);
1840 }
1841 else if (m_data.id == TEST_ID_LAUNCH_SIZE_EXT)
1842 {
1843 const deUint32 expectedValue = m_data.width + 256 * (m_data.height + 256 * m_data.depth);
1844 const std::vector<deInt32> result2 (m_data.depth * m_data.height * m_data.width, deInt32(expectedValue) + 1);
1845
1846 result = result2;
1847 }
1848 else if (m_data.id == TEST_ID_GEOMETRY_INDEX_EXT)
1849 {
1850 for (deUint32 z = 0; z < m_data.depth; ++z)
1851 for (deUint32 y = 0; y < m_data.height; ++y)
1852 for (deUint32 x = 0; x < m_data.width; ++x)
1853 result.push_back(deInt32((pos++ / m_data.squaresGroupCount) % m_data.geometriesGroupCount));
1854 }
1855 else if (m_data.id == TEST_ID_PRIMITIVE_ID)
1856 {
1857 for (deUint32 z = 0; z < m_data.depth; ++z)
1858 for (deUint32 y = 0; y < m_data.height; ++y)
1859 for (deUint32 x = 0; x < m_data.width; ++x)
1860 result.push_back(deInt32(pos++ % m_data.squaresGroupCount));
1861 }
1862 else if (m_data.id == TEST_ID_INSTANCE_ID)
1863 {
1864 for (deUint32 z = 0; z < m_data.depth; ++z)
1865 for (deUint32 y = 0; y < m_data.height; ++y)
1866 for (deUint32 x = 0; x < m_data.width; ++x)
1867 result.push_back(deInt32(pos++ / (m_data.squaresGroupCount * m_data.geometriesGroupCount)));
1868 }
1869 else if (m_data.id == TEST_ID_INSTANCE_CUSTOM_INDEX_EXT)
1870 {
1871 for (deUint32 z = 0; z < m_data.depth; ++z)
1872 for (deUint32 y = 0; y < m_data.height; ++y)
1873 for (deUint32 x = 0; x < m_data.width; ++x)
1874 result.push_back(deInt32(2 * (pos++ / (m_data.squaresGroupCount * m_data.geometriesGroupCount))));
1875 }
1876 else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_EXT)
1877 {
1878 DE_ASSERT(m_data.squaresGroupCount == (1<<RAY_FLAG_BIT_LAST_PER_TEST));
1879 DE_ASSERT(DEFAULT_UINT_CLEAR_VALUE != (1<<RAY_FLAG_BIT_LAST_PER_TEST));
1880
1881 for (deUint32 z = 0; z < m_data.depth; ++z)
1882 for (deUint32 y = 0; y < m_data.height; ++y)
1883 for (deUint32 x = 0; x < m_data.width; ++x)
1884 {
1885 const deUint32 n = x + m_data.width * (y + m_data.height * z);
1886 const bool rayOpaque = (0 != (n & (1<<RAY_FLAG_BIT_OPAQUE_EXT )));
1887 const bool rayNoOpaque = (0 != (n & (1<<RAY_FLAG_BIT_NO_OPAQUE_EXT ))) && !rayOpaque;
1888 const bool rayTerminateOnFirstHit = (0 != (n & (1<<RAY_FLAG_BIT_TERMINATE_ON_FIRST_HIT_EXT )));
1889 const bool raySkipClosestHitShader = (0 != (n & (1<<RAY_FLAG_BIT_SKIP_CLOSEST_HIT_SHADER_EXT )));
1890 const bool rayCullBack = (0 != (n & (1<<RAY_FLAG_BIT_CULL_BACK_FACING_TRIANGLES_EXT )));
1891 const bool rayCullFront = (0 != (n & (1<<RAY_FLAG_BIT_CULL_FRONT_FACING_TRIANGLES_EXT))) && !rayCullBack;
1892 const bool rayCullOpaque = (0 != (n & (1<<RAY_FLAG_BIT_CULL_OPAQUE_EXT ))) && !rayOpaque && !rayNoOpaque;
1893 const bool rayCullNoOpaque = (0 != (n & (1<<RAY_FLAG_BIT_CULL_NO_OPAQUE_EXT ))) && !rayOpaque && !rayNoOpaque && !rayCullOpaque;
1894 const bool raySkipTriangles = m_data.rayFlagSkipTriangles;
1895 const bool raySkipAABBs = m_data.rayFlagSkipAABSs;
1896 const bool pipelineSkipTriangles = (m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR) != 0;
1897 const bool pipelineSkipAABBs = (m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR) != 0;
1898 const bool cullingTest = m_data.rayFlagSkipTriangles || m_data.rayFlagSkipAABSs || pipelineSkipTriangles || pipelineSkipAABBs;
1899 const bool geometryFrontFace = m_data.frontFace;
1900 const bool geometryOpaque = m_data.opaque;
1901 const bool geometryTriangles = (m_data.geomType == GEOM_TYPE_TRIANGLES) ? true : false;
1902 const bool geometryAABBs = (m_data.geomType == GEOM_TYPE_AABBS) ? true : false;
1903 deUint32 v = 0
1904 | (rayOpaque ? (1<<RAY_FLAG_BIT_OPAQUE_EXT ) : 0)
1905 | (rayNoOpaque ? (1<<RAY_FLAG_BIT_NO_OPAQUE_EXT ) : 0)
1906 | (rayTerminateOnFirstHit ? (1<<RAY_FLAG_BIT_TERMINATE_ON_FIRST_HIT_EXT ) : 0)
1907 | (raySkipClosestHitShader ? (1<<RAY_FLAG_BIT_SKIP_CLOSEST_HIT_SHADER_EXT ) : 0)
1908 | (rayCullBack ? (1<<RAY_FLAG_BIT_CULL_BACK_FACING_TRIANGLES_EXT ) : 0)
1909 | (rayCullFront ? (1<<RAY_FLAG_BIT_CULL_FRONT_FACING_TRIANGLES_EXT) : 0)
1910 | (rayCullOpaque ? (1<<RAY_FLAG_BIT_CULL_OPAQUE_EXT ) : 0)
1911 | (rayCullNoOpaque ? (1<<RAY_FLAG_BIT_CULL_NO_OPAQUE_EXT ) : 0)
1912 | (raySkipTriangles ? (1<<RAY_FLAG_BIT_SKIP_TRIANGLES_EXT ) : 0)
1913 | (raySkipAABBs ? (1<<RAY_FLAG_BIT_SKIP_AABB_EXT ) : 0);
1914
1915 if (m_data.stage == VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR && raySkipClosestHitShader)
1916 v = DEFAULT_UINT_CLEAR_VALUE;
1917
1918 if (m_data.stage == VK_SHADER_STAGE_ANY_HIT_BIT_KHR && (rayOpaque || (geometryOpaque && !rayOpaque && !rayNoOpaque)))
1919 v = DEFAULT_UINT_CLEAR_VALUE;
1920
1921 if (geometryOpaque)
1922 {
1923 if (rayCullOpaque)
1924 if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1925 v = DEFAULT_UINT_CLEAR_VALUE;
1926 }
1927 else
1928 {
1929 if (rayCullNoOpaque)
1930 if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1931 v = DEFAULT_UINT_CLEAR_VALUE;
1932 }
1933
1934 if (geometryTriangles)
1935 {
1936 if (geometryFrontFace)
1937 {
1938 if (rayCullFront)
1939 if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1940 v = DEFAULT_UINT_CLEAR_VALUE;
1941 }
1942 else
1943 {
1944 if (rayCullBack)
1945 if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1946 v = DEFAULT_UINT_CLEAR_VALUE;
1947 }
1948 }
1949
1950 if (cullingTest)
1951 {
1952 if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1953 {
1954 if (geometryTriangles)
1955 {
1956 if (raySkipTriangles || pipelineSkipTriangles)
1957 v = DEFAULT_UINT_CLEAR_VALUE;
1958 }
1959
1960 if (geometryAABBs)
1961 {
1962 if (raySkipAABBs || pipelineSkipAABBs)
1963 v = DEFAULT_UINT_CLEAR_VALUE;
1964 }
1965 }
1966 }
1967
1968 result.push_back(deInt32(v));
1969 }
1970 }
1971 else if (m_data.id == TEST_ID_HIT_KIND_EXT)
1972 {
1973 for (deUint32 z = 0; z < m_data.depth; ++z)
1974 for (deUint32 y = 0; y < m_data.height; ++y)
1975 for (deUint32 x = 0; x < m_data.width; ++x)
1976 {
1977 const deUint32 n = x + m_data.width * (y + m_data.height * z);
1978 const deUint32 geometryNdx = n / m_data.squaresGroupCount;
1979 const deUint32 hitKind = ((geometryNdx & 1) == 0) ? 0xFEu : 0xFFu;
1980 const bool geometryOpaque = ((geometryNdx & 2) == 0) ? true : false;
1981 deUint32 v = (m_data.geomType == GEOM_TYPE_TRIANGLES) ? hitKind : 0x7Eu;
1982
1983 if (m_data.stage == VK_SHADER_STAGE_ANY_HIT_BIT_KHR && geometryOpaque)
1984 v = DEFAULT_UINT_CLEAR_VALUE;
1985
1986 result.push_back(deInt32(v));
1987 }
1988 }
1989 else
1990 {
1991 TCU_THROW(InternalError, "Not implemented");
1992 }
1993
1994 return result;
1995 }
1996
expectedFloatValuesBuffer(void)1997 std::vector<float> RayTracingBuiltinLaunchTestInstance::expectedFloatValuesBuffer (void)
1998 {
1999 std::vector<float> result;
2000
2001 result.reserve(m_data.depth * m_data.height * m_data.width);
2002
2003 if (m_data.id == TEST_ID_HIT_T_EXT)
2004 {
2005 for (deUint32 z = 0; z < m_data.depth; ++z)
2006 for (deUint32 y = 0; y < m_data.height; ++y)
2007 for (deUint32 x = 0; x < m_data.width; ++x)
2008 {
2009 const float a = float(x) / float(m_data.width);
2010 const float b = 1.0f + float(y) / float(m_data.height);
2011 const float f = 0.03125f + 0.25f * a / b;
2012
2013 result.push_back(f);
2014 }
2015 }
2016 else if (m_data.id == TEST_ID_RAY_T_MIN_EXT)
2017 {
2018 for (deUint32 z = 0; z < m_data.depth; ++z)
2019 for (deUint32 y = 0; y < m_data.height; ++y)
2020 for (deUint32 x = 0; x < m_data.width; ++x)
2021 {
2022 const float a = float(x) / float(m_data.width);
2023 const float b = 1.0f + float(y) / float(m_data.height);
2024 const float f = 0.25f * a / b;
2025
2026 result.push_back(f);
2027 }
2028 }
2029 else if (m_data.id == TEST_ID_RAY_T_MAX_EXT)
2030 {
2031 for (deUint32 z = 0; z < m_data.depth; ++z)
2032 for (deUint32 y = 0; y < m_data.height; ++y)
2033 for (deUint32 x = 0; x < m_data.width; ++x)
2034 {
2035 const float a = float(x) / float(m_data.width);
2036 const float b = 1.0f + float(y) / float(m_data.height);
2037 const float c = 0.25f * a / b;
2038 // In a miss shader, the value is identical to the parameter passed into traceRayEXT().
2039 const float m = 0.75f + c;
2040 // In the closest-hit shader, the value reflects the closest distance to the intersected primitive.
2041 // In the any-hit shader, it reflects the distance to the primitive currently being intersected.
2042 // In the intersection shader, it reflects the distance to the closest primitive intersected so far.
2043 const float n = 0.03125f + c;
2044 const bool normalRow = (y & 1) != 0;
2045 const bool doublePrimitive = (x & 1) != 0;
2046 const float s = normalRow ? m
2047 : doublePrimitive ? 0.4375f + c
2048 : float(DEFAULT_UINT_CLEAR_VALUE) / float(FIXED_POINT_DIVISOR);
2049 const float f = (m_data.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR) ? s
2050 : (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR) ? m
2051 : n;
2052
2053 result.push_back(f);
2054 }
2055 }
2056 else
2057 {
2058 TCU_THROW(InternalError, "Not implemented");
2059 }
2060
2061 return result;
2062 }
2063
expectedVectorValuesBuffer(void)2064 std::vector<float> RayTracingBuiltinLaunchTestInstance::expectedVectorValuesBuffer (void)
2065 {
2066 const deUint32 imageDepth = 4;
2067 const deUint32 expectedFloats = imageDepth * m_data.height * m_data.width;
2068 std::vector<float> result (expectedFloats, float(DEFAULT_UINT_CLEAR_VALUE) / float(FIXED_POINT_DIVISOR));
2069
2070 if (m_data.id == TEST_ID_WORLD_RAY_ORIGIN_EXT)
2071 {
2072 deUint32 pos = 0;
2073
2074 for (deUint32 y = 0; y < m_data.height; ++y)
2075 for (deUint32 x = 0; x < m_data.width; ++x)
2076 result[pos++] = (0.5f + float(x)) / float(m_data.width);
2077
2078 for (deUint32 y = 0; y < m_data.height; ++y)
2079 for (deUint32 x = 0; x < m_data.width; ++x)
2080 result[pos++] = (0.5f + float(y)) / float(m_data.height);
2081
2082 for (deUint32 y = 0; y < m_data.height; ++y)
2083 for (deUint32 x = 0; x < m_data.width; ++x)
2084 result[pos++] = 0.0f;
2085 }
2086 else if (m_data.id == TEST_ID_WORLD_RAY_DIRECTION_EXT)
2087 {
2088 deUint32 pos = 0;
2089
2090 for (deUint32 y = 0; y < m_data.height; ++y)
2091 for (deUint32 x = 0; x < m_data.width; ++x)
2092 result[pos++] = 0.0f;
2093
2094 for (deUint32 y = 0; y < m_data.height; ++y)
2095 for (deUint32 x = 0; x < m_data.width; ++x)
2096 result[pos++] = 0.0f;
2097
2098 for (deUint32 y = 0; y < m_data.height; ++y)
2099 for (deUint32 x = 0; x < m_data.width; ++x)
2100 result[pos++] = -1.0f;
2101 }
2102 else if (m_data.id == TEST_ID_OBJECT_RAY_ORIGIN_EXT)
2103 {
2104 deUint32 pos = 0;
2105
2106 for (deUint32 y = 0; y < m_data.height; ++y)
2107 for (deUint32 x = 0; x < m_data.width; ++x)
2108 {
2109 const deUint32 instanceId = y / (m_data.height / m_data.instancesGroupCount);
2110 const float offset = (instanceId & 1) ? 1.0f / 8.0f : 0.0f;
2111
2112 result[pos++] = (0.5f + float(x) - offset) / float(m_data.width);
2113 }
2114
2115 for (deUint32 y = 0; y < m_data.height; ++y)
2116 for (deUint32 x = 0; x < m_data.width; ++x)
2117 {
2118 const deUint32 instanceId = y / (m_data.height / m_data.instancesGroupCount);
2119 const float offset = (instanceId & 2) ? 1.0f / 16.0f : 0.0f;
2120
2121 result[pos++] = (0.5f + float(y) - offset) / float(m_data.height);
2122 }
2123
2124 for (deUint32 y = 0; y < m_data.height; ++y)
2125 for (deUint32 x = 0; x < m_data.width; ++x)
2126 result[pos++] = 0.0f;
2127 }
2128 else if (m_data.id == TEST_ID_OBJECT_RAY_DIRECTION_EXT)
2129 {
2130 deUint32 pos = 0;
2131
2132 for (deUint32 y = 0; y < m_data.height; ++y)
2133 for (deUint32 x = 0; x < m_data.width; ++x)
2134 result[pos++] = 0.0f;
2135
2136 for (deUint32 y = 0; y < m_data.height; ++y)
2137 for (deUint32 x = 0; x < m_data.width; ++x)
2138 result[pos++] = 0.0f;
2139
2140 for (deUint32 y = 0; y < m_data.height; ++y)
2141 for (deUint32 x = 0; x < m_data.width; ++x)
2142 result[pos++] = -1.0f;
2143 }
2144 else
2145 {
2146 TCU_THROW(InternalError, "Not implemented");
2147 }
2148
2149 return result;
2150 }
2151
expectedMatrixValuesBuffer(void)2152 std::vector<float> RayTracingBuiltinLaunchTestInstance::expectedMatrixValuesBuffer (void)
2153 {
2154 const deUint32 colCount = 4;
2155 const deUint32 rowCount = 3;
2156 const deUint32 imageDepth = 4 * 4;
2157 const deUint32 zStride = m_data.height * m_data.width;
2158 const deUint32 expectedFloats = imageDepth * m_data.height * m_data.width;
2159 std::vector<float> result (expectedFloats, float(DEFAULT_UINT_CLEAR_VALUE) / float(FIXED_POINT_DIVISOR));
2160
2161 if (m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT ||
2162 m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT ||
2163 m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT ||
2164 m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT)
2165 {
2166 const int translateColumnNumber = 3;
2167 const float translateSign = (m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT || m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT) ? -1.0f : +1.0f;
2168 const float translateX = translateSign * (1.0f / 8.0f) / float(m_data.width);
2169 const float translateY = translateSign * (1.0f / 16.0f) / float(m_data.height);
2170
2171 for (deUint32 y = 0; y < m_data.height; ++y)
2172 {
2173 const deUint32 instanceId = y / (m_data.height / m_data.instancesGroupCount);
2174
2175 for (deUint32 x = 0; x < m_data.width; ++x)
2176 {
2177 tcu::Matrix<float, rowCount, colCount> m;
2178 const deUint32 elem0Pos = x + m_data.width * y;
2179
2180 if (instanceId & 1)
2181 m[translateColumnNumber][0] = translateX;
2182
2183 if (instanceId & 2)
2184 m[translateColumnNumber][1] = translateY;
2185
2186 for (deUint32 rowNdx = 0; rowNdx < rowCount; ++rowNdx)
2187 for (deUint32 colNdx = 0; colNdx < colCount; ++colNdx)
2188 {
2189 const deUint32 z = rowNdx * colCount + colNdx;
2190 const deUint32 pos = elem0Pos + zStride * z;
2191
2192 result[pos] = m[colNdx][rowNdx];
2193 }
2194 }
2195 }
2196 }
2197 else
2198 {
2199 TCU_THROW(InternalError, "Not implemented");
2200 }
2201
2202 return result;
2203 }
2204
validateIntBuffer(de::MovePtr<BufferWithMemory> buffer)2205 bool RayTracingBuiltinLaunchTestInstance::validateIntBuffer (de::MovePtr<BufferWithMemory> buffer)
2206 {
2207 const deInt32* bufferPtr = (deInt32*)buffer->getAllocation().getHostPtr();
2208 const vector<deInt32> expectedValues = expectedIntValuesBuffer();
2209 tcu::TestLog& log = m_context.getTestContext().getLog();
2210 deUint32 failures = 0;
2211 deUint32 pos = 0;
2212
2213 for (deUint32 z = 0; z < m_data.depth; ++z)
2214 for (deUint32 y = 0; y < m_data.height; ++y)
2215 for (deUint32 x = 0; x < m_data.width; ++x)
2216 {
2217 if (bufferPtr[pos] != expectedValues[pos])
2218 failures++;
2219
2220 ++pos;
2221 }
2222
2223 if (failures != 0)
2224 {
2225 const char * names[] = { "Retrieved:", "Expected:" };
2226 for (deUint32 n = 0; n < 2; ++n)
2227 {
2228 const deInt32* loggedData = (n == 0) ? bufferPtr : expectedValues.data();
2229 std::stringstream css;
2230
2231 pos = 0;
2232
2233 for (deUint32 z = 0; z < m_data.depth; ++z)
2234 for (deUint32 y = 0; y < m_data.height; ++y)
2235 {
2236 for (deUint32 x = 0; x < m_data.width; ++x)
2237 {
2238 if (bufferPtr[pos] == expectedValues[pos])
2239 css << "____,";
2240 else
2241 css << std::hex << std::setw(4) << loggedData[pos] << ",";
2242
2243 pos++;
2244 }
2245
2246 css << std::endl;
2247 }
2248
2249 log << tcu::TestLog::Message << names[n] << tcu::TestLog::EndMessage;
2250 log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
2251 }
2252 }
2253
2254 return failures == 0;
2255 }
2256
validateFloatBuffer(de::MovePtr<BufferWithMemory> buffer)2257 bool RayTracingBuiltinLaunchTestInstance::validateFloatBuffer (de::MovePtr<BufferWithMemory> buffer)
2258 {
2259 const float eps = float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
2260 const deInt32* bufferPtr = (deInt32*)buffer->getAllocation().getHostPtr();
2261 const vector<float> expectedValues = expectedFloatValuesBuffer();
2262 tcu::TestLog& log = m_context.getTestContext().getLog();
2263 deUint32 failures = 0;
2264 deUint32 pos = 0;
2265
2266 for (deUint32 z = 0; z < m_data.depth; ++z)
2267 for (deUint32 y = 0; y < m_data.height; ++y)
2268 for (deUint32 x = 0; x < m_data.width; ++x)
2269 {
2270 const float retrievedValue = float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2271
2272 if (deFloatAbs(retrievedValue - expectedValues[pos]) > eps)
2273 failures++;
2274
2275 ++pos;
2276 }
2277
2278 if (failures != 0)
2279 {
2280 const char * names[] = { "Retrieved:", "Expected:" };
2281
2282 for (deUint32 n = 0; n < 2; ++n)
2283 {
2284 std::stringstream css;
2285
2286 pos = 0;
2287
2288 for (deUint32 z = 0; z < m_data.depth; ++z)
2289 for (deUint32 y = 0; y < m_data.height; ++y)
2290 {
2291 for (deUint32 x = 0; x < m_data.width; ++x)
2292 {
2293 const float retrievedValue = float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2294 const float expectedValue = expectedValues[pos];
2295
2296 if (deFloatAbs(retrievedValue - expectedValue) > eps)
2297 css << std::setprecision(8) << std::setw(12) << (n == 0 ? retrievedValue : expectedValue) << ",";
2298 else
2299 css << "____________,";
2300
2301 pos++;
2302 }
2303
2304 css << std::endl;
2305 }
2306
2307 log << tcu::TestLog::Message << names[n] << tcu::TestLog::EndMessage;
2308 log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
2309 }
2310 }
2311
2312 return failures == 0;
2313 }
2314
validateVectorBuffer(de::MovePtr<BufferWithMemory> buffer)2315 bool RayTracingBuiltinLaunchTestInstance::validateVectorBuffer (de::MovePtr<BufferWithMemory> buffer)
2316 {
2317 const float eps = float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
2318 const deInt32* bufferPtr = (deInt32*)buffer->getAllocation().getHostPtr();
2319 const vector<float> expectedValues = expectedVectorValuesBuffer();
2320 const deUint32 depth = 3u; // vec3
2321 tcu::TestLog& log = m_context.getTestContext().getLog();
2322 deUint32 failures = 0;
2323 deUint32 pos = 0;
2324
2325 DE_ASSERT(depth <= m_data.depth);
2326
2327 for (deUint32 z = 0; z < depth; ++z)
2328 for (deUint32 y = 0; y < m_data.height; ++y)
2329 for (deUint32 x = 0; x < m_data.width; ++x)
2330 {
2331 const float retrievedValue = float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2332
2333 if (deFloatAbs(retrievedValue - expectedValues[pos]) > eps)
2334 failures++;
2335
2336 ++pos;
2337 }
2338
2339 if (failures != 0)
2340 {
2341 const char* names[] = { "Retrieved", "Expected " };
2342 std::stringstream css;
2343
2344 for (deUint32 y = 0; y < m_data.height; ++y)
2345 {
2346 for (deUint32 x = 0; x < m_data.width; ++x)
2347 {
2348 for (deUint32 n = 0; n < 2; ++n)
2349 {
2350 css << names[n] << " at (" << x << "," << y << ") {";
2351
2352 for (deUint32 z = 0; z < depth; ++z)
2353 {
2354 pos = x + m_data.width * (y + m_data.height * z);
2355
2356 const float retrievedValue = float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2357 const float expectedValue = expectedValues[pos];
2358
2359 if (deFloatAbs(retrievedValue - expectedValue) > eps)
2360 css << std::setprecision(8) << std::setw(12) << (n == 0 ? retrievedValue : expectedValue) << ",";
2361 else
2362 css << "____________,";
2363 }
2364
2365 css << "}" << std::endl;
2366 }
2367 }
2368 }
2369
2370 log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
2371 }
2372
2373 return failures == 0;
2374 }
2375
validateMatrixBuffer(de::MovePtr<BufferWithMemory> buffer)2376 bool RayTracingBuiltinLaunchTestInstance::validateMatrixBuffer (de::MovePtr<BufferWithMemory> buffer)
2377 {
2378 const float eps = float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
2379 const deInt32* bufferPtr = (deInt32*)buffer->getAllocation().getHostPtr();
2380 const vector<float> expectedValues = expectedMatrixValuesBuffer();
2381 const deUint32 depth = 12u; // mat3x4 or mat4x3
2382 tcu::TestLog& log = m_context.getTestContext().getLog();
2383 deUint32 failures = 0;
2384 deUint32 pos = 0;
2385
2386 DE_ASSERT(depth <= m_data.depth);
2387
2388 for (deUint32 z = 0; z < depth; ++z)
2389 for (deUint32 y = 0; y < m_data.height; ++y)
2390 for (deUint32 x = 0; x < m_data.width; ++x)
2391 {
2392 const float retrievedValue = float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2393
2394 if (deFloatAbs(retrievedValue - expectedValues[pos]) > eps)
2395 failures++;
2396
2397 ++pos;
2398 }
2399
2400 if (failures != 0)
2401 {
2402 const char* names[] = { "Retrieved", "Expected" };
2403 std::stringstream css;
2404
2405 for (deUint32 y = 0; y < m_data.height; ++y)
2406 {
2407 for (deUint32 x = 0; x < m_data.width; ++x)
2408 {
2409 css << "At (" << x << "," << y << ")" << std::endl;
2410 for (deUint32 n = 0; n < 2; ++n)
2411 {
2412 css << names[n] << std::endl << "{" << std::endl;
2413
2414 for (deUint32 z = 0; z < depth; ++z)
2415 {
2416 pos = x + m_data.width * (y + m_data.height * z);
2417
2418 const float retrievedValue = float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2419 const float expectedValue = expectedValues[pos];
2420
2421 if (z % 4 == 0)
2422 css << " {";
2423
2424 if (deFloatAbs(retrievedValue - expectedValue) > eps)
2425 css << std::setprecision(5) << std::setw(9) << (n == 0 ? retrievedValue : expectedValue) << ",";
2426 else
2427 css << "_________,";
2428
2429 if (z % 4 == 3)
2430 css << "}" << std::endl;
2431 }
2432
2433 css << "}" << std::endl;
2434 }
2435 }
2436 }
2437
2438 log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
2439 }
2440
2441 return failures == 0;
2442 }
2443
iterate(void)2444 tcu::TestStatus RayTracingBuiltinLaunchTestInstance::iterate (void)
2445 {
2446 checkSupportInInstance();
2447
2448 de::MovePtr<BufferWithMemory> buffer = runTest();
2449 const bool ok = m_data.fixedPointMatrixOutput ? validateMatrixBuffer(buffer)
2450 : m_data.fixedPointVectorOutput ? validateVectorBuffer(buffer)
2451 : m_data.fixedPointScalarOutput ? validateFloatBuffer(buffer)
2452 : validateIntBuffer(buffer);
2453
2454 if (ok)
2455 return tcu::TestStatus::pass("pass");
2456 else
2457 return tcu::TestStatus::fail("fail");
2458 }
2459
2460 enum ShaderSourceFlag
2461 {
2462 DEFINE_RAY = 0x1,
2463 DEFINE_RESULT_BUFFER = 0x2,
2464 DEFINE_SCENE = 0x4,
2465 DEFINE_RAY_BUFFER = 0x8,
2466 DEFINE_SIMPLE_BINDINGS = DEFINE_RESULT_BUFFER | DEFINE_SCENE | DEFINE_RAY_BUFFER
2467 };
2468
generateShaderSource(const char* body, const char* resultType = �, deUint32 flags = 0, const char* prefix = �)2469 std::string generateShaderSource(const char* body, const char* resultType = "", deUint32 flags = 0, const char* prefix = "")
2470 {
2471 std::ostringstream src;
2472 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n";
2473
2474 src << "#extension GL_EXT_ray_tracing : enable\n";
2475
2476 src << prefix << "\n";
2477
2478 if (flags & DEFINE_SIMPLE_BINDINGS)
2479 flags |= DEFINE_RAY_BUFFER;
2480
2481 if (flags & DEFINE_RAY_BUFFER)
2482 flags |= DEFINE_RAY;
2483
2484 if (flags & DEFINE_RAY)
2485 {
2486 src << "struct Ray { vec3 pos; float tmin; vec3 dir; float tmax; };\n";
2487 }
2488
2489 if (flags & DEFINE_RESULT_BUFFER)
2490 src << "layout(std430, set = 0, binding = " << 0 << ") buffer Results { " << resultType << " results[]; };\n";
2491
2492 if (flags & DEFINE_SCENE)
2493 {
2494 src << "layout(set = 0, binding = " << 1 << ") uniform accelerationStructureEXT scene;\n";
2495 }
2496
2497 if (flags & DEFINE_RAY_BUFFER)
2498 src << "layout(std430, set = 0, binding = " << 2 << ") buffer Rays { Ray rays[]; };\n";
2499
2500 src << "uint launchIndex() { return gl_LaunchIDEXT.z*gl_LaunchSizeEXT.x*gl_LaunchSizeEXT.y + gl_LaunchIDEXT.y*gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x; }\n";
2501
2502 src << body;
2503
2504 return src.str();
2505 }
2506
getShaderIdentifier(const CaseDef& params, VkShaderStageFlagBits stage)2507 std::string getShaderIdentifier(const CaseDef& params, VkShaderStageFlagBits stage)
2508 {
2509 std::string testStage;
2510
2511 switch (params.stage)
2512 {
2513 case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2514 testStage = "raygen";
2515 break;
2516 case VK_SHADER_STAGE_MISS_BIT_KHR:
2517 testStage = "-miss";
2518 break;
2519 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2520 testStage = "-closest-hit";
2521 break;
2522 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2523 testStage = "-any_hit";
2524 break;
2525 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2526 testStage = "-closest_hit";
2527 break;
2528 case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2529 testStage = "-callable";
2530 break;
2531 default:
2532 DE_ASSERT(false);
2533 return std::string();
2534 }
2535
2536 switch (stage)
2537 {
2538 case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2539 return testStage + "-rgen";
2540 case VK_SHADER_STAGE_MISS_BIT_KHR:
2541 return testStage + "-miss";
2542 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2543 return testStage + "-closest_hit";
2544 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2545 return testStage + "-any_hit";
2546 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2547 return testStage + "-isect";
2548 case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2549 return testStage + "-callable";
2550 default:
2551 DE_ASSERT(false);
2552 return std::string();
2553 }
2554 }
2555
replaceString(std::string text, const std::string& search, const std::string& replace)2556 std::string replaceString(std::string text, const std::string& search, const std::string& replace)
2557 {
2558 size_t found;
2559
2560 while ((found = text.find(search)) != std::string::npos)
2561 {
2562 text = text.replace(found, search.length(), replace);
2563 }
2564
2565 return text;
2566 }
2567
addBuiltInShaderSource(SourceCollections& programCollection, VkShaderStageFlagBits stage, const std::string& body, const CaseDef& params, std::string builtInType)2568 template<typename T> inline void addBuiltInShaderSource(SourceCollections& programCollection,
2569 VkShaderStageFlagBits stage,
2570 const std::string& body,
2571 const CaseDef& params,
2572 std::string builtInType)
2573 {
2574 std::string identifier = getShaderIdentifier(params, stage);
2575
2576 deUint32 flags = 0;
2577
2578 if (stage == VK_SHADER_STAGE_RAYGEN_BIT_KHR)
2579 flags |= DEFINE_RAY | DEFINE_SIMPLE_BINDINGS;
2580
2581 std::string text = generateShaderSource(body.c_str(), builtInType.c_str(), flags, "");
2582
2583 text = replaceString(text, "$builtInType$", builtInType);
2584
2585 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0, true);
2586 programCollection.glslSources.add(identifier) << T(text) << buildOptions;
2587 }
2588
2589 class RayTracingIndirectTestInstance : public TestInstance
2590 {
2591 public:
2592 RayTracingIndirectTestInstance (Context& context, const CaseDef& data);
2593 ~RayTracingIndirectTestInstance (void);
2594 tcu::TestStatus iterate (void);
2595
2596 private:
2597 void checkSupportInInstance (void) const;
2598 Move<VkPipeline> createPipelineAndShaderBindingTables (de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
2599 bool aabb,
2600 VkPipelineLayout pipelineLayout);
2601
2602 void createPipelineLayoutAndSet (deUint32 setCount,
2603 vk::Move<VkDescriptorPool>& descriptorPool,
2604 vk::Move<VkDescriptorSetLayout>& descriptorSetLayout,
2605 std::vector<vk::Move<VkDescriptorSet>>& descriptorSets,
2606 vk::Move<VkPipelineLayout>& pipelineLayout);
2607
2608 de::SharedPtr<TopLevelAccelerationStructure> initTopAccelerationStructure (std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures);
2609 vector<de::SharedPtr<BottomLevelAccelerationStructure>> initBottomAccelerationStructures (void);
2610 void initializeParameters (void);
2611 bool verifyResults (void);
2612
2613 private:
2614 CaseDef m_data;
2615 std::vector<std::vector<tcu::Vec3>> m_geomData;
2616 de::MovePtr<BufferWithMemory> m_resultBuffer;
2617 de::MovePtr<BufferWithMemory> m_rayBuffer;
2618 deUint32 m_numGeoms;
2619 deUint32 m_primsPerGeometry;
2620 deUint32 m_geomsPerInstance;
2621
2622 de::MovePtr<BufferWithMemory> m_raygenShaderBindingTable;
2623 de::MovePtr<BufferWithMemory> m_missShaderBindingTable;
2624 de::MovePtr<BufferWithMemory> m_hitShaderBindingTable;
2625
2626 VkStridedDeviceAddressRegionKHR m_raygenShaderBindingTableRegion;
2627 VkStridedDeviceAddressRegionKHR m_missShaderBindingTableRegion;
2628 VkStridedDeviceAddressRegionKHR m_hitShaderBindingTableRegion;
2629 VkStridedDeviceAddressRegionKHR m_callableShaderBindingTableRegion;
2630 };
2631
RayTracingIndirectTestInstance(Context& context, const CaseDef& data)2632 RayTracingIndirectTestInstance::RayTracingIndirectTestInstance (Context& context, const CaseDef& data)
2633 : vkt::TestInstance (context)
2634 , m_data (data)
2635 , m_numGeoms (0)
2636 , m_primsPerGeometry (0)
2637 , m_geomsPerInstance (0)
2638 {
2639 }
2640
~RayTracingIndirectTestInstance(void)2641 RayTracingIndirectTestInstance::~RayTracingIndirectTestInstance(void)
2642 {
2643 }
2644
2645 class RayTracingIndirectTestCase : public TestCase
2646 {
2647 public:
2648 RayTracingIndirectTestCase (tcu::TestContext& context, const char* name, const CaseDef data);
2649 ~RayTracingIndirectTestCase (void);
2650
2651 virtual void initPrograms (SourceCollections& programCollection) const;
2652 virtual TestInstance* createInstance (Context& context) const;
2653 virtual void checkSupport (Context& context) const;
2654
2655 private:
2656 static inline const std::string getIntersectionPassthrough (void);
2657 static inline const std::string getMissPassthrough (void);
2658 static inline const std::string getHitPassthrough (void);
2659
2660 CaseDef m_data;
2661 };
2662
RayTracingIndirectTestCase(tcu::TestContext& context, const char* name, const CaseDef data)2663 RayTracingIndirectTestCase::RayTracingIndirectTestCase (tcu::TestContext& context, const char* name, const CaseDef data)
2664 : vkt::TestCase (context, name)
2665 , m_data (data)
2666 {
2667 }
2668
~RayTracingIndirectTestCase(void)2669 RayTracingIndirectTestCase::~RayTracingIndirectTestCase (void)
2670 {
2671 }
2672
checkSupport(Context& context) const2673 void RayTracingIndirectTestCase::checkSupport(Context& context) const
2674 {
2675 const bool pipelineFlagSkipTriangles = ((m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR) != 0);
2676 const bool pipelineFlagSkipAABSs = ((m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR) != 0);
2677 const bool cullingFlags = m_data.rayFlagSkipTriangles
2678 || m_data.rayFlagSkipAABSs
2679 || pipelineFlagSkipTriangles
2680 || pipelineFlagSkipAABSs;
2681
2682 context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
2683 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
2684
2685 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
2686 if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE )
2687 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
2688
2689 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
2690 if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
2691 TCU_THROW(TestError, "VK_KHR_ray_tracing_pipeline requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
2692
2693 if (cullingFlags && rayTracingPipelineFeaturesKHR.rayTraversalPrimitiveCulling == DE_FALSE)
2694 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTraversalPrimitiveCulling");
2695 }
2696
initPrograms(SourceCollections& programCollection) const2697 void RayTracingIndirectTestCase::initPrograms (SourceCollections& programCollection) const
2698 {
2699 if (m_data.id == TEST_ID_INDICES_INDIRECT)
2700 {
2701 std::ostringstream raygenSrc;
2702 raygenSrc
2703 << "struct Payload { uvec4 data; };\n"
2704 << "layout(location = 0) rayPayloadEXT Payload payload;\n"
2705 << "void main() {\n"
2706 << " uint index = launchIndex();\n"
2707 << " payload.data = uvec4(0, 0, 0, 0);\n"
2708 << " Ray ray = rays[index];\n"
2709 << " traceRayEXT(scene, 0, 0xff, 0, 0, 0, ray.pos, ray.tmin, ray.dir, ray.tmax, 0);\n"
2710 << " results[index] = payload.data;\n"
2711 << "}";
2712 const std::string raygen = raygenSrc.str();
2713 addBuiltInShaderSource<glu::RaygenSource>(programCollection, VK_SHADER_STAGE_RAYGEN_BIT_KHR, raygen, m_data, "uvec4");
2714
2715 std::ostringstream missSrc;
2716 missSrc
2717 << "struct Payload { uvec4 data; };\n"
2718 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2719 << "void main() {\n"
2720 << " payload.data = uvec4(111, 222, 333, 444);\n"
2721 << "}";
2722 const std::string miss = missSrc.str();
2723 addBuiltInShaderSource<glu::MissSource>(programCollection, VK_SHADER_STAGE_MISS_BIT_KHR, miss, m_data, "uvec4");
2724
2725 std::ostringstream closestHitSrc;
2726 closestHitSrc
2727 << "struct Payload { uvec4 data; };\n"
2728 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2729 << "hitAttributeEXT vec2 attribs;\n"
2730 << "void main() {\n"
2731 << " payload.data = uvec4(gl_PrimitiveID, 0, gl_InstanceID, gl_InstanceCustomIndexEXT);\n"
2732 << "}";
2733 const std::string closestHit = closestHitSrc.str();
2734 addBuiltInShaderSource<glu::ClosestHitSource>(programCollection, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, closestHit, m_data, "uvec4");
2735
2736 std::ostringstream anyHitSrc;
2737 anyHitSrc
2738 << "struct Payload { uvec4 data; };\n"
2739 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2740 << "hitAttributeEXT vec2 attribs;\n"
2741 << "void main() {\n"
2742 << " payload.data = uvec4(gl_PrimitiveID, 0, gl_InstanceID, gl_InstanceCustomIndexEXT);\n"
2743 << "}";
2744 const std::string anyHit = anyHitSrc.str();
2745 addBuiltInShaderSource<glu::AnyHitSource>(programCollection, VK_SHADER_STAGE_ANY_HIT_BIT_KHR, anyHit, m_data, "uvec4");
2746
2747 std::ostringstream isectSrc;
2748 isectSrc
2749 << "hitAttributeEXT vec2 dummy;\n"
2750 << "void main() {\n"
2751 << " reportIntersectionEXT(0.0, 0u);\n"
2752 << "}";
2753 const std::string isect = isectSrc.str();
2754 addBuiltInShaderSource<glu::IntersectionSource>(programCollection, VK_SHADER_STAGE_INTERSECTION_BIT_KHR, isect, m_data, "uvec4");
2755 }
2756 else if (m_data.id == TEST_ID_TRANSFORMS_INDIRECT)
2757 {
2758 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0, true);
2759
2760 std::ostringstream preambleSrc;
2761 preambleSrc
2762 << "struct ResultData { Ray ray; vec4 worldRayOrig; vec4 worldRayDir; vec4 objectRayOrig; vec4 objectRayDir;\n"
2763 << "vec4 objectToWorld[4]; vec4 worldToObject[4];\n"
2764 << "uint missResult; uint closestHitResult; uint anyHitResult; uint isectResult; };\n"
2765 << "layout(std430, set = 0, binding = 0) buffer Results { ResultData results; };\n"
2766 << "\n"
2767 << "#ifdef CHECKS\n"
2768 << "bool fuzzy_check(vec3 a, vec3 b) {\n"
2769 << " float eps = 0.00001;\n"
2770 << " return abs(a.x - b.x) <= eps && abs(a.y - b.y) <= eps && abs(a.z - b.z) <= eps;\n"
2771 << "}\n"
2772 << "bool check_all() {\n"
2773 << " if (fuzzy_check(results.worldRayOrig.xyz, gl_WorldRayOriginEXT) == false)\n"
2774 << " return false;\n"
2775 << " if (fuzzy_check(results.worldRayDir.xyz, gl_WorldRayDirectionEXT) == false)\n"
2776 << " return false;\n"
2777 << "#ifndef MISS_SHADER\n"
2778 << " if (fuzzy_check(results.objectRayOrig.xyz, gl_ObjectRayOriginEXT) == false)\n"
2779 << " return false;\n"
2780 << " if (fuzzy_check(results.objectRayDir.xyz, gl_WorldRayDirectionEXT) == false)\n"
2781 << " return false;\n"
2782 << " if (fuzzy_check(results.objectToWorld[0].xyz, gl_ObjectToWorldEXT[0]) == false)\n"
2783 << " return false;\n"
2784 << " if (fuzzy_check(results.objectToWorld[1].xyz, gl_ObjectToWorldEXT[1]) == false)\n"
2785 << " return false;\n"
2786 << " if (fuzzy_check(results.objectToWorld[2].xyz, gl_ObjectToWorldEXT[2]) == false)\n"
2787 << " return false;\n"
2788 << " if (fuzzy_check(results.objectToWorld[3].xyz, gl_ObjectToWorldEXT[3]) == false)\n"
2789 << " return false;\n"
2790 << " if (fuzzy_check(results.worldToObject[0].xyz, gl_WorldToObjectEXT[0]) == false)\n"
2791 << " return false;\n"
2792 << " if (fuzzy_check(results.worldToObject[1].xyz, gl_WorldToObjectEXT[1]) == false)\n"
2793 << " return false;\n"
2794 << " if (fuzzy_check(results.worldToObject[2].xyz, gl_WorldToObjectEXT[2]) == false)\n"
2795 << " return false;\n"
2796 << " if (fuzzy_check(results.worldToObject[3].xyz, gl_WorldToObjectEXT[3]) == false)\n"
2797 << " return false;\n"
2798 << "#endif\n"
2799 << " return true;\n"
2800 << "};\n"
2801 << "#endif\n";
2802 const std::string preamble = preambleSrc.str();
2803
2804 std::ostringstream raygenSrc;
2805 raygenSrc
2806 << "$preamble$\n"
2807 << "struct Payload { uint x; };\n"
2808 << "layout(location = 0) rayPayloadEXT Payload payload;\n"
2809 << "void main() {\n"
2810 << " payload.x = 0;\n"
2811 << " results.missResult = 0;\n"
2812 << " results.closestHitResult = 0;\n"
2813 << " results.anyHitResult = 0;\n"
2814 << " results.isectResult = 0;\n"
2815 << " Ray ray = results.ray;\n"
2816 << " traceRayEXT(scene, 0, 0xff, 0, 0, 0, ray.pos, ray.tmin, ray.dir, ray.tmax, 0);\n"
2817 << "}";
2818 std::string raygen = raygenSrc.str();
2819 raygen = generateShaderSource(raygen.c_str(), "", DEFINE_RAY | DEFINE_SCENE);
2820 raygen = replaceString(raygen, "$preamble$", preamble);
2821 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_RAYGEN_BIT_KHR)) << glu::RaygenSource(raygen) << buildOptions;
2822
2823 std::ostringstream missSrc;
2824 missSrc
2825 << "#define CHECKS\n"
2826 << "#define MISS_SHADER\n"
2827 << "$preamble$\n"
2828 << "struct Payload { uint x; };\n"
2829 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2830 << "void main() {\n"
2831 << " if (check_all())\n"
2832 << " results.missResult = 1;\n"
2833 << "}";
2834 std::string miss = missSrc.str();
2835 miss = generateShaderSource(miss.c_str(), "", DEFINE_RAY);
2836 miss = replaceString(miss, "$preamble$", preamble);
2837 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_MISS_BIT_KHR)) << glu::MissSource(miss) << buildOptions;
2838
2839 std::ostringstream closestHitSrc;
2840 closestHitSrc
2841 << "#define CHECKS\n"
2842 << "$preamble$\n"
2843 << "struct Payload { uint x; };\n"
2844 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2845 << "hitAttributeEXT vec2 attribs; "
2846 << "void main() {\n"
2847 << " if (check_all())\n"
2848 << " results.closestHitResult = 1;\n"
2849 << "}";
2850 std::string closestHit = closestHitSrc.str();
2851 closestHit = generateShaderSource(closestHit.c_str(), "", DEFINE_RAY);
2852 closestHit = replaceString(closestHit, "$preamble$", preamble);
2853 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)) << glu::ClosestHitSource(closestHit) << buildOptions;
2854
2855 std::ostringstream anyHitSrc;
2856 anyHitSrc
2857 << "#define CHECKS\n"
2858 << "$preamble$\n"
2859 << "struct Payload { uint x; };\n"
2860 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2861 << "hitAttributeEXT vec2 attribs; "
2862 << "void main() {\n"
2863 << " if (check_all())\n"
2864 << " results.anyHitResult = 1;\n"
2865 << "}";
2866 std::string anyHit = anyHitSrc.str();
2867 anyHit = generateShaderSource(anyHit.c_str(), "", DEFINE_RAY);
2868 anyHit = replaceString(anyHit, "$preamble$", preamble);
2869 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_ANY_HIT_BIT_KHR)) << glu::AnyHitSource(anyHit) << buildOptions;
2870
2871 std::ostringstream isectSrc;
2872 isectSrc
2873 << "#define CHECKS\n"
2874 << "$preamble$\n"
2875 << "hitAttributeEXT vec2 dummy;\n"
2876 << "void main() {\n"
2877 << " if (check_all())\n"
2878 << " results.isectResult = 1;\n"
2879 << " reportIntersectionEXT(0.0, 0u);\n"
2880 << "}";
2881 std::string isect = isectSrc.str();
2882 isect = generateShaderSource(isect.c_str(), "", DEFINE_RAY);
2883 isect = replaceString(isect, "$preamble$", preamble);
2884 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_INTERSECTION_BIT_KHR)) << glu::IntersectionSource(isect) << buildOptions;
2885 }
2886 else if (m_data.id == TEST_ID_TMINMAX_INDIRECT)
2887 {
2888 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
2889
2890 std::ostringstream preambleSrc;
2891 preambleSrc
2892 << "struct ResultData { Ray ray; float miss_maxt; float chit_maxt; float ahit_maxt; float isect_maxt;\n"
2893 << "uint missResult; uint closestHitResult; uint anyHitResult; uint isectResult; float debug; };\n"
2894 << "layout(std430, set = 0, binding = 0) buffer Results { ResultData results; };\n"
2895 << "\n"
2896 << "#ifdef CHECKS\n"
2897 << "bool fuzzy_check(float a, float b) {\n"
2898 << " float eps = 0.0001;\n"
2899 << " return abs(a - b) <= eps;\n"
2900 << "}\n"
2901 << "bool check_all() {\n"
2902 << " if (fuzzy_check(results.ray.tmin, gl_RayTminEXT) == false)\n"
2903 << " return false;\n"
2904 << "#ifdef MISS_SHADER\n"
2905 << " if (fuzzy_check(results.miss_maxt, gl_RayTmaxEXT) == false)\n"
2906 << " return false;\n"
2907 << "#endif\n"
2908 << "#ifdef CHIT_SHADER\n"
2909 << " if (fuzzy_check(results.chit_maxt, gl_RayTmaxEXT) == false)\n"
2910 << " return false;\n"
2911 << "#endif\n"
2912 << "#ifdef AHIT_SHADER\n"
2913 << " if (fuzzy_check(results.ahit_maxt, gl_RayTmaxEXT) == false)\n"
2914 << " return false;\n"
2915 << "#endif\n"
2916 << "#ifdef ISECT_SHADER\n"
2917 << " if (fuzzy_check(results.isect_maxt, gl_RayTmaxEXT) == false)\n"
2918 << " return false;\n"
2919 << "#endif\n"
2920 << " return true;\n"
2921 << "};\n"
2922 << "#endif\n";
2923 const std::string preamble = preambleSrc.str();
2924
2925 std::ostringstream raygenSrc;
2926 raygenSrc
2927 << "$preamble$\n"
2928 << "struct Payload { uint x; };\n"
2929 << "layout(location = 0) rayPayloadEXT Payload payload;\n"
2930 << "void main() {\n"
2931 << " payload.x = 0;\n"
2932 << " results.missResult = 0;\n"
2933 << " results.closestHitResult = 0;\n"
2934 << " results.anyHitResult = 0;\n"
2935 << " results.isectResult = 0;\n"
2936 << " Ray ray = results.ray;\n"
2937 << " traceRayEXT(scene, 0, 0xff, 0, 0, 0, ray.pos, ray.tmin, ray.dir, ray.tmax, 0);\n"
2938 << "}";
2939 std::string raygen = raygenSrc.str();
2940 raygen = generateShaderSource(raygen.c_str(), "", DEFINE_RAY | DEFINE_SCENE);
2941 raygen = replaceString(raygen, "$preamble$", preamble);
2942 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_RAYGEN_BIT_KHR)) << glu::RaygenSource(raygen) << buildOptions;
2943
2944 std::ostringstream missSrc;
2945 missSrc
2946 << "#define CHECKS\n"
2947 << "#define MISS_SHADER\n"
2948 << "$preamble$\n"
2949 << "struct Payload { uint x; };\n"
2950 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2951 << "void main() {\n"
2952 << " if (check_all())\n"
2953 << " results.missResult = 1;\n"
2954 << "}";
2955 std::string miss = missSrc.str();
2956 miss = generateShaderSource(miss.c_str(), "", DEFINE_RAY);
2957 miss = replaceString(miss, "$preamble$", preamble);
2958 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_MISS_BIT_KHR)) << glu::MissSource(miss) << buildOptions;
2959
2960 std::ostringstream cloesetHitSrc;
2961 cloesetHitSrc
2962 << "#define CHECKS\n"
2963 << "#define CHIT_SHADER\n"
2964 << "$preamble$\n"
2965 << "struct Payload { uint x; };\n"
2966 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2967 << "hitAttributeEXT vec2 attribs; "
2968 << "void main() {\n"
2969 << " if (check_all())\n"
2970 << " results.closestHitResult = 1;\n"
2971 << "}";
2972 std::string closestHit = cloesetHitSrc.str();
2973 closestHit = generateShaderSource(closestHit.c_str(), "", DEFINE_RAY);
2974 closestHit = replaceString(closestHit, "$preamble$", preamble);
2975 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)) << glu::ClosestHitSource(closestHit) << buildOptions;
2976
2977 std::ostringstream anyHitSrc;
2978 anyHitSrc
2979 << "#define CHECKS\n"
2980 << "#define AHIT_SHADER\n"
2981 << "$preamble$\n"
2982 << "struct Payload { uint x; };\n"
2983 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2984 << "hitAttributeEXT vec2 attribs; "
2985 << "void main() {\n"
2986 << " if (check_all())\n"
2987 << " results.anyHitResult = 1;\n"
2988 << "}";
2989 std::string anyHit = anyHitSrc.str();
2990 anyHit = generateShaderSource(anyHit.c_str(), "", DEFINE_RAY);
2991 anyHit = replaceString(anyHit, "$preamble$", preamble);
2992 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_ANY_HIT_BIT_KHR)) << glu::AnyHitSource(anyHit) << buildOptions;
2993
2994 std::ostringstream isectSrc;
2995 isectSrc
2996 << "#define CHECKS\n"
2997 << "#define ISECT_SHADER\n"
2998 << "$preamble$\n"
2999 << "hitAttributeEXT vec2 dummy;\n"
3000 << "void main() {\n"
3001 << " results.debug = gl_RayTmaxEXT;\n"
3002 << " if (check_all())\n"
3003 << " results.isectResult = 1;\n"
3004 << " reportIntersectionEXT(results.chit_maxt, 0u);\n"
3005 << "}";
3006 std::string isect = isectSrc.str();
3007 isect = generateShaderSource(isect.c_str(), "", DEFINE_RAY);
3008 isect = replaceString(isect, "$preamble$", preamble);
3009 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_INTERSECTION_BIT_KHR)) << glu::IntersectionSource(isect) << buildOptions;
3010 }
3011 else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_INDIRECT)
3012 {
3013 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0, true);
3014
3015 std::ostringstream preambleSrc;
3016 preambleSrc
3017 << "struct ResultData { Ray ray[2]; uint flags; uint miss[2]; uint chit[2]; uint ahit[2]; uint isect[2]; };\n"
3018 << "layout(std430, set = 0, binding = 0) buffer Results { ResultData results; };\n"
3019 << "\n"
3020 << "#ifdef CHECKS\n"
3021 << "bool check_all() {\n"
3022 << " if (gl_IncomingRayFlagsEXT != results.flags)\n"
3023 << " return false;\n"
3024 << " return true;\n"
3025 << "}\n"
3026 << "#endif\n";
3027 const std::string preamble = preambleSrc.str();
3028
3029 std::ostringstream raygenSrc;
3030 raygenSrc
3031 << "$preamble$\n"
3032 << "struct Payload { uint x; };\n"
3033 << "layout(location = 0) rayPayloadEXT Payload payload;\n"
3034 << "void main() {\n"
3035 << " payload.x = 0;\n"
3036 << " results.miss[gl_LaunchIDEXT.x] = 0;\n"
3037 << " results.chit[gl_LaunchIDEXT.x] = 0;\n"
3038 << " results.ahit[gl_LaunchIDEXT.x] = 0;\n"
3039 << " results.isect[gl_LaunchIDEXT.x] = 0;\n"
3040 << " Ray ray = results.ray[gl_LaunchIDEXT.x];\n"
3041 << " traceRayEXT(scene, results.flags, 0xff, 0, 0, 0, ray.pos, ray.tmin, ray.dir, ray.tmax, 0);\n"
3042 << "}";
3043 std::string raygen = raygenSrc.str();
3044 raygen = generateShaderSource(raygen.c_str(), "", DEFINE_RAY | DEFINE_SCENE);
3045 raygen = replaceString(raygen, "$preamble$", preamble);
3046 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_RAYGEN_BIT_KHR)) << glu::RaygenSource(raygen) << buildOptions;
3047
3048 std::ostringstream missSrc;
3049 missSrc
3050 << "#define CHECKS\n"
3051 << "#define MISS_SHADER\n"
3052 << "$preamble$\n"
3053 << "struct Payload { uint x; };\n"
3054 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
3055 << "void main() {\n"
3056 << " if (check_all())\n"
3057 << " results.miss[gl_LaunchIDEXT.x]++;\n"
3058 << "}";
3059 std::string miss = missSrc.str();
3060 miss = generateShaderSource(miss.c_str(), "", DEFINE_RAY);
3061 miss = replaceString(miss, "$preamble$", preamble);
3062 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_MISS_BIT_KHR)) << glu::MissSource(miss) << buildOptions;
3063
3064 std::ostringstream closestHitSrc;
3065 closestHitSrc
3066 << "#define CHECKS\n"
3067 << "#define CHIT_SHADER\n"
3068 << "$preamble$\n"
3069 << "struct Payload { uint x; };\n"
3070 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
3071 << "hitAttributeEXT vec2 attribs; "
3072 << "void main() {\n"
3073 << " if (check_all())\n"
3074 << " results.chit[gl_LaunchIDEXT.x]++;\n"
3075 << "}";
3076 std::string closestHit = closestHitSrc.str();
3077 closestHit = generateShaderSource(closestHit.c_str(), "", DEFINE_RAY);
3078 closestHit = replaceString(closestHit, "$preamble$", preamble);
3079 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)) << glu::ClosestHitSource(closestHit) << buildOptions;
3080
3081 std::ostringstream anyHitSrc;
3082 anyHitSrc
3083 << "#define CHECKS\n"
3084 << "#define AHIT_SHADER\n"
3085 << "$preamble$\n"
3086 << "struct Payload { uint x; };\n"
3087 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
3088 << "hitAttributeEXT vec2 attribs; "
3089 << "void main() {\n"
3090 << " if (check_all())\n"
3091 << " results.ahit[gl_LaunchIDEXT.x]++;\n"
3092 << "}";
3093 std::string anyHit = anyHitSrc.str();
3094 anyHit = generateShaderSource(anyHit.c_str(), "", DEFINE_RAY);
3095 anyHit = replaceString(anyHit, "$preamble$", preamble);
3096 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_ANY_HIT_BIT_KHR)) << glu::AnyHitSource(anyHit) << buildOptions;
3097
3098 std::ostringstream isectSrc;
3099 isectSrc
3100 << "#define CHECKS\n"
3101 << "#define ISECT_SHADER\n"
3102 << "$preamble$\n"
3103 << "hitAttributeEXT vec2 dummy;\n"
3104 << "void main() {\n"
3105 << " if (check_all())\n"
3106 << " results.isect[gl_LaunchIDEXT.x]++;\n"
3107 << " reportIntersectionEXT(gl_RayTminEXT, 0u);\n"
3108 << "}";
3109 std::string isect = isectSrc.str();
3110 isect = generateShaderSource(isect.c_str(), "", DEFINE_RAY);
3111 isect = replaceString(isect, "$preamble$", preamble);
3112 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_INTERSECTION_BIT_KHR)) << glu::IntersectionSource(isect) << buildOptions;
3113 }
3114 else if (m_data.id == TEST_ID_HIT_KIND_INDIRECT)
3115 {
3116 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0, true);
3117
3118 std::ostringstream preambleSrc;
3119 preambleSrc
3120 << "struct ResultData { Ray ray[2]; uint kind[2]; uint chit[2]; uint ahit[2]; uint debug[2]; };\n"
3121 << "layout(std430, set = 0, binding = 0) buffer Results { ResultData results; };\n"
3122 << "\n"
3123 << "#ifdef CHECKS\n"
3124 << "bool check_all() {\n"
3125 << "#if defined(CHIT_SHADER) || defined(AHIT_SHADER)\n"
3126 << " if (gl_HitKindEXT != results.kind[gl_LaunchIDEXT.x])\n"
3127 << " return false;\n"
3128 << "#endif\n"
3129 << " return true;\n"
3130 << "}\n"
3131 << "#endif\n";
3132 const std::string preamble = preambleSrc.str();
3133
3134 std::ostringstream raygenSrc;
3135 raygenSrc
3136 << "$preamble$\n"
3137 << "struct Payload { uint x; };\n"
3138 << "layout(location = 0) rayPayloadEXT Payload payload;\n"
3139 << "void main() {\n"
3140 << " payload.x = 0;\n"
3141 << " uint i = gl_LaunchIDEXT.x;\n"
3142 << " results.chit[i] = 0;\n"
3143 << " results.ahit[i] = 0;\n"
3144 << " Ray ray = results.ray[i];\n"
3145 << " traceRayEXT(scene, 0, 0xff, 0, 0, 0, ray.pos, ray.tmin, ray.dir, ray.tmax, 0);\n"
3146 << "}";
3147 std::string raygen = raygenSrc.str();
3148 raygen = generateShaderSource(raygen.c_str(), "", DEFINE_RAY | DEFINE_SCENE);
3149 raygen = replaceString(raygen, "$preamble$", preamble);
3150 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_RAYGEN_BIT_KHR)) << glu::RaygenSource(raygen) << buildOptions;
3151
3152 std::ostringstream missSrc;
3153 missSrc
3154 << "#define CHECKS\n"
3155 << "#define MISS_SHADER\n"
3156 << "$preamble$\n"
3157 << "struct Payload { uint x; };\n"
3158 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
3159 << "void main() {\n"
3160 << "}";
3161 std::string miss = missSrc.str();
3162 miss = generateShaderSource(miss.c_str(), "", DEFINE_RAY);
3163 miss = replaceString(miss, "$preamble$", preamble);
3164 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_MISS_BIT_KHR)) << glu::MissSource(miss) << buildOptions;
3165
3166 std::ostringstream closestHitSrc;
3167 closestHitSrc
3168 << "#define CHECKS\n"
3169 << "#define CHIT_SHADER\n"
3170 << "$preamble$\n"
3171 << "struct Payload { uint x; };\n"
3172 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
3173 << "hitAttributeEXT vec2 attribs; "
3174 << "void main() {\n"
3175 << " results.debug[gl_LaunchIDEXT.x] = gl_HitKindEXT;\n"
3176 << " if (check_all())\n"
3177 << " results.chit[gl_LaunchIDEXT.x] = 1;\n"
3178 << "}";
3179 std::string closestHit = closestHitSrc.str();
3180 closestHit = generateShaderSource(closestHit.c_str(), "", DEFINE_RAY);
3181 closestHit = replaceString(closestHit, "$preamble$", preamble);
3182 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)) << glu::ClosestHitSource(closestHit) << buildOptions;
3183
3184 std::ostringstream anyHitSrc;
3185 anyHitSrc
3186 << "#define CHECKS\n"
3187 << "#define AHIT_SHADER\n"
3188 << "$preamble$\n"
3189 << "struct Payload { uint x; };\n"
3190 << "layout(location = 0) rayPayloadInEXT Payload payload;\n"
3191 << "hitAttributeEXT vec2 attribs; "
3192 << "void main() {\n"
3193 << " if (check_all())\n"
3194 << " results.ahit[gl_LaunchIDEXT.x] = 1;\n"
3195 << "}";
3196 std::string anyHit = anyHitSrc.str();
3197 anyHit = generateShaderSource(anyHit.c_str(), "", DEFINE_RAY);
3198 anyHit = replaceString(anyHit, "$preamble$", preamble);
3199 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_ANY_HIT_BIT_KHR)) << glu::AnyHitSource(anyHit) << buildOptions;
3200
3201 std::ostringstream isectSrc;
3202 isectSrc
3203 << "#define CHECKS\n"
3204 << "#define ISECT_SHADER\n"
3205 << "$preamble$\n"
3206 << "hitAttributeEXT vec2 dummy;\n"
3207 << "void main() {\n"
3208 << " reportIntersectionEXT(gl_RayTminEXT, results.kind[gl_LaunchIDEXT.x]);\n"
3209 << "}";
3210 std::string isect = isectSrc.str();
3211 isect = generateShaderSource(isect.c_str(), "", DEFINE_RAY);
3212 isect = replaceString(isect, "$preamble$", preamble);
3213 programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_INTERSECTION_BIT_KHR)) << glu::IntersectionSource(isect) << buildOptions;
3214 }
3215 }
3216
createInstance(Context& context) const3217 TestInstance* RayTracingIndirectTestCase::createInstance (Context& context) const
3218 {
3219 return new RayTracingIndirectTestInstance(context, m_data);
3220 }
3221
createPipelineAndShaderBindingTables(de::MovePtr<RayTracingPipeline>& rayTracingPipeline, bool aabb, VkPipelineLayout pipelineLayout)3222 Move<VkPipeline> RayTracingIndirectTestInstance::createPipelineAndShaderBindingTables (de::MovePtr<RayTracingPipeline>& rayTracingPipeline, bool aabb, VkPipelineLayout pipelineLayout)
3223 {
3224 const InstanceInterface& vki = m_context.getInstanceInterface();
3225 const DeviceInterface& vk = m_context.getDeviceInterface();
3226 const VkDevice device = m_context.getDevice();
3227 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
3228 Allocator& allocator = m_context.getDefaultAllocator();
3229
3230 const deUint32 shaderGroupHandleSize = getShaderGroupSize(vki, physicalDevice);
3231 const deUint32 shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice);
3232
3233 rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get(getShaderIdentifier(m_data, VK_SHADER_STAGE_RAYGEN_BIT_KHR)), 0), 0);
3234 rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get(getShaderIdentifier(m_data, VK_SHADER_STAGE_MISS_BIT_KHR)), 0), 1);
3235 for (deUint32 g = 0; g < m_numGeoms; ++g)
3236 {
3237 rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get(getShaderIdentifier(m_data, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)), 0), 2 + g);
3238 rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get(getShaderIdentifier(m_data, VK_SHADER_STAGE_ANY_HIT_BIT_KHR)), 0), 2 + g);
3239
3240 if (aabb)
3241 {
3242 rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR, createShaderModule(vk, device, m_context.getBinaryCollection().get(getShaderIdentifier(m_data, VK_SHADER_STAGE_INTERSECTION_BIT_KHR)), 0), 2 + g);
3243 }
3244 }
3245 Move<VkPipeline> pipeline = rayTracingPipeline->createPipeline(vk, device, pipelineLayout);
3246
3247 m_raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
3248 m_missShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
3249 m_hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, m_numGeoms);
3250
3251 m_raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, m_raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
3252 m_missShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, m_missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
3253 m_hitShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, m_hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
3254 m_callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
3255
3256 return pipeline;
3257 }
3258
createPipelineLayoutAndSet(deUint32 setCount, vk::Move<VkDescriptorPool>& descriptorPool, vk::Move<VkDescriptorSetLayout>& descriptorSetLayout, std::vector<vk::Move<VkDescriptorSet>>& descriptorSets, vk::Move<VkPipelineLayout>& pipelineLayout)3259 void RayTracingIndirectTestInstance::createPipelineLayoutAndSet (deUint32 setCount,
3260 vk::Move<VkDescriptorPool>& descriptorPool,
3261 vk::Move<VkDescriptorSetLayout>& descriptorSetLayout,
3262 std::vector<vk::Move<VkDescriptorSet>>& descriptorSets,
3263 vk::Move<VkPipelineLayout>& pipelineLayout)
3264 {
3265 const DeviceInterface& vk = m_context.getDeviceInterface();
3266 const VkDevice device = m_context.getDevice();
3267
3268 vk::DescriptorPoolBuilder descriptorPoolBuilder;
3269
3270 deUint32 storageBufCount = 2 * setCount;
3271
3272 const VkDescriptorType accelType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
3273
3274 descriptorPoolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, storageBufCount);
3275 descriptorPoolBuilder.addType(accelType, setCount);
3276
3277 descriptorPool = descriptorPoolBuilder.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, setCount);
3278
3279 vk::DescriptorSetLayoutBuilder setLayoutBuilder;
3280
3281 setLayoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, ALL_RAY_TRACING_STAGES);
3282 setLayoutBuilder.addSingleBinding(accelType, ALL_RAY_TRACING_STAGES);
3283 setLayoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, ALL_RAY_TRACING_STAGES);
3284
3285 descriptorSetLayout = setLayoutBuilder.build(vk, device);
3286
3287 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
3288 {
3289 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
3290 DE_NULL, // const void* pNext;
3291 *descriptorPool, // VkDescriptorPool descriptorPool;
3292 1u, // deUint32 setLayoutCount;
3293 &descriptorSetLayout.get() // const VkDescriptorSetLayout* pSetLayouts;
3294 };
3295
3296 for (uint32_t i = 0; i < setCount; ++i)
3297 descriptorSets.push_back(allocateDescriptorSet(vk, device, &descriptorSetAllocateInfo));
3298
3299 const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
3300 {
3301 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
3302 DE_NULL, // const void* pNext;
3303 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
3304 1u, // deUint32 setLayoutCount;
3305 &descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
3306 0u, // deUint32 pushConstantRangeCount;
3307 nullptr, // const VkPushConstantRange* pPushConstantRanges;
3308 };
3309
3310 pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutInfo);
3311 }
3312
initTopAccelerationStructure(std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>& blas)3313 de::SharedPtr<TopLevelAccelerationStructure> RayTracingIndirectTestInstance::initTopAccelerationStructure (std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>& blas)
3314 {
3315 de::SharedPtr<TopLevelAccelerationStructure> tlas = de::SharedPtr<TopLevelAccelerationStructure>(makeTopLevelAccelerationStructure().release());
3316
3317 VkTransformMatrixKHR transform = identityMatrix3x4;
3318 if (m_data.id == TEST_ID_TRANSFORMS_INDIRECT)
3319 {
3320 tcu::Vec3 instanceOffset = tcu::Vec3(2.0f, 4.0f, 8.0f);
3321 transform.matrix[0][3] = instanceOffset[0];
3322 transform.matrix[1][3] = instanceOffset[1];
3323 transform.matrix[2][3] = instanceOffset[2];
3324 }
3325
3326 for (size_t i = 0; i < blas.size(); ++i)
3327 {
3328 tlas->addInstance(blas[i], transform, 1000 + static_cast<deUint32>(i));
3329 }
3330
3331 return tlas;
3332 }
3333
initBottomAccelerationStructures()3334 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> RayTracingIndirectTestInstance::initBottomAccelerationStructures()
3335 {
3336 const bool aabb = (m_data.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR);
3337
3338 deUint32 numInstances = m_data.id == TEST_ID_INDICES_INDIRECT ? 5 : 1;
3339
3340 if (m_data.id == TEST_ID_INDICES_INDIRECT || m_data.id == TEST_ID_TRANSFORMS_INDIRECT || m_data.id == TEST_ID_TMINMAX_INDIRECT)
3341 {
3342 m_geomsPerInstance = m_data.id == TEST_ID_INDICES_INDIRECT ? 3 : 1;
3343 m_primsPerGeometry = m_data.id == TEST_ID_INDICES_INDIRECT ? 4 : 1;
3344
3345 m_numGeoms = numInstances * m_geomsPerInstance;
3346
3347 for (deUint32 i = 0; i < m_numGeoms; ++i)
3348 {
3349 std::vector<tcu::Vec3> geomPrims;
3350
3351 for (deUint32 j = 0; j < m_primsPerGeometry; ++j)
3352 {
3353 const deUint32 primId = (i * m_primsPerGeometry) + j;
3354 float dx = 10.0f * static_cast<float>(primId);
3355 if (aabb == false)
3356 {
3357 geomPrims.push_back(tcu::Vec3(dx + -1.0f, -1.0f, 1.0f));
3358 geomPrims.push_back(tcu::Vec3(dx + 1.0f, -1.0f, 1.0f));
3359 geomPrims.push_back(tcu::Vec3(dx + 0.0f, 1.0f, 1.0f));
3360 }
3361 else
3362 {
3363 geomPrims.push_back(tcu::Vec3(dx - 1.0f, -1.0f, 1.0f)); // min x/y/z
3364 geomPrims.push_back(tcu::Vec3(dx + 1.0f, 1.0f, 2.0f)); // max x/y/z
3365 }
3366 }
3367 m_geomData.push_back(geomPrims);
3368 }
3369 }
3370 else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_INDIRECT || m_data.id == TEST_ID_HIT_KIND_INDIRECT)
3371 {
3372 m_geomsPerInstance = m_data.id == TEST_ID_INCOMING_RAY_FLAGS_INDIRECT ? 2 : 1;
3373 m_primsPerGeometry = 1;
3374
3375 m_numGeoms = numInstances * m_geomsPerInstance;
3376
3377 for (deUint32 i = 0; i < m_numGeoms; ++i)
3378 {
3379 std::vector<tcu::Vec3> geomPrims;
3380
3381 for (deUint32 j = 0; j < m_primsPerGeometry; ++j)
3382 {
3383 const deUint32 primId = (i * m_primsPerGeometry) + j;
3384 float z = 1.0f + 10.0f * static_cast<float>(primId);
3385
3386 bool ccw = (primId % 2) == 0;
3387
3388 if (aabb == false)
3389 {
3390 if (ccw)
3391 {
3392 geomPrims.push_back(tcu::Vec3(-1.0f, -1.0f, z));
3393 geomPrims.push_back(tcu::Vec3( 1.0f, -1.0f, z));
3394 geomPrims.push_back(tcu::Vec3( 0.0f, 1.0f, z));
3395 }
3396 else
3397 {
3398 geomPrims.push_back(tcu::Vec3( 1.0f, -1.0f, z));
3399 geomPrims.push_back(tcu::Vec3(-1.0f, -1.0f, z));
3400 geomPrims.push_back(tcu::Vec3( 0.0f, 1.0f, z));
3401 }
3402 }
3403 else
3404 {
3405 geomPrims.push_back(tcu::Vec3(-1.0f, -1.0f, z)); // min x/y/z
3406 geomPrims.push_back(tcu::Vec3( 1.0f, 1.0f, z + 1.0f)); // max x/y/z
3407 }
3408 }
3409 m_geomData.push_back(geomPrims);
3410 }
3411 }
3412
3413 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> blas;
3414
3415 if (!m_geomData.empty())
3416 {
3417 for (deUint32 i = 0; i < numInstances; ++i)
3418 {
3419 de::SharedPtr<BottomLevelAccelerationStructure> accel = de::SharedPtr<BottomLevelAccelerationStructure>(makeBottomLevelAccelerationStructure().release());
3420 for (deUint32 j = 0; j < m_geomsPerInstance; ++j)
3421 {
3422 accel->addGeometry(m_geomData[(i * m_geomsPerInstance) + j], !aabb, 0U);
3423 }
3424 blas.push_back(accel);
3425 }
3426 }
3427 return blas;
3428 }
3429
3430 struct Ray
3431 {
Rayvkt::RayTracing::__anon28502::Ray3432 Ray() : o(0.0f), tmin(0.0f), d(0.0f), tmax(0.0f){}
Rayvkt::RayTracing::__anon28502::Ray3433 Ray(const tcu::Vec3& io, float imin, const tcu::Vec3& id, float imax): o(io), tmin(imin), d(id), tmax(imax){}
3434 tcu::Vec3 o;
3435 float tmin;
3436 tcu::Vec3 d;
3437 float tmax;
3438 };
3439
3440 struct TransformResultData {
3441
TransformResultDatavkt::RayTracing::__anon28502::TransformResultData3442 TransformResultData(): ray(), worldRayOrig(0.f), padding0(0.f), worldRayDir(0.f), padding1(0.f),
3443 objectRayOrig(0.f), padding2(0.f), objectRayDir(0.f), padding3(0.f), objectToWorld0(0.f), padding4(0.f),
3444 objectToWorld1(0.f), padding5(0.f), objectToWorld2(0.f), padding6(0.f), objectToWorld3(0.f), padding7(0.f),
3445 worldToObject0(0.f), padding8(0.f), worldToObject1(0.f), padding9(0.f), worldToObject2(0.f), padding10(0.f),
3446 worldToObject3(0.f), padding11(0.f), missResult(0), closestHitResult(0), anyHitResult(0), isectResult(0) {}
3447
3448 Ray ray;
3449 tcu::Vec3 worldRayOrig; float padding0;
3450 tcu::Vec3 worldRayDir; float padding1;
3451 tcu::Vec3 objectRayOrig; float padding2;
3452 tcu::Vec3 objectRayDir; float padding3;
3453 tcu::Vec3 objectToWorld0; float padding4;
3454 tcu::Vec3 objectToWorld1; float padding5;
3455 tcu::Vec3 objectToWorld2; float padding6;
3456 tcu::Vec3 objectToWorld3; float padding7;
3457 tcu::Vec3 worldToObject0; float padding8;
3458 tcu::Vec3 worldToObject1; float padding9;
3459 tcu::Vec3 worldToObject2; float padding10;
3460 tcu::Vec3 worldToObject3; float padding11;
3461 deUint32 missResult;
3462 deUint32 closestHitResult;
3463 deUint32 anyHitResult;
3464 deUint32 isectResult;
3465 };
3466
3467 struct TMinMaxResultData {
3468 Ray ray;
3469 float miss_maxt;
3470 float chit_maxt;
3471 float ahit_maxt;
3472 float isect_maxt;
3473 deUint32 missResult;
3474 deUint32 closestHitResult;
3475 deUint32 anyHitResult;
3476 deUint32 isectResult;
3477 float debug;
3478 };
3479
3480 struct IncomingFlagsResultData {
3481 Ray ray[2];
3482 deUint32 flags;
3483 deUint32 miss[2];
3484 deUint32 chit[2];
3485 deUint32 ahit[2];
3486 deUint32 isect[2];
3487 };
3488
3489 struct HitKindResultData {
3490 Ray ray[2];
3491 deUint32 kind[2];
3492 deUint32 chit[2];
3493 deUint32 ahit[2];
3494 deUint32 debug[2];
3495 };
3496
initializeParameters()3497 void RayTracingIndirectTestInstance::initializeParameters()
3498 {
3499 const VkDevice device = m_context.getDevice();
3500 const DeviceInterface& vk = m_context.getDeviceInterface();
3501 Allocator& allocator = m_context.getDefaultAllocator();
3502
3503 const bool aabb = (m_data.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR);
3504
3505 if (m_data.id == TEST_ID_INDICES_INDIRECT)
3506 {
3507 std::vector<Ray> rays;
3508 for (deUint32 g = 0; g < m_numGeoms; ++g)
3509 {
3510 for (deUint32 p = 0; p < m_primsPerGeometry; ++p)
3511 {
3512 tcu::Vec3 center = aabb ?
3513 (m_geomData[g][2 * p + 0] + m_geomData[g][2 * p + 1]) * 0.5f :
3514 (m_geomData[g][3 * p + 0] + m_geomData[g][3 * p + 1] + m_geomData[g][3 * p + 2]) * (1.0f / 3.0f);
3515
3516 Ray r;
3517
3518 r.o = tcu::Vec3(center[0], center[1], 0.0f);
3519 r.d = tcu::Vec3(0.0f, 0.0f, 1.0f);
3520 r.tmin = 0.0f;
3521 r.tmax = 1000.0f;
3522
3523 rays.push_back(r);
3524 }
3525 }
3526 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(rays.size() * sizeof(deUint32) * 8, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3527 m_resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
3528
3529 const VkBufferCreateInfo rayBufferCreateInfo = makeBufferCreateInfo(rays.size() * sizeof(Ray), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3530 m_rayBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, rayBufferCreateInfo, MemoryRequirement::HostVisible));
3531
3532 memcpy(m_rayBuffer->getAllocation().getHostPtr(), &rays[0], rays.size() * sizeof(Ray));
3533 flushMappedMemoryRange(vk, device, m_rayBuffer->getAllocation().getMemory(), m_rayBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
3534 }
3535 else if (m_data.id == TEST_ID_TRANSFORMS_INDIRECT)
3536 {
3537 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(sizeof(TransformResultData), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3538 m_resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
3539
3540 TransformResultData* resultData = (TransformResultData*)m_resultBuffer->getAllocation().getHostPtr();
3541 *resultData = {};
3542
3543 VkTransformMatrixKHR transform = identityMatrix3x4;
3544 tcu::Vec3 instanceOffset = tcu::Vec3(2.0f, 4.0f, 8.0f);
3545 transform.matrix[0][3] = instanceOffset[0];
3546 transform.matrix[1][3] = instanceOffset[1];
3547 transform.matrix[2][3] = instanceOffset[2];
3548
3549 {
3550 tcu::Vec3 center = aabb ?
3551 (m_geomData[0][0] + m_geomData[0][1]) * 0.5f :
3552 (m_geomData[0][0] + m_geomData[0][1] + m_geomData[0][2]) * (1.0f / 3.0f);
3553
3554 center = center + instanceOffset;
3555
3556 Ray r;
3557
3558 r.o = tcu::Vec3(center[0], center[1], 0.0f);
3559 r.d = tcu::Vec3(0.0f, 0.0f, 1.0f);
3560 r.tmin = 0.0f;
3561 r.tmax = 1000.0f;
3562
3563 if (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR)
3564 {
3565 r.d[2] = -1.0f;
3566 }
3567
3568 resultData->ray = r;
3569 }
3570
3571 resultData->worldRayOrig = resultData->ray.o;
3572 resultData->worldRayDir = resultData->ray.d;
3573 resultData->objectRayOrig = resultData->worldRayOrig - instanceOffset;
3574 resultData->objectRayDir = resultData->worldRayDir;
3575
3576 resultData->objectToWorld0 = tcu::Vec3(transform.matrix[0][0], transform.matrix[1][0], transform.matrix[2][0]);
3577 resultData->objectToWorld1 = tcu::Vec3(transform.matrix[0][1], transform.matrix[1][1], transform.matrix[2][1]);
3578 resultData->objectToWorld2 = tcu::Vec3(transform.matrix[0][2], transform.matrix[1][2], transform.matrix[2][2]);
3579 resultData->objectToWorld3 = tcu::Vec3(transform.matrix[0][3], transform.matrix[1][3], transform.matrix[2][3]);
3580
3581 resultData->worldToObject0 = tcu::Vec3(transform.matrix[0][0], transform.matrix[0][1], transform.matrix[0][2]);
3582 resultData->worldToObject1 = tcu::Vec3(transform.matrix[1][0], transform.matrix[1][1], transform.matrix[1][2]);
3583 resultData->worldToObject2 = tcu::Vec3(transform.matrix[2][0], transform.matrix[2][1], transform.matrix[2][2]);
3584 resultData->worldToObject3 = tcu::Vec3(-transform.matrix[0][3], -transform.matrix[1][3], -transform.matrix[2][3]);
3585 }
3586 else if (m_data.id == TEST_ID_TMINMAX_INDIRECT)
3587 {
3588 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(sizeof(TMinMaxResultData) * m_numGeoms * m_primsPerGeometry, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3589 m_resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
3590
3591 TMinMaxResultData* resultData = (TMinMaxResultData*)m_resultBuffer->getAllocation().getHostPtr();
3592 *resultData = {};
3593 {
3594 tcu::Vec3 center = aabb ?
3595 (m_geomData[0][0] + m_geomData[0][1]) * 0.5f :
3596 (m_geomData[0][0] + m_geomData[0][1] + m_geomData[0][2]) * (1.0f / 3.0f);
3597
3598 Ray r;
3599
3600 r.o = tcu::Vec3(center[0], center[1], 0.0f);
3601 r.d = tcu::Vec3(0.0f, 0.0f, 1.0f);
3602 r.tmin = 0.05f;
3603 r.tmax = 1000.0f;
3604
3605 if (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR)
3606 {
3607 r.d[2] = -1.0f;
3608 }
3609
3610 resultData->ray = r;
3611 }
3612
3613 resultData->miss_maxt = resultData->ray.tmax;
3614 resultData->isect_maxt = resultData->ray.tmax;
3615 resultData->chit_maxt = aabb ? 1.5f : 1.0f;
3616 resultData->ahit_maxt = aabb ? 1.5f : 1.0f;
3617 resultData->isect_maxt = resultData->ray.tmax;
3618 resultData->debug = -2.0f;
3619 }
3620 else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_INDIRECT)
3621 {
3622 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(sizeof(IncomingFlagsResultData), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3623 m_resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
3624
3625 IncomingFlagsResultData* resultData = (IncomingFlagsResultData*)m_resultBuffer->getAllocation().getHostPtr();
3626 *resultData = {};
3627
3628 for (deUint32 i = 0; i < 2; ++i)
3629 {
3630 tcu::Vec3 center = aabb ?
3631 (m_geomData[0][0] + m_geomData[0][1]) * 0.5f :
3632 (m_geomData[0][0] + m_geomData[0][1] + m_geomData[0][2]) * (1.0f / 3.0f);
3633
3634 Ray r;
3635
3636 r.o = tcu::Vec3(center[0], center[1], 0.0f);
3637 r.d = tcu::Vec3(0.0f, 0.0f, (i == 0) ? -1.0f : 1.0f);
3638 r.tmin = 0.05f;
3639 r.tmax = 1000.0f;
3640
3641 resultData->ray[i] = r;
3642 }
3643
3644 if (m_data.opaque)
3645 resultData->flags |= (1 << RAY_FLAG_BIT_OPAQUE_EXT);
3646 if (m_data.skipClosestHit)
3647 resultData->flags |= (1 << RAY_FLAG_BIT_SKIP_CLOSEST_HIT_SHADER_EXT);
3648 }
3649 else if (m_data.id == TEST_ID_HIT_KIND_INDIRECT)
3650 {
3651 const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(sizeof(HitKindResultData), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3652 m_resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
3653
3654 HitKindResultData* resultData = (HitKindResultData*)m_resultBuffer->getAllocation().getHostPtr();
3655 *resultData = {};
3656
3657 for (deUint32 i = 0; i < 2; ++i)
3658 {
3659 tcu::Vec3 center = aabb ?
3660 (m_geomData[0][0] + m_geomData[0][1]) * 0.5f :
3661 (m_geomData[0][0] + m_geomData[0][1] + m_geomData[0][2]) * (1.0f / 3.0f);
3662
3663 Ray r;
3664
3665 r.o = tcu::Vec3(center[0], center[1], 0.0f);
3666 r.d = tcu::Vec3(0.0f, 0.0f, (i == 1) ? -1.0f : 1.0f);
3667
3668 if (i == 1)
3669 r.o += tcu::Vec3(0, 0, 100.0f);
3670
3671 r.tmin = 0.05f;
3672 r.tmax = 1000.0f;
3673
3674 resultData->ray[i] = r;
3675 }
3676
3677 resultData->kind[0] = 255;
3678 resultData->kind[1] = 254;
3679 }
3680 }
3681
verifyResults()3682 bool RayTracingIndirectTestInstance::verifyResults()
3683 {
3684 const bool aabb = (m_data.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR);
3685
3686 if (m_data.id == TEST_ID_INDICES_INDIRECT)
3687 {
3688 deUint32* resultData = (deUint32*)m_resultBuffer->getAllocation().getHostPtr();
3689 for (deUint32 r = 0; r < m_numGeoms * m_primsPerGeometry; ++r)
3690 {
3691 deUint32 primitiveId = r % m_primsPerGeometry;
3692 deUint32 instanceId = (r / m_primsPerGeometry) / m_geomsPerInstance;
3693 deUint32 instanceCustomIndex = 1000 + instanceId;
3694
3695 if (resultData[4 * r + 0] != primitiveId)
3696 return false;
3697
3698 if (resultData[4 * r + 2] != instanceId)
3699 return false;
3700
3701 if (resultData[4 * r + 3] != instanceCustomIndex)
3702 return false;
3703 }
3704 }
3705 else if (m_data.id == TEST_ID_TRANSFORMS_INDIRECT)
3706 {
3707 TransformResultData* resultData = (TransformResultData*)m_resultBuffer->getAllocation().getHostPtr();
3708 if (resultData->anyHitResult != 1 || resultData->closestHitResult != 1)
3709 {
3710 return false;
3711 }
3712
3713 if (aabb && resultData->isectResult != 1)
3714 {
3715 return false;
3716 }
3717 }
3718 else if (m_data.id == TEST_ID_TMINMAX_INDIRECT)
3719 {
3720 TMinMaxResultData* resultData = (TMinMaxResultData*)m_resultBuffer->getAllocation().getHostPtr();
3721 if (resultData->anyHitResult != 1 || resultData->closestHitResult != 1)
3722 {
3723 return false;
3724 }
3725
3726 if (aabb && resultData->isectResult != 1)
3727 {
3728 return false;
3729 }
3730 }
3731 else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_INDIRECT)
3732 {
3733 IncomingFlagsResultData* resultData = (IncomingFlagsResultData*)m_resultBuffer->getAllocation().getHostPtr();
3734
3735 deUint32 miss[2] = { 1, 0 };
3736 deUint32 chitMin[2] = { 0, 1 };
3737 deUint32 chitMax[2] = { 0, 1 };
3738 deUint32 ahitMin[2] = { 0, 1 };
3739 deUint32 ahitMax[2] = { 0, 2 };
3740 deUint32 isectMin[2] = { 0, 0 };
3741 deUint32 isectMax[2] = { 0, 0 };
3742
3743 if (aabb)
3744 {
3745 isectMin[1] = 1;
3746 isectMax[1] = 2;
3747 }
3748
3749 if (m_data.opaque)
3750 {
3751 ahitMin[1] = 0;
3752 ahitMax[1] = 0;
3753 }
3754
3755 if (m_data.skipClosestHit)
3756 {
3757 chitMin[1] = 0;
3758 chitMax[1] = 0;
3759 }
3760
3761 for (deUint32 i = 0; i < 2; ++i)
3762 {
3763 if (resultData->miss[i] != miss[i])
3764 return false;
3765 if (resultData->chit[i] < chitMin[i])
3766 return false;
3767 if (resultData->chit[i] > chitMax[i])
3768 return false;
3769 if (resultData->ahit[i] < ahitMin[i])
3770 return false;
3771 if (resultData->ahit[i] > ahitMax[i])
3772 return false;
3773 if (resultData->isect[i] < isectMin[i])
3774 return false;
3775 if (resultData->isect[i] > isectMax[i])
3776 return false;
3777 }
3778 }
3779 else if (m_data.id == TEST_ID_HIT_KIND_INDIRECT)
3780 {
3781 HitKindResultData* resultData = (HitKindResultData*)m_resultBuffer->getAllocation().getHostPtr();
3782 for (deUint32 i = 0; i < 2; ++i)
3783 {
3784 if (resultData->chit[i] != 1)
3785 return false;
3786
3787 if (resultData->ahit[i] != 1)
3788 return false;
3789 }
3790 }
3791 else
3792 {
3793 return false;
3794 }
3795 return true;
3796 }
3797
iterate(void)3798 tcu::TestStatus RayTracingIndirectTestInstance::iterate (void)
3799 {
3800 const VkDevice device = m_context.getDevice();
3801 const DeviceInterface& vk = m_context.getDeviceInterface();
3802 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3803 Allocator& allocator = m_context.getDefaultAllocator();
3804
3805 const bool aabb = (m_data.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR);
3806
3807 vk::Move<VkDescriptorPool> descriptorPool;
3808 vk::Move<VkDescriptorSetLayout> descriptorSetLayout;
3809 std::vector<vk::Move<VkDescriptorSet>> descriptorSet;
3810 vk::Move<VkPipelineLayout> pipelineLayout;
3811
3812 createPipelineLayoutAndSet(1u, descriptorPool, descriptorSetLayout, descriptorSet, pipelineLayout);
3813
3814 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> blas = initBottomAccelerationStructures();
3815
3816 de::SharedPtr<TopLevelAccelerationStructure> tlas = initTopAccelerationStructure(blas);
3817
3818 de::MovePtr<RayTracingPipeline> rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
3819 Move<VkPipeline> pipeline = createPipelineAndShaderBindingTables(rayTracingPipeline, aabb, *pipelineLayout);
3820
3821 initializeParameters();
3822
3823 const VkDescriptorBufferInfo resultDescriptorInfo = makeDescriptorBufferInfo(m_resultBuffer->get(), 0, VK_WHOLE_SIZE);
3824
3825 const Move<VkCommandPool> cmdPool = createCommandPool(vk, device, 0, queueFamilyIndex);
3826 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3827
3828 beginCommandBuffer(vk, *cmdBuffer);
3829
3830 for (const auto& accel : blas)
3831 {
3832 accel->createAndBuild(vk, device, *cmdBuffer, allocator);
3833 }
3834 tlas->createAndBuild(vk, device, *cmdBuffer, allocator);
3835
3836 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
3837 {
3838 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
3839 DE_NULL, // const void* pNext;
3840 1u, // deUint32 accelerationStructureCount;
3841 tlas->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures;
3842 };
3843
3844 if (m_rayBuffer)
3845 {
3846 const VkDescriptorBufferInfo rayDescriptorInfo = makeDescriptorBufferInfo(m_rayBuffer->get(), 0, VK_WHOLE_SIZE);
3847
3848 DescriptorSetUpdateBuilder()
3849 .writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultDescriptorInfo)
3850 .writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
3851 .writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &rayDescriptorInfo)
3852 .update(vk, device);
3853 }
3854 else
3855 {
3856 DescriptorSetUpdateBuilder()
3857 .writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultDescriptorInfo)
3858 .writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
3859 .update(vk, device);
3860 }
3861
3862 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet[0].get(), 0, DE_NULL);
3863
3864 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipeline);
3865
3866 deUint32 rayCount = m_numGeoms * m_primsPerGeometry;
3867 if (m_data.id == TEST_ID_HIT_KIND_INDIRECT)
3868 {
3869 rayCount *= 2;
3870 }
3871
3872 VkAccelerationStructureBuildRangeInfoKHR buildRangeInfo = { rayCount, 1, 1, 0};
3873
3874 VkBufferCreateInfo indirectBufferCreateInfo = makeBufferCreateInfo(sizeof(VkAccelerationStructureBuildRangeInfoKHR), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
3875 de::MovePtr<BufferWithMemory> indirectBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, indirectBufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::DeviceAddress));
3876
3877 deMemcpy(indirectBuffer->getAllocation().getHostPtr(), (void*)&buildRangeInfo, sizeof(VkAccelerationStructureBuildRangeInfoKHR));
3878 invalidateMappedMemoryRange(vk, device, indirectBuffer->getAllocation().getMemory(), indirectBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
3879
3880 cmdTraceRaysIndirect(vk, *cmdBuffer, &m_raygenShaderBindingTableRegion, &m_missShaderBindingTableRegion, &m_hitShaderBindingTableRegion, &m_callableShaderBindingTableRegion, getBufferDeviceAddress(vk, device, indirectBuffer->get(), 0));
3881
3882 endCommandBuffer(vk, *cmdBuffer);
3883
3884 submitCommandsAndWait(vk, device, m_context.getUniversalQueue(), *cmdBuffer);
3885
3886 invalidateMappedMemoryRange(vk, device, m_resultBuffer->getAllocation().getMemory(), m_resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
3887
3888 return verifyResults() ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Invalid results");
3889 }
3890
3891 static const struct Stages
3892 {
3893 const char* name;
3894 VkShaderStageFlagBits stage;
3895 }
3896 stages[]
3897 {
3898 { "rgen", VK_SHADER_STAGE_RAYGEN_BIT_KHR },
3899 { "ahit", VK_SHADER_STAGE_ANY_HIT_BIT_KHR },
3900 { "chit", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR },
3901 { "sect", VK_SHADER_STAGE_INTERSECTION_BIT_KHR },
3902 { "miss", VK_SHADER_STAGE_MISS_BIT_KHR },
3903 { "call", VK_SHADER_STAGE_CALLABLE_BIT_KHR },
3904 };
3905
3906 static const struct GeomTypes
3907 {
3908 const char* name;
3909 GeomType geomType;
3910 }
3911 geomTypes[] =
3912 {
3913 { "triangles", GEOM_TYPE_TRIANGLES },
3914 { "aabs", GEOM_TYPE_AABBS },
3915 };
3916
createLaunchTests(tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)3917 void createLaunchTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)
3918 {
3919 const struct
3920 {
3921 deUint32 width;
3922 deUint32 height;
3923 deUint32 depth;
3924 }
3925 sizes[] =
3926 {
3927 { 1, 1, 1 },
3928 { 16, 16, 16 },
3929 { 256, 256, 1 },
3930 { 16384, 1, 1 },
3931 { 1, 16384, 1 },
3932 { 1, 1, 16384 },
3933 { 128, 128, 128 },
3934 { 2048, 4096, 1 },
3935 { 317, 3331, 1 },
3936 { 1, 1331, 111 },
3937 };
3938
3939 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, de::toLower(name).c_str()));
3940
3941 for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
3942 {
3943 if ((shaderStageFlags & stages[stageNdx].stage) == 0)
3944 continue;
3945
3946 for (size_t sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
3947 {
3948 const deUint32 width = sizes[sizeNdx].width;
3949 const deUint32 height = sizes[sizeNdx].height;
3950 const deUint32 depth = sizes[sizeNdx].depth;
3951 const bool plain = isPlain(width, height, depth);
3952 const deUint32 k = (plain ? 1 : 6);
3953 const deUint32 largestGroup = k * width * height * depth;
3954 const deUint32 squaresGroupCount = largestGroup;
3955 const deUint32 geometriesGroupCount = 1;
3956 const deUint32 instancesGroupCount = 1;
3957 const CaseDef caseDef =
3958 {
3959 id, // TestId id;
3960 name, // const char* name;
3961 width, // deUint32 width;
3962 height, // deUint32 height;
3963 depth, // deUint32 depth;
3964 depth, // deUint32 raysDepth;
3965 VK_FORMAT_R32_SINT, // VkFormat format;
3966 false, // bool fixedPointScalarOutput;
3967 false, // bool fixedPointVectorOutput;
3968 false, // bool fixedPointMatrixOutput;
3969 GEOM_TYPE_TRIANGLES, // GeomType geomType;
3970 squaresGroupCount, // deUint32 squaresGroupCount;
3971 geometriesGroupCount, // deUint32 geometriesGroupCount;
3972 instancesGroupCount, // deUint32 instancesGroupCount;
3973 stages[stageNdx].stage, // VkShaderStageFlagBits stage;
3974 false, // bool skipTriangles;
3975 false, // bool skipAABSs;
3976 false, // bool opaque;
3977 false, // bool frontFace;
3978 0u, // VkPipelineCreateFlags pipelineCreateFlags;
3979 false, // bool useSpecConstants;
3980 false, // bool skipClosestHit;
3981 false, // bool useMaintenance5;
3982 };
3983 const std::string suffix = de::toString(caseDef.width) + '_' + de::toString(caseDef.height) + '_' + de::toString(caseDef.depth);
3984 const std::string testName = string(stages[stageNdx].name) + '_' + suffix;
3985
3986 group->addChild(new RayTracingTestCase(testCtx, testName.c_str(), caseDef));
3987 }
3988 }
3989
3990 builtinGroup->addChild(group.release());
3991 }
3992
createScalarTests(tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)3993 void createScalarTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)
3994 {
3995 const struct
3996 {
3997 deUint32 width;
3998 deUint32 height;
3999 TestId id;
4000 }
4001 sizes[] =
4002 {
4003 { 16, 16, TEST_ID_HIT_KIND_EXT },
4004 { 16, 16, TEST_ID_HIT_T_EXT },
4005 { 16, 16, TEST_ID_RAY_T_MIN_EXT },
4006 { 16, 16, TEST_ID_RAY_T_MAX_EXT },
4007 { 32, 32, TEST_ID_LAST },
4008 { 64, 64, TEST_ID_LAST },
4009 { 256, 256, TEST_ID_LAST },
4010 };
4011 const bool fourGeometryGroups = id == TEST_ID_HIT_KIND_EXT
4012 || id == TEST_ID_HIT_T_EXT
4013 || id == TEST_ID_RAY_T_MIN_EXT
4014 || id == TEST_ID_RAY_T_MAX_EXT;
4015 const bool fixedPointScalarOutput = id == TEST_ID_HIT_T_EXT
4016 || id == TEST_ID_RAY_T_MIN_EXT
4017 || id == TEST_ID_RAY_T_MAX_EXT;
4018 const deUint32 imageDepth = 1;
4019 const deUint32 rayDepth = 1;
4020
4021 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, de::toLower(name).c_str()));
4022
4023 for (size_t geomTypesNdx = 0; geomTypesNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypesNdx)
4024 for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
4025 {
4026 const GeomType geomType = geomTypes[geomTypesNdx].geomType;
4027
4028 if ((shaderStageFlags & stages[stageNdx].stage) == 0)
4029 continue;
4030
4031 if (stages[stageNdx].stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR && geomTypes[geomTypesNdx].geomType == GEOM_TYPE_TRIANGLES)
4032 continue;
4033
4034 bool testAdded = false;
4035 bool generalTestsStarted = false;
4036
4037 for (size_t sizesNdx = 0; sizesNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizesNdx)
4038 {
4039 const bool specializedTest = (sizes[sizesNdx].id != TEST_ID_LAST);
4040 const deUint32 width = sizes[sizesNdx].width;
4041 const deUint32 height = sizes[sizesNdx].height;
4042 const deUint32 instancesGroupCount = fourGeometryGroups ? 1 : 4;
4043 const deUint32 geometriesGroupCount = fourGeometryGroups ? 4 : 8;
4044 const deUint32 largestGroup = width * height / geometriesGroupCount / instancesGroupCount;
4045 const deUint32 squaresGroupCount = largestGroup;
4046 const CaseDef caseDef =
4047 {
4048 id, // TestId id;
4049 name, // const char* name;
4050 width, // deUint32 width;
4051 height, // deUint32 height;
4052 imageDepth, // deUint32 depth;
4053 rayDepth, // deUint32 raysDepth;
4054 VK_FORMAT_R32_SINT, // VkFormat format;
4055 fixedPointScalarOutput, // bool fixedPointScalarOutput;
4056 false, // bool fixedPointVectorOutput;
4057 false, // bool fixedPointMatrixOutput;
4058 geomType, // GeomType geomType;
4059 squaresGroupCount, // deUint32 squaresGroupCount;
4060 geometriesGroupCount, // deUint32 geometriesGroupCount;
4061 instancesGroupCount, // deUint32 instancesGroupCount;
4062 stages[stageNdx].stage, // VkShaderStageFlagBits stage;
4063 false, // bool skipTriangles;
4064 false, // bool skipAABSs;
4065 false, // bool opaque;
4066 false, // bool frontFace;
4067 0u, // VkPipelineCreateFlags pipelineCreateFlags;
4068 false, // bool useSpecConstants;
4069 false, // bool skipClosestHit;
4070 false, // bool useMaintenance5;
4071 };
4072 const std::string suffix = '_' + de::toString(caseDef.width) + '_' + de::toString(caseDef.height);
4073 const std::string testName = string(stages[stageNdx].name) + '_' + geomTypes[geomTypesNdx].name + (specializedTest ? "" : suffix);
4074
4075 if (specializedTest)
4076 {
4077 DE_UNREF(generalTestsStarted);
4078 DE_ASSERT(!generalTestsStarted);
4079
4080 if (sizes[sizesNdx].id != id)
4081 continue;
4082 }
4083 else
4084 {
4085 generalTestsStarted = true;
4086 }
4087
4088 group->addChild(new RayTracingTestCase(testCtx, testName.c_str(), caseDef));
4089 testAdded = true;
4090
4091 if (specializedTest)
4092 break;
4093 }
4094
4095 DE_ASSERT(testAdded);
4096 DE_UNREF(testAdded);
4097 }
4098
4099 builtinGroup->addChild(group.release());
4100 }
4101
createRayFlagsTests(tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)4102 void createRayFlagsTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)
4103 {
4104 const deUint32 width = 16;
4105 const deUint32 height = 16;
4106 const deUint32 imageDepth = 1;
4107 const deUint32 rayDepth = 1;
4108
4109 const struct Opaques
4110 {
4111 const char* name;
4112 bool flag;
4113 }
4114 opaques[] =
4115 {
4116 { "opaque", true },
4117 { "noopaque", false },
4118 };
4119 const struct Faces
4120 {
4121 const char* name;
4122 bool flag;
4123 }
4124 faces[] =
4125 {
4126 { "frontface", true },
4127 { "backface", false },
4128 };
4129 const struct SkipRayFlags
4130 {
4131 const char* name;
4132 bool skipTriangles;
4133 bool skipAABBs;
4134 }
4135 skipRayFlags[] =
4136 {
4137 { "raynoskipflags", false, false },
4138 { "rayskiptriangles", true, false },
4139 { "rayskipaabbs", false, true },
4140 };
4141 const struct PipelineFlags
4142 {
4143 const char* name;
4144 VkPipelineCreateFlags flag;
4145 }
4146 pipelineFlags[] =
4147 {
4148 { "pipelinenoskipflags", static_cast<VkPipelineCreateFlags>(0) },
4149 { "pipelineskiptriangles", VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR },
4150 { "pipelineskipaabbs", VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR },
4151 };
4152
4153 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, de::toLower(name).c_str()));
4154
4155 for (size_t geomTypesNdx = 0; geomTypesNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypesNdx)
4156 {
4157 const GeomType geomType = geomTypes[geomTypesNdx].geomType;
4158 de::MovePtr<tcu::TestCaseGroup> geomGroup (new tcu::TestCaseGroup(testCtx, geomTypes[geomTypesNdx].name));
4159
4160 for (size_t skipRayFlagsNdx = 0; skipRayFlagsNdx < DE_LENGTH_OF_ARRAY(skipRayFlags); ++skipRayFlagsNdx)
4161 {
4162 de::MovePtr<tcu::TestCaseGroup> rayFlagsGroup (new tcu::TestCaseGroup(testCtx, skipRayFlags[skipRayFlagsNdx].name));
4163
4164 for (size_t pipelineFlagsNdx = 0; pipelineFlagsNdx < DE_LENGTH_OF_ARRAY(pipelineFlags); ++pipelineFlagsNdx)
4165 {
4166 const bool skipTriangles = (skipRayFlags[skipRayFlagsNdx].skipTriangles || (pipelineFlags[pipelineFlagsNdx].flag & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR));
4167 const bool skipAABBs = (skipRayFlags[skipRayFlagsNdx].skipAABBs || (pipelineFlags[pipelineFlagsNdx].flag & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR));
4168
4169 // Skipping both triangles and AABBs is not legal according to the spec.
4170 if (skipTriangles && skipAABBs)
4171 continue;
4172
4173 // Skipping - SkipTrianglesKHR is mutually exclusive with CullBackFacingTrianglesKHR and CullFrontFacingTrianglesKHR
4174 if ((geomTypes[geomTypesNdx].geomType == GEOM_TYPE_TRIANGLES) && skipRayFlags[skipRayFlagsNdx].skipTriangles &&
4175 (pipelineFlags[pipelineFlagsNdx].flag == static_cast<VkPipelineCreateFlags>(0)))
4176 {
4177 continue;
4178 }
4179
4180 de::MovePtr<tcu::TestCaseGroup> pipelineFlagsGroup (new tcu::TestCaseGroup(testCtx, pipelineFlags[pipelineFlagsNdx].name));
4181
4182 for (size_t opaquesNdx = 0; opaquesNdx < DE_LENGTH_OF_ARRAY(opaques); ++opaquesNdx)
4183 for (size_t facesNdx = 0; facesNdx < DE_LENGTH_OF_ARRAY(faces); ++facesNdx)
4184 {
4185 const std::string geomPropertiesGroupName = string(opaques[opaquesNdx].name) + '_' + string(faces[facesNdx].name);
4186 de::MovePtr<tcu::TestCaseGroup> geomPropertiesGroup (new tcu::TestCaseGroup(testCtx, geomPropertiesGroupName.c_str()));
4187
4188 for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
4189 {
4190 if ((shaderStageFlags & stages[stageNdx].stage) == 0)
4191 continue;
4192
4193 if (stages[stageNdx].stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR && geomTypes[geomTypesNdx].geomType == GEOM_TYPE_TRIANGLES)
4194 continue;
4195
4196 const deUint32 instancesGroupCount = 1;
4197 const deUint32 geometriesGroupCount = 1;
4198 const deUint32 squaresGroupCount = width * height / geometriesGroupCount / instancesGroupCount;
4199 const CaseDef caseDef =
4200 {
4201 id, // TestId id;
4202 name, // const char* name;
4203 width, // deUint32 width;
4204 height, // deUint32 height;
4205 imageDepth, // deUint32 depth;
4206 rayDepth, // deUint32 raysDepth;
4207 VK_FORMAT_R32_SINT, // VkFormat format;
4208 false, // bool fixedPointScalarOutput;
4209 false, // bool fixedPointVectorOutput;
4210 false, // bool fixedPointMatrixOutput;
4211 geomType, // GeomType geomType;
4212 squaresGroupCount, // deUint32 squaresGroupCount;
4213 geometriesGroupCount, // deUint32 geometriesGroupCount;
4214 instancesGroupCount, // deUint32 instancesGroupCount;
4215 stages[stageNdx].stage, // VkShaderStageFlagBits stage;
4216 skipRayFlags[skipRayFlagsNdx].skipTriangles, // bool skipTriangles;
4217 skipRayFlags[skipRayFlagsNdx].skipAABBs, // bool skipAABSs;
4218 opaques[opaquesNdx].flag, // bool opaque;
4219 faces[facesNdx].flag, // bool frontFace;
4220 pipelineFlags[pipelineFlagsNdx].flag, // VkPipelineCreateFlags pipelineCreateFlags;
4221 false, // bool useSpecConstants;
4222 false, // bool skipClosestHit;
4223 false, // bool useMaintenance5;
4224 };
4225 const std::string testName = string(stages[stageNdx].name) ;
4226
4227 geomPropertiesGroup->addChild(new RayTracingTestCase(testCtx, testName.c_str(), caseDef));
4228 }
4229
4230 pipelineFlagsGroup->addChild(geomPropertiesGroup.release());
4231 }
4232
4233 rayFlagsGroup->addChild(pipelineFlagsGroup.release());
4234 }
4235
4236 geomGroup->addChild(rayFlagsGroup.release());
4237 }
4238
4239 group->addChild(geomGroup.release());
4240 }
4241
4242 {
4243 de::MovePtr<tcu::TestCaseGroup> miscGroup(new tcu::TestCaseGroup(testCtx, "misc", ""));
4244 CaseDef caseDef
4245 {
4246 TEST_ID_INCOMING_RAY_FLAGS_EXT, // TestId id;
4247 name, // const char* name;
4248 width, // deUint32 width;
4249 height, // deUint32 height;
4250 imageDepth, // deUint32 depth;
4251 rayDepth, // deUint32 raysDepth;
4252 VK_FORMAT_R32_SINT, // VkFormat format;
4253 false, // bool fixedPointScalarOutput;
4254 false, // bool fixedPointVectorOutput;
4255 false, // bool fixedPointMatrixOutput;
4256 GEOM_TYPE_TRIANGLES, // GeomType geomType;
4257 width * height, // deUint32 squaresGroupCount;
4258 1, // deUint32 geometriesGroupCount;
4259 1, // deUint32 instancesGroupCount;
4260 VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, // VkShaderStageFlagBits stage;
4261 false, // bool skipTriangles;
4262 false, // bool skipAABSs;
4263 false, // bool opaque;
4264 true, // bool frontFace;
4265 VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR, // VkPipelineCreateFlags pipelineCreateFlags;
4266 false, // bool useSpecConstants;
4267 false, // bool skipClosestHit;
4268 true, // bool useMaintenance5;
4269 };
4270
4271 miscGroup->addChild(new RayTracingTestCase(testCtx, "pipelineskiptriangles_maintenance5", caseDef));
4272 caseDef.pipelineCreateFlags = VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR;
4273 miscGroup->addChild(new RayTracingTestCase(testCtx, "pipelineskipaabbs_maintenance5", caseDef));
4274
4275 group->addChild(miscGroup.release());
4276 }
4277
4278 builtinGroup->addChild(group.release());
4279 }
4280
createMultiOutputTests(tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)4281 void createMultiOutputTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)
4282 {
4283 const bool fixedPointVectorOutput = id == TEST_ID_WORLD_RAY_ORIGIN_EXT
4284 || id == TEST_ID_WORLD_RAY_DIRECTION_EXT
4285 || id == TEST_ID_OBJECT_RAY_ORIGIN_EXT
4286 || id == TEST_ID_OBJECT_RAY_DIRECTION_EXT;
4287 const bool fixedPointMatrixOutput = id == TEST_ID_OBJECT_TO_WORLD_EXT
4288 || id == TEST_ID_WORLD_TO_OBJECT_EXT
4289 || id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT
4290 || id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT;
4291 const deUint32 imageDepth = fixedPointMatrixOutput ? 4 * 4
4292 : fixedPointVectorOutput ? 4
4293 : 0;
4294 const deUint32 rayDepth = 1;
4295
4296 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, de::toLower(name).c_str()));
4297
4298 DE_ASSERT(imageDepth != 0);
4299
4300 for (size_t geomTypesNdx = 0; geomTypesNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypesNdx)
4301 for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
4302 {
4303 const GeomType geomType = geomTypes[geomTypesNdx].geomType;
4304
4305 if ((shaderStageFlags & stages[stageNdx].stage) == 0)
4306 continue;
4307
4308 if (stages[stageNdx].stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR && geomTypes[geomTypesNdx].geomType == GEOM_TYPE_TRIANGLES)
4309 continue;
4310
4311 const deUint32 width = 4;
4312 const deUint32 height = 4;
4313 const deUint32 instancesGroupCount = 4;
4314 const deUint32 geometriesGroupCount = 1;
4315 const deUint32 largestGroup = width * height / geometriesGroupCount / instancesGroupCount;
4316 const deUint32 squaresGroupCount = largestGroup;
4317 const CaseDef caseDef =
4318 {
4319 id, // TestId id;
4320 name, // const char* name;
4321 width, // deUint32 width;
4322 height, // deUint32 height;
4323 imageDepth, // deUint32 depth;
4324 rayDepth, // deUint32 raysDepth;
4325 VK_FORMAT_R32_SINT, // VkFormat format;
4326 false, // bool fixedPointScalarOutput;
4327 fixedPointVectorOutput, // bool fixedPointVectorOutput;
4328 fixedPointMatrixOutput, // bool fixedPointMatrixOutput;
4329 geomType, // GeomType geomType;
4330 squaresGroupCount, // deUint32 squaresGroupCount;
4331 geometriesGroupCount, // deUint32 geometriesGroupCount;
4332 instancesGroupCount, // deUint32 instancesGroupCount;
4333 stages[stageNdx].stage, // VkShaderStageFlagBits stage;
4334 false, // bool rayFlagSkipTriangles;
4335 false, // bool rayFlagSkipAABSs;
4336 false, // bool opaque;
4337 false, // bool frontFace;
4338 0u, // VkPipelineCreateFlags pipelineCreateFlags;
4339 false, // bool useSpecConstants;
4340 false, // bool skipClosestHit;
4341 false, // bool useMaintenance5;
4342 };
4343 const std::string testName = string(stages[stageNdx].name) + '_' + geomTypes[geomTypesNdx].name;
4344
4345 group->addChild(new RayTracingTestCase(testCtx, testName.c_str(), caseDef));
4346 }
4347
4348 builtinGroup->addChild(group.release());
4349 }
4350
createIndirectTestCases(tcu::TestContext& testCtx, tcu::TestCaseGroup* indirectGroup, TestId id, const char* name)4351 void createIndirectTestCases(tcu::TestContext& testCtx, tcu::TestCaseGroup* indirectGroup, TestId id, const char* name)
4352 {
4353 const struct
4354 {
4355 VkShaderStageFlagBits stage;
4356 const char* name;
4357 }
4358 types[] =
4359 {
4360 { VK_SHADER_STAGE_RAYGEN_BIT_KHR, "triangles" },
4361 { VK_SHADER_STAGE_INTERSECTION_BIT_KHR, "aabbs" },
4362 };
4363
4364 const CaseDef caseDef =
4365 {
4366 id, // TestId id;
4367 "", // const char* name;
4368 0, // deUint32 width;
4369 0, // deUint32 height;
4370 0, // deUint32 depth;
4371 0, // deUint32 raysDepth;
4372 VK_FORMAT_R32_SINT, // VkFormat format;
4373 false, // bool fixedPointScalarOutput;
4374 false, // bool fixedPointVectorOutput;
4375 false, // bool fixedPointMatrixOutput;
4376 GEOM_TYPE_TRIANGLES, // GeomType geomType;
4377 0, // deUint32 squaresGroupCount;
4378 0, // deUint32 geometriesGroupCount;
4379 0, // deUint32 instancesGroupCount;
4380 VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM, // VkShaderStageFlagBits stage;
4381 false, // bool rayFlagSkipTriangles;
4382 false, // bool rayFlagSkipAABSs;
4383 false, // bool opaque;
4384 false, // bool frontFace;
4385 0u, // VkPipelineCreateFlags pipelineCreateFlags;
4386 false, // bool useSpecConstants;
4387 false, // bool skipClosestHit;
4388 false, // bool useMaintenance5;
4389 };
4390
4391 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, name));
4392
4393 for (size_t typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); ++typeNdx)
4394 {
4395 CaseDef params = caseDef;
4396 params.stage = types[typeNdx].stage;
4397 group->addChild(new RayTracingIndirectTestCase(testCtx, types[typeNdx].name, params));
4398 }
4399 indirectGroup->addChild(group.release());
4400 }
4401
createIndirectFlagsTestCases(tcu::TestContext& testCtx, tcu::TestCaseGroup* indirectGroup, TestId id, const char* name)4402 void createIndirectFlagsTestCases(tcu::TestContext& testCtx, tcu::TestCaseGroup* indirectGroup, TestId id, const char* name)
4403 {
4404 const struct
4405 {
4406 VkShaderStageFlagBits stage;
4407 const char* name;
4408 }
4409 types[] =
4410 {
4411 { VK_SHADER_STAGE_RAYGEN_BIT_KHR, "triangles" },
4412 { VK_SHADER_STAGE_INTERSECTION_BIT_KHR, "aabbs" },
4413 };
4414
4415 const struct
4416 {
4417 bool opaque;
4418 bool skipClosestHit;
4419 const char* name;
4420 }
4421 flags[] =
4422 {
4423 { false, false, "none" },
4424 { true, false, "opaque" },
4425 { false, true, "skip_closest_hit" },
4426 };
4427
4428 const CaseDef caseDef =
4429 {
4430 id, // TestId id;
4431 "", // const char* name;
4432 0, // deUint32 width;
4433 0, // deUint32 height;
4434 0, // deUint32 depth;
4435 0, // deUint32 raysDepth;
4436 VK_FORMAT_R32_SINT, // VkFormat format;
4437 false, // bool fixedPointScalarOutput;
4438 false, // bool fixedPointVectorOutput;
4439 false, // bool fixedPointMatrixOutput;
4440 GEOM_TYPE_TRIANGLES, // GeomType geomType;
4441 0, // deUint32 squaresGroupCount;
4442 0, // deUint32 geometriesGroupCount;
4443 0, // deUint32 instancesGroupCount;
4444 VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM, // VkShaderStageFlagBits stage;
4445 false, // bool rayFlagSkipTriangles;
4446 false, // bool rayFlagSkipAABSs;
4447 false, // bool opaque;
4448 false, // bool frontFace;
4449 0u, // VkPipelineCreateFlags pipelineCreateFlags;
4450 false, // bool useSpecConstants;
4451 false, // bool skipClosestHit;
4452 false, // bool useMaintenance5;
4453 };
4454
4455 de::MovePtr<tcu::TestCaseGroup> testGroup (new tcu::TestCaseGroup(testCtx, name));
4456
4457 for (size_t typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); ++typeNdx)
4458 {
4459 CaseDef params = caseDef;
4460 params.stage = types[typeNdx].stage;
4461 de::MovePtr<tcu::TestCaseGroup> typeGroup (new tcu::TestCaseGroup(testCtx, types[typeNdx].name));
4462
4463 for (size_t flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(flags); ++flagsNdx)
4464 {
4465 params.opaque = flags[flagsNdx].opaque;
4466 params.skipClosestHit = flags[flagsNdx].skipClosestHit;
4467 typeGroup->addChild(new RayTracingIndirectTestCase(testCtx, flags[flagsNdx].name, params));
4468 }
4469 testGroup->addChild(typeGroup.release());
4470 }
4471 indirectGroup->addChild(testGroup.release());
4472 }
4473
createIndirectTests(tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup)4474 void createIndirectTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup)
4475 {
4476 typedef void CreateIndirectTestsFunc (tcu::TestContext& testCtx, tcu::TestCaseGroup* group, TestId id, const char* name);
4477
4478 const struct
4479 {
4480 TestId id;
4481 const char* name;
4482 CreateIndirectTestsFunc* createTestsFunc;
4483 }
4484 tests[] =
4485 {
4486 { TEST_ID_INDICES_INDIRECT, "indices", createIndirectTestCases },
4487 { TEST_ID_TRANSFORMS_INDIRECT, "transforms", createIndirectTestCases },
4488 { TEST_ID_TMINMAX_INDIRECT, "t_min_max", createIndirectTestCases },
4489 { TEST_ID_INCOMING_RAY_FLAGS_INDIRECT, "incoming_flag",createIndirectFlagsTestCases },
4490 { TEST_ID_HIT_KIND_INDIRECT, "hit_kind", createIndirectTestCases },
4491 };
4492
4493 // Test builtins using indirect trace rays
4494 de::MovePtr<tcu::TestCaseGroup> indirectGroup (new tcu::TestCaseGroup(testCtx, "indirect"));
4495
4496 for (size_t testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
4497 {
4498 tests[testNdx].createTestsFunc(testCtx, indirectGroup.get(), tests[testNdx].id, tests[testNdx].name);
4499 }
4500 builtinGroup->addChild(indirectGroup.release());
4501 }
4502 } // anonymous
4503
createBuiltinTests(tcu::TestContext& testCtx)4504 tcu::TestCaseGroup* createBuiltinTests (tcu::TestContext& testCtx)
4505 {
4506 typedef void CreateBuiltinTestsFunc (tcu::TestContext& testCtx, tcu::TestCaseGroup* group, TestId id, const char* name, const VkShaderStageFlags);
4507
4508 const VkShaderStageFlagBits R = VK_SHADER_STAGE_RAYGEN_BIT_KHR;
4509 const VkShaderStageFlagBits A = VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
4510 const VkShaderStageFlagBits C = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
4511 const VkShaderStageFlagBits M = VK_SHADER_STAGE_MISS_BIT_KHR;
4512 const VkShaderStageFlagBits I = VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
4513 const VkShaderStageFlagBits L = VK_SHADER_STAGE_CALLABLE_BIT_KHR;
4514
4515 const struct
4516 {
4517 TestId id;
4518 const char* name;
4519 VkShaderStageFlags stages;
4520 CreateBuiltinTestsFunc* createBuiltinTestsFunc;
4521 }
4522 tests[] =
4523 {
4524 { TEST_ID_LAUNCH_ID_EXT, "LaunchIDEXT" , R | A | C | I | M | L , createLaunchTests },
4525 { TEST_ID_LAUNCH_SIZE_EXT, "LaunchSizeEXT" , R | A | C | I | M | L , createLaunchTests },
4526 { TEST_ID_PRIMITIVE_ID, "PrimitiveID" , A | C | I , createScalarTests },
4527 { TEST_ID_INSTANCE_ID, "InstanceID" , A | C | I , createScalarTests },
4528 { TEST_ID_INSTANCE_CUSTOM_INDEX_EXT, "InstanceCustomIndexEXT", A | C | I , createScalarTests },
4529 { TEST_ID_GEOMETRY_INDEX_EXT, "GeometryIndexEXT" , A | C | I , createScalarTests },
4530 { TEST_ID_WORLD_RAY_ORIGIN_EXT, "WorldRayOriginEXT" , A | C | I | M , createMultiOutputTests },
4531 { TEST_ID_WORLD_RAY_DIRECTION_EXT, "WorldRayDirectionEXT" , A | C | I | M , createMultiOutputTests },
4532 { TEST_ID_OBJECT_RAY_ORIGIN_EXT, "ObjectRayOriginEXT" , A | C | I , createMultiOutputTests },
4533 { TEST_ID_OBJECT_RAY_DIRECTION_EXT, "ObjectRayDirectionEXT" , A | C | I , createMultiOutputTests },
4534 { TEST_ID_RAY_T_MIN_EXT, "RayTminEXT" , A | C | I | M , createScalarTests },
4535 { TEST_ID_RAY_T_MAX_EXT, "RayTmaxEXT" , A | C | I | M , createScalarTests },
4536 { TEST_ID_INCOMING_RAY_FLAGS_EXT, "IncomingRayFlagsEXT" , A | C | I | M , createRayFlagsTests },
4537 { TEST_ID_HIT_T_EXT, "HitTEXT" , A | C , createScalarTests },
4538 { TEST_ID_HIT_KIND_EXT, "HitKindEXT" , A | C , createScalarTests },
4539 { TEST_ID_OBJECT_TO_WORLD_EXT, "ObjectToWorldEXT" , A | C | I , createMultiOutputTests },
4540 { TEST_ID_WORLD_TO_OBJECT_EXT, "WorldToObjectEXT" , A | C | I , createMultiOutputTests },
4541 { TEST_ID_OBJECT_TO_WORLD_3X4_EXT, "ObjectToWorld3x4EXT" , A | C | I , createMultiOutputTests },
4542 { TEST_ID_WORLD_TO_OBJECT_3X4_EXT, "WorldToObject3x4EXT" , A | C | I , createMultiOutputTests },
4543 };
4544
4545 de::MovePtr<tcu::TestCaseGroup> builtinGroup(new tcu::TestCaseGroup(testCtx, "builtin", "Ray tracing shader builtin tests"));
4546
4547 for (size_t testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
4548 {
4549 tests[testNdx].createBuiltinTestsFunc(testCtx, builtinGroup.get(), tests[testNdx].id, tests[testNdx].name, tests[testNdx].stages);
4550 }
4551
4552 {
4553 createIndirectTests(testCtx, builtinGroup.get());
4554 }
4555
4556 return builtinGroup.release();
4557 }
4558
createSpecConstantTests(tcu::TestContext& testCtx)4559 tcu::TestCaseGroup* createSpecConstantTests (tcu::TestContext& testCtx)
4560 {
4561 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "spec_constants", "Test using spec constants in ray tracing shader stages"));
4562
4563 const VkShaderStageFlags stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR
4564 | VK_SHADER_STAGE_ANY_HIT_BIT_KHR
4565 | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
4566 | VK_SHADER_STAGE_MISS_BIT_KHR
4567 | VK_SHADER_STAGE_INTERSECTION_BIT_KHR
4568 | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
4569 const deUint32 width = 256u;
4570 const deUint32 height = 256u;
4571 const deUint32 depth = 1u;
4572 const bool plain = isPlain(width, height, depth);
4573 const deUint32 k = (plain ? 1 : 6);
4574 const deUint32 largestGroup = k * width * height * depth;
4575 const deUint32 squaresGroupCount = largestGroup;
4576 const deUint32 geometriesGroupCount = 1;
4577 const deUint32 instancesGroupCount = 1;
4578
4579 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
4580 {
4581 if ((stageFlags & stages[stageNdx].stage) == 0)
4582 continue;
4583
4584 const CaseDef caseDef =
4585 {
4586 TEST_ID_LAUNCH_ID_EXT, // TestId id;
4587 "LaunchIDEXT", // const char* name;
4588 width, // deUint32 width;
4589 height, // deUint32 height;
4590 depth, // deUint32 depth;
4591 depth, // deUint32 raysDepth;
4592 VK_FORMAT_R32_SINT, // VkFormat format;
4593 false, // bool fixedPointScalarOutput;
4594 false, // bool fixedPointVectorOutput;
4595 false, // bool fixedPointMatrixOutput;
4596 GEOM_TYPE_TRIANGLES, // GeomType geomType;
4597 squaresGroupCount, // deUint32 squaresGroupCount;
4598 geometriesGroupCount, // deUint32 geometriesGroupCount;
4599 instancesGroupCount, // deUint32 instancesGroupCount;
4600 stages[stageNdx].stage, // VkShaderStageFlagBits stage;
4601 false, // bool skipTriangles;
4602 false, // bool skipAABSs;
4603 false, // bool opaque;
4604 false, // bool frontFace;
4605 0u, // VkPipelineCreateFlags pipelineCreateFlags;
4606 true, // bool useSpecConstants;
4607 false, // bool skipClosestHit;
4608 false, // bool useMaintenance5;
4609 };
4610
4611 group->addChild(new RayTracingTestCase(testCtx, stages[stageNdx].name, caseDef));
4612 }
4613
4614 return group.release();
4615 }
4616
4617 } // RayTracing
4618 } // vkt
4619