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
38 #include "vkRayTracingUtil.hpp"
39
40 #include "tcuTestLog.hpp"
41 #include "tcuMatrix.hpp"
42
43 #include "deMath.h"
44
45 namespace vkt
46 {
47 namespace RayTracing
48 {
49 namespace
50 {
51 using namespace vk;
52 using namespace std;
53
54 static const VkFlags ALL_RAY_TRACING_STAGES = VK_SHADER_STAGE_RAYGEN_BIT_KHR
55 | VK_SHADER_STAGE_ANY_HIT_BIT_KHR
56 | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
57 | VK_SHADER_STAGE_MISS_BIT_KHR
58 | VK_SHADER_STAGE_INTERSECTION_BIT_KHR
59 | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
60
61 enum GeomType
62 {
63 GEOM_TYPE_TRIANGLES,
64 GEOM_TYPE_AABBS,
65 };
66
67 enum TestId
68 {
69 TEST_ID_LAUNCH_ID_EXT = 0,
70 TEST_ID_LAUNCH_SIZE_EXT,
71 TEST_ID_PRIMITIVE_ID,
72 TEST_ID_INSTANCE_ID,
73 TEST_ID_INSTANCE_CUSTOM_INDEX_EXT,
74 TEST_ID_GEOMETRY_INDEX_EXT,
75 TEST_ID_WORLD_RAY_ORIGIN_EXT,
76 TEST_ID_WORLD_RAY_DIRECTION_EXT,
77 TEST_ID_OBJECT_RAY_ORIGIN_EXT,
78 TEST_ID_OBJECT_RAY_DIRECTION_EXT,
79 TEST_ID_RAY_T_MIN_EXT,
80 TEST_ID_RAY_T_MAX_EXT,
81 TEST_ID_INCOMING_RAY_FLAGS_EXT,
82 TEST_ID_HIT_T_EXT,
83 TEST_ID_HIT_KIND_EXT,
84 TEST_ID_OBJECT_TO_WORLD_EXT,
85 TEST_ID_OBJECT_TO_WORLD_3X4_EXT,
86 TEST_ID_WORLD_TO_OBJECT_EXT,
87 TEST_ID_WORLD_TO_OBJECT_3X4_EXT,
88 TEST_ID_LAST
89 };
90
91 enum RayFlagBits
92 {
93 RAY_FLAG_BIT_OPAQUE_EXT = 0, // const uint gl_RayFlagsOpaqueEXT = 1U;
94 RAY_FLAG_BIT_NO_OPAQUE_EXT = 1, // const uint gl_RayFlagsNoOpaqueEXT = 2U;
95 RAY_FLAG_BIT_TERMINATE_ON_FIRST_HIT_EXT = 2, // const uint gl_RayFlagsTerminateOnFirstHitEXT = 4U;
96 RAY_FLAG_BIT_SKIP_CLOSEST_HIT_SHADER_EXT = 3, // const uint gl_RayFlagsSkipClosestHitShaderEXT = 8U;
97 RAY_FLAG_BIT_CULL_BACK_FACING_TRIANGLES_EXT = 4, // const uint gl_RayFlagsCullBackFacingTrianglesEXT = 16U;
98 RAY_FLAG_BIT_CULL_FRONT_FACING_TRIANGLES_EXT = 5, // const uint gl_RayFlagsCullFrontFacingTrianglesEXT = 32U;
99 RAY_FLAG_BIT_CULL_OPAQUE_EXT = 6, // const uint gl_RayFlagsCullOpaqueEXT = 64U;
100 RAY_FLAG_BIT_CULL_NO_OPAQUE_EXT = 7, // const uint gl_RayFlagsCullNoOpaqueEXT = 128U;
101 RAY_FLAG_BIT_LAST_PER_TEST,
102 RAY_FLAG_BIT_SKIP_TRIANGLES_EXT = 8, // const uint gl_RayFlagsSkipTrianglesEXT = 256U;
103 RAY_FLAG_BIT_SKIP_AABB_EXT = 9, // const uint gl_RayFlagsSkipAABBEXT = 512U;
104 RAY_FLAG_BIT_LAST
105 };
106
107 struct CaseDef
108 {
109 TestId id;
110 const char* name;
111 deUint32 width;
112 deUint32 height;
113 deUint32 depth;
114 deUint32 raysDepth;
115 VkFormat format;
116 bool fixedPointScalarOutput;
117 bool fixedPointVectorOutput;
118 bool fixedPointMatrixOutput;
119 GeomType geomType;
120 deUint32 squaresGroupCount;
121 deUint32 geometriesGroupCount;
122 deUint32 instancesGroupCount;
123 VkShaderStageFlagBits stage;
124 bool rayFlagSkipTriangles;
125 bool rayFlagSkipAABSs;
126 bool opaque;
127 bool frontFace;
128 VkPipelineCreateFlags pipelineCreateFlags;
129 bool useSpecConstants;
130 };
131
132 const deUint32 DEFAULT_UINT_CLEAR_VALUE = 0x8000;
133 const deUint32 FIXED_POINT_DIVISOR = 1024 * 1024;
134 const deUint32 FIXED_POINT_ALLOWED_ERROR = 4;
135
isPlain(const deUint32 width,const deUint32 height,const deUint32 depth)136 bool isPlain (const deUint32 width, const deUint32 height, const deUint32 depth)
137 {
138 return (width == 1 || height == 1 || depth == 1);
139 }
140
getShaderGroupSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)141 deUint32 getShaderGroupSize (const InstanceInterface& vki,
142 const VkPhysicalDevice physicalDevice)
143 {
144 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
145
146 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
147 return rayTracingPropertiesKHR->getShaderGroupHandleSize();
148 }
149
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)150 deUint32 getShaderGroupBaseAlignment (const InstanceInterface& vki,
151 const VkPhysicalDevice physicalDevice)
152 {
153 de::MovePtr<RayTracingProperties> rayTracingPropertiesKHR;
154
155 rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
156 return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
157 }
158
makeImageCreateInfo(deUint32 width,deUint32 height,deUint32 depth,VkFormat format)159 VkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, deUint32 depth, VkFormat format)
160 {
161 const VkImageType imageType = VK_IMAGE_TYPE_3D;
162 const VkImageUsageFlags usage = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
163 const VkImageCreateInfo imageCreateInfo =
164 {
165 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
166 DE_NULL, // const void* pNext;
167 (VkImageCreateFlags)0u, // VkImageCreateFlags flags;
168 imageType, // VkImageType imageType;
169 format, // VkFormat format;
170 makeExtent3D(width, height, depth), // VkExtent3D extent;
171 1u, // deUint32 mipLevels;
172 1u, // deUint32 arrayLayers;
173 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
174 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
175 usage, // VkImageUsageFlags usage;
176 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
177 0u, // deUint32 queueFamilyIndexCount;
178 DE_NULL, // const deUint32* pQueueFamilyIndices;
179 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
180 };
181
182 return imageCreateInfo;
183 }
184
185 class RayTracingBuiltinLaunchTestInstance : public TestInstance
186 {
187 public:
188 RayTracingBuiltinLaunchTestInstance (Context& context, const CaseDef& data);
189 ~RayTracingBuiltinLaunchTestInstance (void);
190 tcu::TestStatus iterate (void);
191
192 protected:
193 void checkSupportInInstance (void) const;
194 Move<VkPipeline> makePipeline (de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
195 VkPipelineLayout pipelineLayout,
196 const VkSpecializationInfo* specializationInfo);
197 std::vector<deInt32> expectedIntValuesBuffer (void);
198 std::vector<float> expectedFloatValuesBuffer (void);
199 std::vector<float> expectedVectorValuesBuffer (void);
200 std::vector<float> expectedMatrixValuesBuffer (void);
201 de::MovePtr<BufferWithMemory> runTest (void);
202 de::MovePtr<BufferWithMemory> createShaderBindingTable (const InstanceInterface& vki,
203 const DeviceInterface& vkd,
204 const VkDevice device,
205 const VkPhysicalDevice physicalDevice,
206 const VkPipeline pipeline,
207 Allocator& allocator,
208 de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
209 const deUint32 group);
210
211 bool validateIntBuffer (de::MovePtr<BufferWithMemory> buffer);
212 bool validateFloatBuffer (de::MovePtr<BufferWithMemory> buffer);
213 bool validateVectorBuffer (de::MovePtr<BufferWithMemory> buffer);
214 bool validateMatrixBuffer (de::MovePtr<BufferWithMemory> buffer);
215
216 de::MovePtr<TopLevelAccelerationStructure> initTopAccelerationStructure (VkCommandBuffer cmdBuffer,
217 vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures);
218 vector<de::SharedPtr<BottomLevelAccelerationStructure> > initBottomAccelerationStructures (VkCommandBuffer cmdBuffer);
219 de::MovePtr<BottomLevelAccelerationStructure> initBottomAccelerationStructure (VkCommandBuffer cmdBuffer,
220 tcu::UVec2& startPos);
221
222 private:
223 CaseDef m_data;
224 VkShaderStageFlags m_shaders;
225 deUint32 m_raygenShaderGroup;
226 deUint32 m_missShaderGroup;
227 deUint32 m_hitShaderGroup;
228 deUint32 m_callableShaderGroup;
229 deUint32 m_shaderGroupCount;
230 };
231
RayTracingBuiltinLaunchTestInstance(Context & context,const CaseDef & data)232 RayTracingBuiltinLaunchTestInstance::RayTracingBuiltinLaunchTestInstance (Context& context, const CaseDef& data)
233 : vkt::TestInstance (context)
234 , m_data (data)
235 , m_shaders (0)
236 , m_raygenShaderGroup (~0u)
237 , m_missShaderGroup (~0u)
238 , m_hitShaderGroup (~0u)
239 , m_callableShaderGroup (~0u)
240 , m_shaderGroupCount (0)
241 {
242 const VkShaderStageFlags hitStages = VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
243 BinaryCollection& collection = m_context.getBinaryCollection();
244 deUint32 group = 0;
245 deUint32 shaderCount = 0;
246
247 if (collection.contains("rgen")) m_shaders |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
248 if (collection.contains("ahit")) m_shaders |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
249 if (collection.contains("chit")) m_shaders |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
250 if (collection.contains("miss")) m_shaders |= VK_SHADER_STAGE_MISS_BIT_KHR;
251 if (collection.contains("sect")) m_shaders |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
252 if (collection.contains("call")) m_shaders |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
253
254 for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
255 shaderCount++;
256
257 if (shaderCount != (deUint32)dePop32(m_shaders))
258 TCU_THROW(InternalError, "Unused shaders detected in the collection");
259
260 if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))
261 m_raygenShaderGroup = group++;
262
263 if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))
264 m_missShaderGroup = group++;
265
266 if (0 != (m_shaders & hitStages))
267 m_hitShaderGroup = group++;
268
269 if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))
270 m_callableShaderGroup = group++;
271
272 m_shaderGroupCount = group;
273 }
274
~RayTracingBuiltinLaunchTestInstance(void)275 RayTracingBuiltinLaunchTestInstance::~RayTracingBuiltinLaunchTestInstance (void)
276 {
277 }
278
279 class RayTracingTestCase : public TestCase
280 {
281 public:
282 RayTracingTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data);
283 ~RayTracingTestCase (void);
284
285 virtual void initPrograms (SourceCollections& programCollection) const;
286 virtual TestInstance* createInstance (Context& context) const;
287 virtual void checkSupport (Context& context) const;
288
289 private:
290 static inline const std::string getIntersectionPassthrough (void);
291 static inline const std::string getMissPassthrough (void);
292 static inline const std::string getHitPassthrough (void);
293
294 CaseDef m_data;
295 };
296
RayTracingTestCase(tcu::TestContext & context,const char * name,const char * desc,const CaseDef data)297 RayTracingTestCase::RayTracingTestCase (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data)
298 : vkt::TestCase (context, name, desc)
299 , m_data (data)
300 {
301 }
302
~RayTracingTestCase(void)303 RayTracingTestCase::~RayTracingTestCase (void)
304 {
305 }
306
checkSupport(Context & context) const307 void RayTracingTestCase::checkSupport(Context& context) const
308 {
309 const bool pipelineFlagSkipTriangles = ((m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR) != 0);
310 const bool pipelineFlagSkipAABSs = ((m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR) != 0);
311 const bool cullingFlags = m_data.rayFlagSkipTriangles
312 || m_data.rayFlagSkipAABSs
313 || pipelineFlagSkipTriangles
314 || pipelineFlagSkipAABSs;
315
316 context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
317 context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
318
319 const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
320 if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE )
321 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
322
323 const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
324 if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
325 TCU_THROW(TestError, "VK_KHR_ray_tracing_pipeline requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
326
327 if (cullingFlags && rayTracingPipelineFeaturesKHR.rayTraversalPrimitiveCulling == DE_FALSE)
328 TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTraversalPrimitiveCulling");
329 }
330
getIntersectionPassthrough(void)331 const std::string RayTracingTestCase::getIntersectionPassthrough (void)
332 {
333 const std::string intersectionPassthrough =
334 "#version 460 core\n"
335 "#extension GL_EXT_ray_tracing : require\n"
336 "hitAttributeEXT vec3 hitAttribute;\n"
337 "\n"
338 "void main()\n"
339 "{\n"
340 " reportIntersectionEXT(0.95f, 0x7Eu);\n"
341 "}\n";
342
343 return intersectionPassthrough;
344 }
345
getMissPassthrough(void)346 const std::string RayTracingTestCase::getMissPassthrough (void)
347 {
348 const std::string missPassthrough =
349 "#version 460 core\n"
350 "#extension GL_EXT_ray_tracing : require\n"
351 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
352 "\n"
353 "void main()\n"
354 "{\n"
355 "}\n";
356
357 return missPassthrough;
358 }
359
getHitPassthrough(void)360 const std::string RayTracingTestCase::getHitPassthrough (void)
361 {
362 const std::string hitPassthrough =
363 "#version 460 core\n"
364 "#extension GL_EXT_ray_tracing : require\n"
365 "hitAttributeEXT vec3 attribs;\n"
366 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
367 "\n"
368 "void main()\n"
369 "{\n"
370 "}\n";
371
372 return hitPassthrough;
373 }
374
initPrograms(SourceCollections & programCollection) const375 void RayTracingTestCase::initPrograms (SourceCollections& programCollection) const
376 {
377 const bool useSC = m_data.useSpecConstants;
378 DE_ASSERT(!useSC || m_data.id == TEST_ID_LAUNCH_ID_EXT);
379
380 const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
381
382 if (m_data.id == TEST_ID_LAUNCH_ID_EXT || m_data.id == TEST_ID_LAUNCH_SIZE_EXT)
383 {
384 const std::string specConstants =
385 "layout (constant_id=0) const highp int factor1 = 1;\n"
386 "layout (constant_id=1) const highp float factor2 = 2.0;\n"
387 ;
388
389 const std::string updateImage =
390 " ivec3 p = ivec3(gl_LaunchIDEXT);\n"
391 " ivec3 v = ivec3(gl_" + std::string(m_data.name) + ");\n"
392 " int r = v.x + " + (useSC ? "factor1" : "256") + " * (v.y + " + (useSC ? "int(factor2)" : "256") + " * v.z) + 1;\n"
393 " ivec4 c = ivec4(r,0,0,1);\n"
394 " imageStore(result, p, c);\n";
395
396 switch (m_data.stage)
397 {
398 case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
399 {
400 std::stringstream css;
401 css <<
402 "#version 460 core\n"
403 "#extension GL_EXT_ray_tracing : require\n"
404 << (useSC ? specConstants : "") <<
405 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
406 "\n"
407 "void main()\n"
408 "{\n"
409 << updateImage <<
410 "}\n";
411
412 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
413
414 break;
415 }
416
417 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
418 {
419 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
420
421 {
422 std::stringstream css;
423 css <<
424 "#version 460 core\n"
425 "#extension GL_EXT_ray_tracing : require\n"
426 << (useSC ? specConstants : "") <<
427 "hitAttributeEXT vec3 attribs;\n"
428 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
429 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
430 "\n"
431 "void main()\n"
432 "{\n"
433 << updateImage <<
434 "}\n";
435
436 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
437 }
438
439 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
440 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
441
442 break;
443 }
444
445 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
446 {
447 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
448
449 {
450 std::stringstream css;
451 css <<
452 "#version 460 core\n"
453 "#extension GL_EXT_ray_tracing : require\n"
454 << (useSC ? specConstants : "") <<
455 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
456 "hitAttributeEXT vec3 attribs;\n"
457 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
458 "\n"
459 "void main()\n"
460 "{\n"
461 << updateImage <<
462 "}\n";
463
464 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
465 }
466
467 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
468 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
469
470 break;
471 }
472
473 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
474 {
475 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
476
477 {
478 std::stringstream css;
479 css <<
480 "#version 460 core\n"
481 "#extension GL_EXT_ray_tracing : require\n"
482 << (useSC ? specConstants : "") <<
483 "hitAttributeEXT vec3 hitAttribute;\n"
484 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
485 "\n"
486 "void main()\n"
487 "{\n"
488 << updateImage <<
489 " hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n"
490 " reportIntersectionEXT(1.0f, 0);\n"
491 "}\n";
492
493 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
494 }
495
496 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
497 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
498 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
499
500 break;
501 }
502
503 case VK_SHADER_STAGE_MISS_BIT_KHR:
504 {
505 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
506
507 {
508 std::stringstream css;
509 css <<
510 "#version 460 core\n"
511 "#extension GL_EXT_ray_tracing : require\n"
512 << (useSC ? specConstants : "") <<
513 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
514 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
515 "\n"
516 "void main()\n"
517 "{\n"
518 << updateImage <<
519 "}\n";
520
521 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
522 }
523
524 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
525 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
526
527 break;
528 }
529
530 case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
531 {
532 {
533 std::stringstream css;
534 css <<
535 "#version 460 core\n"
536 "#extension GL_EXT_ray_tracing : require\n"
537 "layout(location = 0) callableDataEXT float dummy;"
538 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
539 "\n"
540 "void main()\n"
541 "{\n"
542 " executeCallableEXT(0, 0);\n"
543 "}\n";
544
545 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
546 }
547
548 {
549 std::stringstream css;
550 css <<
551 "#version 460 core\n"
552 "#extension GL_EXT_ray_tracing : require\n"
553 << (useSC ? specConstants : "") <<
554 "layout(location = 0) callableDataInEXT float dummy;"
555 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
556 "\n"
557 "void main()\n"
558 "{\n"
559 << updateImage <<
560 "}\n";
561
562 programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
563 }
564
565 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
566 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
567 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
568
569 break;
570 }
571
572 default:
573 TCU_THROW(InternalError, "Unknown stage");
574 }
575 }
576 else if (m_data.id == TEST_ID_GEOMETRY_INDEX_EXT ||
577 m_data.id == TEST_ID_PRIMITIVE_ID ||
578 m_data.id == TEST_ID_INSTANCE_ID ||
579 m_data.id == TEST_ID_INSTANCE_CUSTOM_INDEX_EXT ||
580 m_data.id == TEST_ID_HIT_KIND_EXT )
581 {
582 const std::string conditionGeometryIndex = " int n = int(gl_LaunchIDEXT.x + gl_LaunchSizeEXT.x * (gl_LaunchIDEXT.y + gl_LaunchSizeEXT.y * gl_LaunchIDEXT.z));\n"
583 " int m = (n / " + de::toString(m_data.squaresGroupCount) + ") % " + de::toString(m_data.geometriesGroupCount) + ";\n"
584 " if (r == m)";
585 const std::string conditionPrimitiveId = " int n = int(gl_LaunchIDEXT.x + gl_LaunchSizeEXT.x * (gl_LaunchIDEXT.y + gl_LaunchSizeEXT.y * gl_LaunchIDEXT.z));\n"
586 " int m = n % " + de::toString(m_data.squaresGroupCount) + ";\n"
587 " if (r == m)";
588 const std::string condition = (m_data.id == TEST_ID_GEOMETRY_INDEX_EXT) && (m_data.geomType == GEOM_TYPE_AABBS) ? conditionGeometryIndex
589 : (m_data.id == TEST_ID_PRIMITIVE_ID) && (m_data.geomType == GEOM_TYPE_AABBS) ? conditionPrimitiveId
590 : "";
591 const std::string updateImage =
592 " ivec3 p = ivec3(gl_LaunchIDEXT);\n"
593 " int r = int(gl_" + std::string(m_data.name) + ");\n"
594 " ivec4 c = ivec4(r,0,0,1);\n"
595 + condition + " imageStore(result, p, c);\n";
596
597 switch (m_data.stage)
598 {
599 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
600 {
601 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
602
603 {
604 std::stringstream css;
605 css <<
606 "#version 460 core\n"
607 "#extension GL_EXT_ray_tracing : require\n"
608 "hitAttributeEXT vec3 attribs;\n"
609 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
610 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
611 "\n"
612 "void main()\n"
613 "{\n"
614 << updateImage <<
615 "}\n";
616
617 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
618 }
619
620 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
621 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
622
623 if (m_data.geomType == GEOM_TYPE_AABBS)
624 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(getIntersectionPassthrough())) << buildOptions;
625
626 break;
627 }
628
629 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
630 {
631 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
632
633 {
634 std::stringstream css;
635 css <<
636 "#version 460 core\n"
637 "#extension GL_EXT_ray_tracing : require\n"
638 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
639 "hitAttributeEXT vec3 attribs;\n"
640 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
641 "\n"
642 "void main()\n"
643 "{\n"
644 << updateImage <<
645 "}\n";
646
647 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
648 }
649
650 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
651 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
652
653 if (m_data.geomType == GEOM_TYPE_AABBS)
654 {
655 const std::string intersectionShaderSingle =
656 "#version 460 core\n"
657 "#extension GL_EXT_ray_tracing : require\n"
658 "hitAttributeEXT vec3 hitAttribute;\n"
659 "\n"
660 "void main()\n"
661 "{\n"
662 " int r = int(gl_" + std::string(m_data.name) + ");\n"
663 + condition + " reportIntersectionEXT(0.95f, 0x7Eu);\n"
664 "}\n";
665 const std::string intersectionShader = condition.empty() ? getIntersectionPassthrough() : intersectionShaderSingle;
666
667 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
668 }
669
670 break;
671 }
672
673 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
674 {
675 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
676
677 {
678 std::stringstream css;
679 css <<
680 "#version 460 core\n"
681 "#extension GL_EXT_ray_tracing : require\n"
682 "hitAttributeEXT vec3 hitAttribute;\n"
683 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
684 "\n"
685 "void main()\n"
686 "{\n"
687 << updateImage <<
688 " reportIntersectionEXT(0.95f, 0);\n"
689 "}\n";
690
691 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
692 }
693
694 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
695 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
696 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
697
698 break;
699 }
700
701 default:
702 TCU_THROW(InternalError, "Unknown stage");
703 }
704 }
705 else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_EXT)
706 {
707 const bool cullingFlags = m_data.rayFlagSkipTriangles || m_data.rayFlagSkipAABSs;
708 const std::string cullingFlagsInit = (m_data.rayFlagSkipTriangles && m_data.rayFlagSkipAABSs) ? "gl_RayFlagsSkipTrianglesEXT|gl_RayFlagsSkipAABBEXT"
709 : m_data.rayFlagSkipTriangles ? "gl_RayFlagsSkipTrianglesEXT"
710 : m_data.rayFlagSkipAABSs ? "gl_RayFlagsSkipAABBEXT"
711 : "gl_RayFlagsNoneEXT";
712 const std::string updateImage =
713 " ivec3 p = ivec3(gl_LaunchIDEXT);\n"
714 " int r = int(gl_" + std::string(m_data.name) + ");\n"
715 " ivec4 c = ivec4(r,0,0,1);\n"
716 " imageStore(result, p, c);\n";
717 const std::string intersectionShader =
718 "#version 460 core\n"
719 "#extension GL_EXT_ray_tracing : require\n"
720 "hitAttributeEXT vec3 hitAttribute;\n"
721 "\n"
722 "void main()\n"
723 "{\n"
724 " uint hitKind = " + std::string(m_data.frontFace ? "0x7Eu" : "0x7Fu") + ";\n"
725 " reportIntersectionEXT(0.95f, hitKind);\n"
726 "}\n";
727 const std::string raygenFlagsFragment =
728 "\n"
729 " if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_OPAQUE_EXT ) + "))) f = f | gl_RayFlagsOpaqueEXT;\n"
730 " else if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_NO_OPAQUE_EXT ) + "))) f = f | gl_RayFlagsNoOpaqueEXT;\n"
731 " else if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_CULL_OPAQUE_EXT ) + "))) f = f | gl_RayFlagsCullOpaqueEXT;\n"
732 " else if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_CULL_NO_OPAQUE_EXT ) + "))) f = f | gl_RayFlagsCullNoOpaqueEXT;\n"
733 "\n"
734 " if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_CULL_BACK_FACING_TRIANGLES_EXT ) + "))) f = f | gl_RayFlagsCullBackFacingTrianglesEXT;\n"
735 " else if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_CULL_FRONT_FACING_TRIANGLES_EXT) + "))) f = f | gl_RayFlagsCullFrontFacingTrianglesEXT;\n"
736 "\n"
737 " if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_TERMINATE_ON_FIRST_HIT_EXT ) + "))) f = f | gl_RayFlagsTerminateOnFirstHitEXT;\n"
738 " if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_SKIP_CLOSEST_HIT_SHADER_EXT ) + "))) f = f | gl_RayFlagsSkipClosestHitShaderEXT;\n"
739 "\n";
740 const std::string raygenShader =
741 "#version 460 core\n"
742 "#extension GL_EXT_ray_tracing : require\n"
743 + (cullingFlags ? std::string("#extension GL_EXT_ray_flags_primitive_culling : require\n") : "") +
744 "layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
745 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
746 "\n"
747 "void main()\n"
748 "{\n"
749 " uint n = gl_LaunchIDEXT.x + gl_LaunchSizeEXT.x * (gl_LaunchIDEXT.y + gl_LaunchSizeEXT.y * gl_LaunchIDEXT.z);\n"
750 " uint f = " + cullingFlagsInit + ";\n"
751 + raygenFlagsFragment +
752 " uint rayFlags = f;\n"
753 " uint cullMask = 0xFF;\n"
754 " float tmin = 0.0;\n"
755 " float tmax = 9.0;\n"
756 " 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"
757 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
758 " traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
759 "}\n";
760
761 switch (m_data.stage)
762 {
763 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
764 {
765 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
766
767 {
768 std::stringstream css;
769 css <<
770 "#version 460 core\n"
771 "#extension GL_EXT_ray_tracing : require\n"
772 "hitAttributeEXT vec3 hitAttribute;\n"
773 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
774 "\n"
775 "void main()\n"
776 "{\n"
777 << updateImage <<
778 "}\n";
779
780 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
781 }
782
783 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
784 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
785 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
786
787 break;
788 }
789
790 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
791 {
792 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
793
794 {
795 std::stringstream css;
796 css <<
797 "#version 460 core\n"
798 "#extension GL_EXT_ray_tracing : require\n"
799 "hitAttributeEXT vec3 attribs;\n"
800 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
801 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
802 "\n"
803 "void main()\n"
804 "{\n"
805 << updateImage <<
806 "}\n";
807
808 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
809 }
810
811 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
812 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
813
814 if (m_data.geomType == GEOM_TYPE_AABBS)
815 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
816
817 break;
818 }
819
820 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
821 {
822 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
823
824 {
825 std::stringstream css;
826 css <<
827 "#version 460 core\n"
828 "#extension GL_EXT_ray_tracing : require\n"
829 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
830 "hitAttributeEXT vec3 attribs;\n"
831 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
832 "\n"
833 "void main()\n"
834 "{\n"
835 << updateImage <<
836 "}\n";
837
838 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
839 }
840
841 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
842 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
843
844 if (m_data.geomType == GEOM_TYPE_AABBS)
845 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
846
847 break;
848 }
849
850 case VK_SHADER_STAGE_MISS_BIT_KHR:
851 {
852 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
853
854 {
855 std::stringstream css;
856 css <<
857 "#version 460 core\n"
858 "#extension GL_EXT_ray_tracing : require\n"
859 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
860 "\n"
861 "void main()\n"
862 "{\n"
863 << updateImage <<
864 "}\n";
865
866 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
867 }
868
869 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
870 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
871
872 if (m_data.geomType == GEOM_TYPE_AABBS)
873 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
874
875 break;
876 }
877
878 default:
879 TCU_THROW(InternalError, "Unknown stage");
880 }
881 }
882 else if (m_data.id == TEST_ID_HIT_T_EXT ||
883 m_data.id == TEST_ID_RAY_T_MIN_EXT ||
884 m_data.id == TEST_ID_RAY_T_MAX_EXT )
885 {
886 const std::string raygenShader =
887 "#version 460 core\n"
888 "#extension GL_EXT_ray_tracing : require\n"
889 "layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
890 "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
891 "\n"
892 "void main()\n"
893 "{\n"
894 " uint cullMask = 0xFF;\n"
895 " float a = float(gl_LaunchIDEXT.x) / gl_LaunchSizeEXT.x;\n"
896 " float b = 1.0f + float(gl_LaunchIDEXT.y) / gl_LaunchSizeEXT.y;\n"
897 " float c = 0.25f * a / b;\n"
898 " float tmin = c;\n"
899 " float tmax = 0.75f + c;\n"
900 " 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"
901 " vec3 direct = vec3(0.0, 0.0, -1.0);\n"
902 " traceRayEXT(topLevelAS, gl_RayFlagsNoneEXT, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
903 "}\n";
904 const std::string intersectionShader =
905 "#version 460 core\n"
906 "#extension GL_EXT_ray_tracing : require\n"
907 "hitAttributeEXT vec3 hitAttribute;\n"
908 "\n"
909 "void main()\n"
910 "{\n"
911 " float a = float(gl_LaunchIDEXT.x) / gl_LaunchSizeEXT.x;\n"
912 " float b = 1.0f + float(gl_LaunchIDEXT.y) / gl_LaunchSizeEXT.y;\n"
913 " float c = 0.25f * a / b;\n"
914 " reportIntersectionEXT(0.03125f + c, 0);\n"
915 "}\n";
916 const std::string updateImage =
917 " ivec3 p = ivec3(gl_LaunchIDEXT);\n"
918 " int r = int(" +de::toString(FIXED_POINT_DIVISOR) + ".0f * gl_" + std::string(m_data.name) + ");\n"
919 " ivec4 c = ivec4(r,0,0,1);\n"
920 " imageStore(result, p, c);\n";
921
922 switch (m_data.stage)
923 {
924 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
925 {
926 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
927
928 {
929 std::stringstream css;
930 css <<
931 "#version 460 core\n"
932 "#extension GL_EXT_ray_tracing : require\n"
933 "hitAttributeEXT vec3 attribs;\n"
934 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
935 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
936 "\n"
937 "void main()\n"
938 "{\n"
939 << updateImage <<
940 "}\n";
941
942 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
943 }
944
945 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
946 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
947
948 if (m_data.geomType == GEOM_TYPE_AABBS)
949 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
950
951 break;
952 }
953
954 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
955 {
956 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
957
958 {
959 std::stringstream css;
960 css <<
961 "#version 460 core\n"
962 "#extension GL_EXT_ray_tracing : require\n"
963 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
964 "hitAttributeEXT vec3 attribs;\n"
965 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
966 "\n"
967 "void main()\n"
968 "{\n"
969 << updateImage <<
970 "}\n";
971
972 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
973 }
974
975 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
976 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
977
978 if (m_data.geomType == GEOM_TYPE_AABBS)
979 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
980
981 break;
982 }
983
984 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
985 {
986 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
987
988 {
989 std::stringstream css;
990 css <<
991 "#version 460 core\n"
992 "#extension GL_EXT_ray_tracing : require\n"
993 "hitAttributeEXT vec3 hitAttribute;\n"
994 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
995 "\n"
996 "void main()\n"
997 "{\n"
998 << updateImage <<
999 "\n"
1000 " float a = float(gl_LaunchIDEXT.x) / gl_LaunchSizeEXT.x;\n"
1001 " float b = 1.0f + float(gl_LaunchIDEXT.y) / gl_LaunchSizeEXT.y;\n"
1002 " reportIntersectionEXT(0.4375f + 0.25f * a / b, 0x7Eu);\n"
1003 "}\n";
1004
1005 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1006 }
1007
1008 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1009 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1010 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1011
1012 break;
1013 }
1014
1015 case VK_SHADER_STAGE_MISS_BIT_KHR:
1016 {
1017 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
1018
1019 {
1020 std::stringstream css;
1021 css <<
1022 "#version 460 core\n"
1023 "#extension GL_EXT_ray_tracing : require\n"
1024 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1025 "\n"
1026 "void main()\n"
1027 "{\n"
1028 << updateImage <<
1029 "}\n";
1030
1031 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1032 }
1033
1034 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1035 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1036
1037 if (m_data.geomType == GEOM_TYPE_AABBS)
1038 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
1039
1040 break;
1041 }
1042
1043 default:
1044 TCU_THROW(InternalError, "Unknown stage");
1045 }
1046 }
1047 else if (m_data.id == TEST_ID_WORLD_RAY_ORIGIN_EXT ||
1048 m_data.id == TEST_ID_WORLD_RAY_DIRECTION_EXT ||
1049 m_data.id == TEST_ID_OBJECT_RAY_ORIGIN_EXT ||
1050 m_data.id == TEST_ID_OBJECT_RAY_DIRECTION_EXT ||
1051 m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT ||
1052 m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT ||
1053 m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT ||
1054 m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT )
1055 {
1056 const bool matrix4x3 = (m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT || m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT);
1057 const bool matrix3x4 = (m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT || m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT);
1058 const bool matrixOutput = matrix4x3 || matrix3x4;
1059 const std::string vectorLoop =
1060 " for (int ndx = 0; ndx < 3; ndx++)\n"
1061 " {\n";
1062 const std::string matrixLoop4x3 =
1063 " int ndx = -1;\n"
1064 " for (int row = 0; row < 3; row++)\n"
1065 " for (int col = 0; col < 4; col++)\n"
1066 " {\n"
1067 " ndx++;\n";
1068 const std::string matrixLoop3x4 =
1069 " int ndx = -1;\n"
1070 " for (int col = 0; col < 3; col++)\n"
1071 " for (int row = 0; row < 4; row++)\n"
1072 " {\n"
1073 " ndx++;\n";
1074 const std::string loop =
1075 matrix4x3 ? matrixLoop4x3 :
1076 matrix3x4 ? matrixLoop3x4 :
1077 vectorLoop;
1078 const std::string index =
1079 (matrixOutput ? "[col][row]" : "[ndx]");
1080 const std::string updateImage =
1081 " float k = " +de::toString(FIXED_POINT_DIVISOR) + ".0f;\n"
1082 + loop +
1083 " ivec3 p = ivec3(gl_LaunchIDEXT.xy, ndx);\n"
1084 " float r = k * gl_" + std::string(m_data.name) + index + ";\n"
1085 " ivec4 c = ivec4(int(r),0,0,1);\n"
1086 " imageStore(result, p, c);\n"
1087 " }\n";
1088
1089 switch (m_data.stage)
1090 {
1091 case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
1092 {
1093 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1094
1095 {
1096 std::stringstream css;
1097 css <<
1098 "#version 460 core\n"
1099 "#extension GL_EXT_ray_tracing : require\n"
1100 "hitAttributeEXT vec3 attribs;\n"
1101 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1102 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1103 "\n"
1104 "void main()\n"
1105 "{\n"
1106 << updateImage <<
1107 "}\n";
1108
1109 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1110 }
1111
1112 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1113 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1114
1115 if (m_data.geomType == GEOM_TYPE_AABBS)
1116 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(getIntersectionPassthrough())) << buildOptions;
1117
1118 break;
1119 }
1120
1121 case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
1122 {
1123 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1124
1125 {
1126 std::stringstream css;
1127 css <<
1128 "#version 460 core\n"
1129 "#extension GL_EXT_ray_tracing : require\n"
1130 "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1131 "hitAttributeEXT vec3 attribs;\n"
1132 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1133 "\n"
1134 "void main()\n"
1135 "{\n"
1136 << updateImage <<
1137 "}\n";
1138
1139 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1140 }
1141
1142 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1143 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1144
1145 if (m_data.geomType == GEOM_TYPE_AABBS)
1146 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(getIntersectionPassthrough())) << buildOptions;
1147
1148 break;
1149 }
1150
1151 case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
1152 {
1153 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1154
1155 {
1156 std::stringstream css;
1157 css <<
1158 "#version 460 core\n"
1159 "#extension GL_EXT_ray_tracing : require\n"
1160 "hitAttributeEXT vec3 hitAttribute;\n"
1161 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1162 "\n"
1163 "void main()\n"
1164 "{\n"
1165 << updateImage <<
1166 " reportIntersectionEXT(0.95f, 0);\n"
1167 "}\n";
1168
1169 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1170 }
1171
1172 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1173 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1174 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1175
1176 break;
1177 }
1178
1179 case VK_SHADER_STAGE_MISS_BIT_KHR:
1180 {
1181 programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1182
1183 {
1184 std::stringstream css;
1185 css <<
1186 "#version 460 core\n"
1187 "#extension GL_EXT_ray_tracing : require\n"
1188 "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1189 "\n"
1190 "void main()\n"
1191 "{\n"
1192 << updateImage <<
1193 "}\n";
1194
1195 programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1196 }
1197
1198 programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1199 programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1200
1201 if (m_data.geomType == GEOM_TYPE_AABBS)
1202 programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(getIntersectionPassthrough())) << buildOptions;
1203
1204 break;
1205 }
1206
1207 default:
1208 TCU_THROW(InternalError, "Unknown stage");
1209 }
1210 }
1211 else
1212 {
1213 TCU_THROW(InternalError, "Not implemented");
1214 }
1215 }
1216
createInstance(Context & context) const1217 TestInstance* RayTracingTestCase::createInstance (Context& context) const
1218 {
1219 return new RayTracingBuiltinLaunchTestInstance(context, m_data);
1220 }
1221
initTopAccelerationStructure(VkCommandBuffer cmdBuffer,vector<de::SharedPtr<BottomLevelAccelerationStructure>> & bottomLevelAccelerationStructures)1222 de::MovePtr<TopLevelAccelerationStructure> RayTracingBuiltinLaunchTestInstance::initTopAccelerationStructure (VkCommandBuffer cmdBuffer,
1223 vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures)
1224 {
1225 const DeviceInterface& vkd = m_context.getDeviceInterface();
1226 const VkDevice device = m_context.getDevice();
1227 Allocator& allocator = m_context.getDefaultAllocator();
1228 de::MovePtr<TopLevelAccelerationStructure> result = makeTopLevelAccelerationStructure();
1229 const bool transformTest = m_data.id == TEST_ID_WORLD_RAY_ORIGIN_EXT
1230 || m_data.id == TEST_ID_WORLD_RAY_DIRECTION_EXT
1231 || m_data.id == TEST_ID_OBJECT_RAY_ORIGIN_EXT
1232 || m_data.id == TEST_ID_OBJECT_RAY_DIRECTION_EXT
1233 || m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT
1234 || m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT
1235 || m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT
1236 || m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT;
1237
1238 result->setInstanceCount(bottomLevelAccelerationStructures.size());
1239
1240 for (size_t structNdx = 0; structNdx < bottomLevelAccelerationStructures.size(); ++structNdx)
1241 {
1242 VkTransformMatrixKHR transform = identityMatrix3x4;
1243
1244 if (transformTest)
1245 {
1246 if (structNdx & 1)
1247 transform.matrix[0][3] = (1.0f / 8.0f) / float(m_data.width);
1248
1249 if (structNdx & 2)
1250 transform.matrix[1][3] = (1.0f / 16.0f) / float(m_data.height);
1251 }
1252
1253 result->addInstance(bottomLevelAccelerationStructures[structNdx], transform, deUint32(2 * structNdx));
1254 }
1255
1256 result->createAndBuild(vkd, device, cmdBuffer, allocator);
1257
1258 return result;
1259 }
1260
initBottomAccelerationStructure(VkCommandBuffer cmdBuffer,tcu::UVec2 & startPos)1261 de::MovePtr<BottomLevelAccelerationStructure> RayTracingBuiltinLaunchTestInstance::initBottomAccelerationStructure (VkCommandBuffer cmdBuffer,
1262 tcu::UVec2& startPos)
1263 {
1264 const DeviceInterface& vkd = m_context.getDeviceInterface();
1265 const VkDevice device = m_context.getDevice();
1266 Allocator& allocator = m_context.getDefaultAllocator();
1267 de::MovePtr<BottomLevelAccelerationStructure> result = makeBottomLevelAccelerationStructure();
1268
1269 result->setGeometryCount(m_data.geometriesGroupCount);
1270
1271 if (m_data.id == TEST_ID_LAUNCH_ID_EXT || m_data.id == TEST_ID_LAUNCH_SIZE_EXT)
1272 {
1273 result->setDefaultGeometryData(m_data.stage);
1274 }
1275 else if (m_data.id == TEST_ID_GEOMETRY_INDEX_EXT ||
1276 m_data.id == TEST_ID_PRIMITIVE_ID ||
1277 m_data.id == TEST_ID_INSTANCE_ID ||
1278 m_data.id == TEST_ID_INSTANCE_CUSTOM_INDEX_EXT )
1279 {
1280 const bool triangles = (m_data.geomType == GEOM_TYPE_TRIANGLES);
1281 const bool missShader = (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1282 const float z = !missShader ? -1.0f : -100.0f;
1283
1284 DE_ASSERT(m_data.squaresGroupCount != 1);
1285
1286 for (size_t geometryNdx = 0; geometryNdx < m_data.geometriesGroupCount; ++geometryNdx)
1287 {
1288 std::vector<tcu::Vec3> geometryData;
1289
1290 geometryData.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1291
1292 for (size_t squareNdx = 0; squareNdx < m_data.squaresGroupCount; ++squareNdx)
1293 {
1294 const deUint32 n = m_data.width * startPos.y() + startPos.x();
1295 const float x0 = float(startPos.x() + 0) / float(m_data.width);
1296 const float y0 = float(startPos.y() + 0) / float(m_data.height);
1297 const float x1 = float(startPos.x() + 1) / float(m_data.width);
1298 const float y1 = float(startPos.y() + 1) / float(m_data.height);
1299 const deUint32 m = n + 1;
1300
1301 if (triangles)
1302 {
1303 const float xm = (x0 + x1) / 2.0f;
1304 const float ym = (y0 + y1) / 2.0f;
1305
1306 geometryData.push_back(tcu::Vec3(x0, y0, z));
1307 geometryData.push_back(tcu::Vec3(xm, y1, z));
1308 geometryData.push_back(tcu::Vec3(x1, ym, z));
1309 }
1310 else
1311 {
1312 geometryData.push_back(tcu::Vec3(x0, y0, z));
1313 geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
1314 }
1315
1316 startPos.y() = m / m_data.width;
1317 startPos.x() = m % m_data.width;
1318 }
1319
1320 result->addGeometry(geometryData, triangles);
1321 }
1322 }
1323 else if (m_data.id == TEST_ID_HIT_KIND_EXT)
1324 {
1325 const bool triangles = (m_data.geomType == GEOM_TYPE_TRIANGLES);
1326 const bool missShader = (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1327 const float z = !missShader ? -1.0f : -100.0f;
1328
1329 DE_ASSERT(m_data.squaresGroupCount != 1);
1330 DE_ASSERT(m_data.geometriesGroupCount == 4);
1331
1332 std::vector<tcu::Vec3> geometryDataOpaque;
1333 std::vector<tcu::Vec3> geometryDataNonOpaque;
1334
1335 geometryDataOpaque.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1336 geometryDataNonOpaque.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1337
1338 for (size_t geometryNdx = 0; geometryNdx < m_data.geometriesGroupCount; ++geometryNdx)
1339 {
1340 const bool cw = ((geometryNdx & 1) == 0) ? true : false;
1341 std::vector<tcu::Vec3>& geometryData = ((geometryNdx & 2) == 0) ? geometryDataOpaque : geometryDataNonOpaque;
1342
1343 for (size_t squareNdx = 0; squareNdx < m_data.squaresGroupCount; ++squareNdx)
1344 {
1345 const deUint32 n = m_data.width * startPos.y() + startPos.x();
1346 const deUint32 m = n + 1;
1347 const float x0 = float(startPos.x() + 0) / float(m_data.width);
1348 const float y0 = float(startPos.y() + 0) / float(m_data.height);
1349 const float x1 = float(startPos.x() + 1) / float(m_data.width);
1350 const float y1 = float(startPos.y() + 1) / float(m_data.height);
1351
1352 if (triangles)
1353 {
1354 const float xm = (x0 + x1) / 2.0f;
1355 const float ym = (y0 + y1) / 2.0f;
1356
1357 if (cw)
1358 {
1359 geometryData.push_back(tcu::Vec3(x0, y0, z));
1360 geometryData.push_back(tcu::Vec3(x1, ym, z));
1361 geometryData.push_back(tcu::Vec3(xm, y1, z));
1362 }
1363 else
1364 {
1365 geometryData.push_back(tcu::Vec3(x0, y0, z));
1366 geometryData.push_back(tcu::Vec3(xm, y1, z));
1367 geometryData.push_back(tcu::Vec3(x1, ym, z));
1368 }
1369 }
1370 else
1371 {
1372 geometryData.push_back(tcu::Vec3(x0, y0, z));
1373 geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
1374 }
1375
1376 startPos.y() = m / m_data.width;
1377 startPos.x() = m % m_data.width;
1378 }
1379 }
1380
1381 DE_ASSERT(startPos.y() == m_data.height && startPos.x() == 0);
1382
1383 result->addGeometry(geometryDataOpaque, triangles, (VkGeometryFlagsKHR)VK_GEOMETRY_OPAQUE_BIT_KHR);
1384 result->addGeometry(geometryDataNonOpaque, triangles, (VkGeometryFlagsKHR)0);
1385 }
1386 else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_EXT)
1387 {
1388 const bool triangles = (m_data.geomType == GEOM_TYPE_TRIANGLES);
1389 const bool missShader = (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1390 const float z = !missShader ? -1.0f : -100.0f;
1391 const VkGeometryFlagsKHR geometryFlags = m_data.opaque ? static_cast<VkGeometryFlagsKHR>(VK_GEOMETRY_OPAQUE_BIT_KHR) : static_cast<VkGeometryFlagsKHR>(0);
1392 const bool cw = m_data.frontFace;
1393 std::vector<tcu::Vec3> geometryData;
1394
1395 DE_ASSERT(m_data.geometriesGroupCount == 1);
1396 DE_ASSERT(m_data.squaresGroupCount != 1);
1397
1398 geometryData.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1399
1400 for (size_t squareNdx = 0; squareNdx < m_data.squaresGroupCount; ++squareNdx)
1401 {
1402 const deUint32 n = m_data.width * startPos.y() + startPos.x();
1403 const deUint32 m = n + 1;
1404 const float x0 = float(startPos.x() + 0) / float(m_data.width);
1405 const float y0 = float(startPos.y() + 0) / float(m_data.height);
1406 const float x1 = float(startPos.x() + 1) / float(m_data.width);
1407 const float y1 = float(startPos.y() + 1) / float(m_data.height);
1408
1409 if (triangles)
1410 {
1411 const float xm = (x0 + x1) / 2.0f;
1412 const float ym = (y0 + y1) / 2.0f;
1413
1414 if (cw)
1415 {
1416 geometryData.push_back(tcu::Vec3(x0, y0, z));
1417 geometryData.push_back(tcu::Vec3(x1, ym, z));
1418 geometryData.push_back(tcu::Vec3(xm, y1, z));
1419 }
1420 else
1421 {
1422 geometryData.push_back(tcu::Vec3(x0, y0, z));
1423 geometryData.push_back(tcu::Vec3(xm, y1, z));
1424 geometryData.push_back(tcu::Vec3(x1, ym, z));
1425 }
1426 }
1427 else
1428 {
1429 geometryData.push_back(tcu::Vec3(x0, y0, z));
1430 geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
1431 }
1432
1433 startPos.y() = m / m_data.width;
1434 startPos.x() = m % m_data.width;
1435 }
1436
1437 DE_ASSERT(startPos.y() == m_data.height && startPos.x() == 0);
1438
1439 result->addGeometry(geometryData, triangles, geometryFlags);
1440 }
1441 else if (m_data.id == TEST_ID_HIT_T_EXT ||
1442 m_data.id == TEST_ID_RAY_T_MIN_EXT ||
1443 m_data.id == TEST_ID_RAY_T_MAX_EXT )
1444 {
1445 const bool triangles = (m_data.geomType == GEOM_TYPE_TRIANGLES);
1446 const bool missShader = (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1447 const bool sectShader = (m_data.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR);
1448 const bool maxTTest = (m_data.id == TEST_ID_RAY_T_MAX_EXT);
1449
1450 DE_ASSERT(m_data.squaresGroupCount != 1);
1451
1452 for (size_t geometryNdx = 0; geometryNdx < m_data.geometriesGroupCount; ++geometryNdx)
1453 {
1454 std::vector<tcu::Vec3> geometryData;
1455
1456 geometryData.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1457
1458 for (size_t squareNdx = 0; squareNdx < m_data.squaresGroupCount; ++squareNdx)
1459 {
1460 const deUint32 n = m_data.width * startPos.y() + startPos.x();
1461 const deUint32 m = n + 1;
1462 const bool shiftRight = sectShader && maxTTest && (0 == (startPos.y() & 1)) && (0 == (startPos.x() & 1));
1463 const deUint32 xo = shiftRight ? 1 : 0;
1464 const float x0 = float(startPos.x() + 0 + xo) / float(m_data.width);
1465 const float y0 = float(startPos.y() + 0) / float(m_data.height);
1466 const float x1 = float(startPos.x() + 1 + xo) / float(m_data.width);
1467 const float y1 = float(startPos.y() + 1) / float(m_data.height);
1468 const float a = x0;
1469 const float b = 1.0f + y0;
1470 const float c = 0.03125f + 0.25f * a / b;
1471 const float z = !missShader ? -c : -100.0f;
1472
1473 if (triangles)
1474 {
1475 const float xm = (x0 + x1) / 2.0f;
1476 const float ym = (y0 + y1) / 2.0f;
1477
1478 geometryData.push_back(tcu::Vec3(x0, y0, z));
1479 geometryData.push_back(tcu::Vec3(xm, y1, z));
1480 geometryData.push_back(tcu::Vec3(x1, ym, z));
1481 }
1482 else
1483 {
1484 geometryData.push_back(tcu::Vec3(x0, y0, z));
1485 geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
1486 }
1487
1488 startPos.y() = m / m_data.width;
1489 startPos.x() = m % m_data.width;
1490 }
1491
1492 result->addGeometry(geometryData, triangles);
1493 }
1494 }
1495 else if (m_data.id == TEST_ID_WORLD_RAY_ORIGIN_EXT ||
1496 m_data.id == TEST_ID_WORLD_RAY_DIRECTION_EXT ||
1497 m_data.id == TEST_ID_OBJECT_RAY_ORIGIN_EXT ||
1498 m_data.id == TEST_ID_OBJECT_RAY_DIRECTION_EXT ||
1499 m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT ||
1500 m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT ||
1501 m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT ||
1502 m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT )
1503 {
1504 const bool triangles = m_data.geomType == GEOM_TYPE_TRIANGLES;
1505 const float y0 = float(startPos.y() + 0) / float(m_data.height);
1506 const float y1 = float(startPos.y() + 1) / float(m_data.height);
1507 const bool missShader = (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1508 const float z = !missShader ? -1.0f : -100.0f;
1509 std::vector<tcu::Vec3> geometryData;
1510
1511 if (triangles)
1512 {
1513 geometryData.push_back(tcu::Vec3(-1.0f, y1, z));
1514 geometryData.push_back(tcu::Vec3(-1.0f, y0, z));
1515 geometryData.push_back(tcu::Vec3(+1.0f, y0, z));
1516 geometryData.push_back(tcu::Vec3(-1.0f, y1, z));
1517 geometryData.push_back(tcu::Vec3(+1.0f, y0, z));
1518 geometryData.push_back(tcu::Vec3(+1.0f, y1, z));
1519 }
1520 else
1521 {
1522 geometryData.reserve(2);
1523
1524 geometryData.push_back(tcu::Vec3(-1.0f, y0, z));
1525 geometryData.push_back(tcu::Vec3(+1.0f, y1, z));
1526 }
1527
1528 DE_ASSERT(startPos.y() < m_data.height);
1529
1530 startPos.y()++;
1531
1532 result->addGeometry(geometryData, triangles);
1533 }
1534 else
1535 {
1536 TCU_THROW(InternalError, "Not implemented");
1537 }
1538
1539 result->createAndBuild(vkd, device, cmdBuffer, allocator);
1540
1541 return result;
1542 }
1543
initBottomAccelerationStructures(VkCommandBuffer cmdBuffer)1544 vector<de::SharedPtr<BottomLevelAccelerationStructure> > RayTracingBuiltinLaunchTestInstance::initBottomAccelerationStructures (VkCommandBuffer cmdBuffer)
1545 {
1546 tcu::UVec2 startPos;
1547 vector<de::SharedPtr<BottomLevelAccelerationStructure> > result;
1548
1549 for (size_t instanceNdx = 0; instanceNdx < m_data.instancesGroupCount; ++instanceNdx)
1550 {
1551 de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure = initBottomAccelerationStructure(cmdBuffer, startPos);
1552
1553 result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1554 }
1555
1556 return result;
1557 }
1558
makePipeline(de::MovePtr<RayTracingPipeline> & rayTracingPipeline,VkPipelineLayout pipelineLayout,const VkSpecializationInfo * specializationInfo)1559 Move<VkPipeline> RayTracingBuiltinLaunchTestInstance::makePipeline (de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
1560 VkPipelineLayout pipelineLayout,
1561 const VkSpecializationInfo* specializationInfo)
1562 {
1563 const DeviceInterface& vkd = m_context.getDeviceInterface();
1564 const VkDevice device = m_context.getDevice();
1565 vk::BinaryCollection& collection = m_context.getBinaryCollection();
1566
1567 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);
1568 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);
1569 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);
1570 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);
1571 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);
1572 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);
1573
1574 if (m_data.pipelineCreateFlags != 0)
1575 rayTracingPipeline->setCreateFlags(m_data.pipelineCreateFlags);
1576
1577 Move<VkPipeline> pipeline = rayTracingPipeline->createPipeline(vkd, device, pipelineLayout);
1578
1579 return pipeline;
1580 }
1581
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)1582 de::MovePtr<BufferWithMemory> RayTracingBuiltinLaunchTestInstance::createShaderBindingTable (const InstanceInterface& vki,
1583 const DeviceInterface& vkd,
1584 const VkDevice device,
1585 const VkPhysicalDevice physicalDevice,
1586 const VkPipeline pipeline,
1587 Allocator& allocator,
1588 de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
1589 const deUint32 group)
1590 {
1591 de::MovePtr<BufferWithMemory> shaderBindingTable;
1592
1593 if (group < m_shaderGroupCount)
1594 {
1595 const deUint32 shaderGroupHandleSize = getShaderGroupSize(vki, physicalDevice);
1596 const deUint32 shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice);
1597
1598 shaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, group, 1u);
1599 }
1600
1601 return shaderBindingTable;
1602 }
1603
1604 // Provides two spec constants, one integer and one float, both with value 256.
1605 class SpecConstantsHelper
1606 {
1607 public:
1608 SpecConstantsHelper ();
1609 const VkSpecializationInfo& getSpecializationInfo (void) const;
1610 private:
1611 std::vector<deUint8> m_data;
1612 std::vector<VkSpecializationMapEntry> m_mapEntries;
1613 VkSpecializationInfo m_specInfo;
1614 };
1615
SpecConstantsHelper()1616 SpecConstantsHelper::SpecConstantsHelper ()
1617 : m_data ()
1618 , m_mapEntries ()
1619 {
1620 // To make things interesting, make both data unaligned and add some padding.
1621 const deInt32 value1 = 256;
1622 const float value2 = 256.0f;
1623
1624 const size_t offset1 = 1u; // Offset of 1 byte.
1625 const size_t offset2 = 1u + sizeof(value1) + 2u; // Offset of 3 bytes plus the size of value1.
1626
1627 m_data.resize(sizeof(value1) + sizeof(value2) + 5u); // Some extra padding at the end too.
1628 deMemcpy(&m_data[offset1], &value1, sizeof(value1));
1629 deMemcpy(&m_data[offset2], &value2, sizeof(value2));
1630
1631 // Map entries.
1632 m_mapEntries.reserve(2u);
1633 m_mapEntries.push_back({ 0u, static_cast<deUint32>(offset1), static_cast<deUintptr>(sizeof(value1)) });
1634 m_mapEntries.push_back({ 1u, static_cast<deUint32>(offset2), static_cast<deUintptr>(sizeof(value2)) });
1635
1636 // Specialization info.
1637 m_specInfo.mapEntryCount = static_cast<deUint32>(m_mapEntries.size());
1638 m_specInfo.pMapEntries = m_mapEntries.data();
1639 m_specInfo.dataSize = static_cast<deUintptr>(m_data.size());
1640 m_specInfo.pData = m_data.data();
1641 }
1642
getSpecializationInfo(void) const1643 const VkSpecializationInfo& SpecConstantsHelper::getSpecializationInfo (void) const
1644 {
1645 return m_specInfo;
1646 }
1647
runTest(void)1648 de::MovePtr<BufferWithMemory> RayTracingBuiltinLaunchTestInstance::runTest (void)
1649 {
1650 const InstanceInterface& vki = m_context.getInstanceInterface();
1651 const DeviceInterface& vkd = m_context.getDeviceInterface();
1652 const VkDevice device = m_context.getDevice();
1653 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1654 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1655 const VkQueue queue = m_context.getUniversalQueue();
1656 Allocator& allocator = m_context.getDefaultAllocator();
1657 const deUint32 shaderGroupHandleSize = getShaderGroupSize(vki, physicalDevice);
1658 const VkFormat format = m_data.format;
1659 const deUint32 pixelSize = tcu::getPixelSize(mapVkFormat(format));
1660 const deUint32 pixelCount = m_data.width * m_data.height * m_data.depth;
1661
1662 const Move<VkDescriptorSetLayout> descriptorSetLayout = DescriptorSetLayoutBuilder()
1663 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
1664 .addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1665 .build(vkd, device);
1666 const Move<VkDescriptorPool> descriptorPool = DescriptorPoolBuilder()
1667 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1668 .addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1669 .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1670 const Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
1671 const Move<VkPipelineLayout> pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
1672 const Move<VkCommandPool> cmdPool = createCommandPool(vkd, device, 0, queueFamilyIndex);
1673 const Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1674
1675 de::MovePtr<RayTracingPipeline> rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
1676 const SpecConstantsHelper specConstantHelper;
1677 const VkSpecializationInfo* specializationInfo = (m_data.useSpecConstants ? &specConstantHelper.getSpecializationInfo() : nullptr);
1678 const Move<VkPipeline> pipeline = makePipeline(rayTracingPipeline, *pipelineLayout, specializationInfo);
1679 const de::MovePtr<BufferWithMemory> raygenShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *pipeline, allocator, rayTracingPipeline, m_raygenShaderGroup);
1680 const de::MovePtr<BufferWithMemory> missShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *pipeline, allocator, rayTracingPipeline, m_missShaderGroup);
1681 const de::MovePtr<BufferWithMemory> hitShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *pipeline, allocator, rayTracingPipeline, m_hitShaderGroup);
1682 const de::MovePtr<BufferWithMemory> callableShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *pipeline, allocator, rayTracingPipeline, m_callableShaderGroup);
1683
1684 const VkStridedDeviceAddressRegionKHR raygenShaderBindingTableRegion = raygenShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1685 const VkStridedDeviceAddressRegionKHR missShaderBindingTableRegion = missShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1686 const VkStridedDeviceAddressRegionKHR hitShaderBindingTableRegion = hitShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1687 const VkStridedDeviceAddressRegionKHR callableShaderBindingTableRegion = callableShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1688
1689 const VkImageCreateInfo imageCreateInfo = makeImageCreateInfo(m_data.width, m_data.height, m_data.depth, format);
1690 const VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0, 1u);
1691 const de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1692 const Move<VkImageView> imageView = makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, format, imageSubresourceRange);
1693
1694 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(pixelCount * pixelSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
1695 const VkImageSubresourceLayers bufferImageSubresourceLayers = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1696 const VkBufferImageCopy bufferImageRegion = makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, m_data.depth), bufferImageSubresourceLayers);
1697 de::MovePtr<BufferWithMemory> buffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
1698
1699 const VkDescriptorImageInfo descriptorImageInfo = makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
1700
1701 const VkImageMemoryBarrier preImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
1702 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1703 **image, imageSubresourceRange);
1704 const VkImageMemoryBarrier postImageBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
1705 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1706 **image, imageSubresourceRange);
1707 const VkMemoryBarrier postTraceMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
1708 const VkMemoryBarrier postCopyMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
1709 const VkClearValue clearValue = makeClearValueColorU32(DEFAULT_UINT_CLEAR_VALUE, DEFAULT_UINT_CLEAR_VALUE, DEFAULT_UINT_CLEAR_VALUE, 255u);
1710
1711 vector<de::SharedPtr<BottomLevelAccelerationStructure> > bottomLevelAccelerationStructures;
1712 de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure;
1713
1714 beginCommandBuffer(vkd, *cmdBuffer, 0u);
1715 {
1716 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
1717 vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
1718 cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
1719
1720 bottomLevelAccelerationStructures = initBottomAccelerationStructures(*cmdBuffer);
1721 topLevelAccelerationStructure = initTopAccelerationStructure(*cmdBuffer, bottomLevelAccelerationStructures);
1722
1723 const TopLevelAccelerationStructure* topLevelAccelerationStructurePtr = topLevelAccelerationStructure.get();
1724 VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
1725 {
1726 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, // VkStructureType sType;
1727 DE_NULL, // const void* pNext;
1728 1u, // deUint32 accelerationStructureCount;
1729 topLevelAccelerationStructurePtr->getPtr(), // const VkAccelerationStructureKHR* pAccelerationStructures;
1730 };
1731
1732 DescriptorSetUpdateBuilder()
1733 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
1734 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1735 .update(vkd, device);
1736
1737 vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
1738
1739 vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipeline);
1740
1741 cmdTraceRays(vkd,
1742 *cmdBuffer,
1743 &raygenShaderBindingTableRegion,
1744 &missShaderBindingTableRegion,
1745 &hitShaderBindingTableRegion,
1746 &callableShaderBindingTableRegion,
1747 m_data.width, m_data.height, m_data.raysDepth);
1748
1749 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier);
1750
1751 vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **buffer, 1u, &bufferImageRegion);
1752
1753 cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
1754 }
1755 endCommandBuffer(vkd, *cmdBuffer);
1756
1757 submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1758
1759 invalidateMappedMemoryRange(vkd, device, buffer->getAllocation().getMemory(), buffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
1760
1761 return buffer;
1762 }
1763
checkFormatSupported(Context & context,VkFormat format,VkImageUsageFlags usage,const VkExtent3D & extent)1764 void checkFormatSupported(Context& context, VkFormat format, VkImageUsageFlags usage, const VkExtent3D& extent)
1765 {
1766 VkResult result;
1767 VkImageFormatProperties properties;
1768
1769 result = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(), format, VK_IMAGE_TYPE_3D, VK_IMAGE_TILING_OPTIMAL, usage, 0, &properties);
1770
1771 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
1772 {
1773 std::ostringstream msg;
1774
1775 msg << "Format " << format << " not supported for usage flags 0x" << std::hex << usage;
1776
1777 TCU_THROW(NotSupportedError, msg.str());
1778 }
1779
1780 if (properties.maxExtent.width < extent.width || properties.maxExtent.height < extent.height || properties.maxExtent.depth < extent.depth)
1781 TCU_THROW(NotSupportedError, "Image size is too large for this format");
1782
1783 VK_CHECK(result);
1784 }
1785
checkSupportInInstance(void) const1786 void RayTracingBuiltinLaunchTestInstance::checkSupportInInstance (void) const
1787 {
1788 const InstanceInterface& vki = m_context.getInstanceInterface();
1789 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1790 const vk::VkPhysicalDeviceProperties& properties = m_context.getDeviceProperties();
1791 const deUint32 requiredAllocations = 8u
1792 + TopLevelAccelerationStructure::getRequiredAllocationCount()
1793 + m_data.instancesGroupCount * BottomLevelAccelerationStructure::getRequiredAllocationCount();
1794 const de::MovePtr<RayTracingProperties> rayTracingProperties = makeRayTracingProperties(vki, physicalDevice);
1795 const VkExtent3D extent = makeExtent3D(m_data.width, m_data.height, m_data.depth);
1796
1797 checkFormatSupported(m_context, m_data.format, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, extent);
1798
1799 if (rayTracingProperties->getMaxPrimitiveCount() < 2 * m_data.squaresGroupCount)
1800 TCU_THROW(NotSupportedError, "Triangles required more than supported");
1801
1802 if (rayTracingProperties->getMaxGeometryCount() < m_data.geometriesGroupCount)
1803 TCU_THROW(NotSupportedError, "Geometries required more than supported");
1804
1805 if (rayTracingProperties->getMaxInstanceCount() < m_data.instancesGroupCount)
1806 TCU_THROW(NotSupportedError, "Instances required more than supported");
1807
1808 if (properties.limits.maxMemoryAllocationCount < requiredAllocations)
1809 TCU_THROW(NotSupportedError, "Test requires more allocations allowed");
1810 }
1811
expectedIntValuesBuffer(void)1812 std::vector<deInt32> RayTracingBuiltinLaunchTestInstance::expectedIntValuesBuffer (void)
1813 {
1814 deUint32 pos = 0;
1815 std::vector<deInt32> result;
1816
1817 result.reserve(m_data.depth * m_data.height * m_data.width);
1818
1819 if (m_data.id == TEST_ID_LAUNCH_ID_EXT)
1820 {
1821 for (deUint32 z = 0; z < m_data.depth; ++z)
1822 for (deUint32 y = 0; y < m_data.height; ++y)
1823 for (deUint32 x = 0; x < m_data.width; ++x)
1824 result.push_back(deInt32(x + 256 * (y + 256 * z)) + 1);
1825 }
1826 else if (m_data.id == TEST_ID_LAUNCH_SIZE_EXT)
1827 {
1828 const deUint32 expectedValue = m_data.width + 256 * (m_data.height + 256 * m_data.depth);
1829 const std::vector<deInt32> result2 (m_data.depth * m_data.height * m_data.width, deInt32(expectedValue) + 1);
1830
1831 result = result2;
1832 }
1833 else if (m_data.id == TEST_ID_GEOMETRY_INDEX_EXT)
1834 {
1835 for (deUint32 z = 0; z < m_data.depth; ++z)
1836 for (deUint32 y = 0; y < m_data.height; ++y)
1837 for (deUint32 x = 0; x < m_data.width; ++x)
1838 result.push_back(deInt32((pos++ / m_data.squaresGroupCount) % m_data.geometriesGroupCount));
1839 }
1840 else if (m_data.id == TEST_ID_PRIMITIVE_ID)
1841 {
1842 for (deUint32 z = 0; z < m_data.depth; ++z)
1843 for (deUint32 y = 0; y < m_data.height; ++y)
1844 for (deUint32 x = 0; x < m_data.width; ++x)
1845 result.push_back(deInt32(pos++ % m_data.squaresGroupCount));
1846 }
1847 else if (m_data.id == TEST_ID_INSTANCE_ID)
1848 {
1849 for (deUint32 z = 0; z < m_data.depth; ++z)
1850 for (deUint32 y = 0; y < m_data.height; ++y)
1851 for (deUint32 x = 0; x < m_data.width; ++x)
1852 result.push_back(deInt32(pos++ / (m_data.squaresGroupCount * m_data.geometriesGroupCount)));
1853 }
1854 else if (m_data.id == TEST_ID_INSTANCE_CUSTOM_INDEX_EXT)
1855 {
1856 for (deUint32 z = 0; z < m_data.depth; ++z)
1857 for (deUint32 y = 0; y < m_data.height; ++y)
1858 for (deUint32 x = 0; x < m_data.width; ++x)
1859 result.push_back(deInt32(2 * (pos++ / (m_data.squaresGroupCount * m_data.geometriesGroupCount))));
1860 }
1861 else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_EXT)
1862 {
1863 DE_ASSERT(m_data.squaresGroupCount == (1<<RAY_FLAG_BIT_LAST_PER_TEST));
1864 DE_ASSERT(DEFAULT_UINT_CLEAR_VALUE != (1<<RAY_FLAG_BIT_LAST_PER_TEST));
1865
1866 for (deUint32 z = 0; z < m_data.depth; ++z)
1867 for (deUint32 y = 0; y < m_data.height; ++y)
1868 for (deUint32 x = 0; x < m_data.width; ++x)
1869 {
1870 const deUint32 n = x + m_data.width * (y + m_data.height * z);
1871 const bool rayOpaque = (0 != (n & (1<<RAY_FLAG_BIT_OPAQUE_EXT )));
1872 const bool rayNoOpaque = (0 != (n & (1<<RAY_FLAG_BIT_NO_OPAQUE_EXT ))) && !rayOpaque;
1873 const bool rayTerminateOnFirstHit = (0 != (n & (1<<RAY_FLAG_BIT_TERMINATE_ON_FIRST_HIT_EXT )));
1874 const bool raySkipClosestHitShader = (0 != (n & (1<<RAY_FLAG_BIT_SKIP_CLOSEST_HIT_SHADER_EXT )));
1875 const bool rayCullBack = (0 != (n & (1<<RAY_FLAG_BIT_CULL_BACK_FACING_TRIANGLES_EXT )));
1876 const bool rayCullFront = (0 != (n & (1<<RAY_FLAG_BIT_CULL_FRONT_FACING_TRIANGLES_EXT))) && !rayCullBack;
1877 const bool rayCullOpaque = (0 != (n & (1<<RAY_FLAG_BIT_CULL_OPAQUE_EXT ))) && !rayOpaque && !rayNoOpaque;
1878 const bool rayCullNoOpaque = (0 != (n & (1<<RAY_FLAG_BIT_CULL_NO_OPAQUE_EXT ))) && !rayOpaque && !rayNoOpaque && !rayCullOpaque;
1879 const bool raySkipTriangles = m_data.rayFlagSkipTriangles;
1880 const bool raySkipAABBs = m_data.rayFlagSkipAABSs;
1881 const bool pipelineSkipTriangles = (m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR) != 0;
1882 const bool pipelineSkipAABBs = (m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR) != 0;
1883 const bool cullingTest = m_data.rayFlagSkipTriangles || m_data.rayFlagSkipAABSs || pipelineSkipTriangles || pipelineSkipAABBs;
1884 const bool geometryFrontFace = m_data.frontFace;
1885 const bool geometryOpaque = m_data.opaque;
1886 const bool geometryTriangles = (m_data.geomType == GEOM_TYPE_TRIANGLES) ? true : false;
1887 const bool geometryAABBs = (m_data.geomType == GEOM_TYPE_AABBS) ? true : false;
1888 deUint32 v = 0
1889 | (rayOpaque ? (1<<RAY_FLAG_BIT_OPAQUE_EXT ) : 0)
1890 | (rayNoOpaque ? (1<<RAY_FLAG_BIT_NO_OPAQUE_EXT ) : 0)
1891 | (rayTerminateOnFirstHit ? (1<<RAY_FLAG_BIT_TERMINATE_ON_FIRST_HIT_EXT ) : 0)
1892 | (raySkipClosestHitShader ? (1<<RAY_FLAG_BIT_SKIP_CLOSEST_HIT_SHADER_EXT ) : 0)
1893 | (rayCullBack ? (1<<RAY_FLAG_BIT_CULL_BACK_FACING_TRIANGLES_EXT ) : 0)
1894 | (rayCullFront ? (1<<RAY_FLAG_BIT_CULL_FRONT_FACING_TRIANGLES_EXT) : 0)
1895 | (rayCullOpaque ? (1<<RAY_FLAG_BIT_CULL_OPAQUE_EXT ) : 0)
1896 | (rayCullNoOpaque ? (1<<RAY_FLAG_BIT_CULL_NO_OPAQUE_EXT ) : 0)
1897 | (raySkipTriangles ? (1<<RAY_FLAG_BIT_SKIP_TRIANGLES_EXT ) : 0)
1898 | (raySkipAABBs ? (1<<RAY_FLAG_BIT_SKIP_AABB_EXT ) : 0);
1899
1900 if (m_data.stage == VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR && raySkipClosestHitShader)
1901 v = DEFAULT_UINT_CLEAR_VALUE;
1902
1903 if (m_data.stage == VK_SHADER_STAGE_ANY_HIT_BIT_KHR && (rayOpaque || (geometryOpaque && !rayOpaque && !rayNoOpaque)))
1904 v = DEFAULT_UINT_CLEAR_VALUE;
1905
1906 if (geometryOpaque)
1907 {
1908 if (rayCullOpaque)
1909 if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1910 v = DEFAULT_UINT_CLEAR_VALUE;
1911 }
1912 else
1913 {
1914 if (rayCullNoOpaque)
1915 if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1916 v = DEFAULT_UINT_CLEAR_VALUE;
1917 }
1918
1919 if (geometryTriangles)
1920 {
1921 if (geometryFrontFace)
1922 {
1923 if (rayCullFront)
1924 if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1925 v = DEFAULT_UINT_CLEAR_VALUE;
1926 }
1927 else
1928 {
1929 if (rayCullBack)
1930 if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1931 v = DEFAULT_UINT_CLEAR_VALUE;
1932 }
1933 }
1934
1935 if (cullingTest)
1936 {
1937 if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1938 {
1939 if (geometryTriangles)
1940 {
1941 if (raySkipTriangles || pipelineSkipTriangles)
1942 v = DEFAULT_UINT_CLEAR_VALUE;
1943 }
1944
1945 if (geometryAABBs)
1946 {
1947 if (raySkipAABBs || pipelineSkipAABBs)
1948 v = DEFAULT_UINT_CLEAR_VALUE;
1949 }
1950 }
1951 }
1952
1953 result.push_back(deInt32(v));
1954 }
1955 }
1956 else if (m_data.id == TEST_ID_HIT_KIND_EXT)
1957 {
1958 for (deUint32 z = 0; z < m_data.depth; ++z)
1959 for (deUint32 y = 0; y < m_data.height; ++y)
1960 for (deUint32 x = 0; x < m_data.width; ++x)
1961 {
1962 const deUint32 n = x + m_data.width * (y + m_data.height * z);
1963 const deUint32 geometryNdx = n / m_data.squaresGroupCount;
1964 const deUint32 hitKind = ((geometryNdx & 1) == 0) ? 0xFEu : 0xFFu;
1965 const bool geometryOpaque = ((geometryNdx & 2) == 0) ? true : false;
1966 deUint32 v = (m_data.geomType == GEOM_TYPE_TRIANGLES) ? hitKind : 0x7Eu;
1967
1968 if (m_data.stage == VK_SHADER_STAGE_ANY_HIT_BIT_KHR && geometryOpaque)
1969 v = DEFAULT_UINT_CLEAR_VALUE;
1970
1971 result.push_back(deInt32(v));
1972 }
1973 }
1974 else
1975 {
1976 TCU_THROW(InternalError, "Not implemented");
1977 }
1978
1979 return result;
1980 }
1981
expectedFloatValuesBuffer(void)1982 std::vector<float> RayTracingBuiltinLaunchTestInstance::expectedFloatValuesBuffer (void)
1983 {
1984 std::vector<float> result;
1985
1986 result.reserve(m_data.depth * m_data.height * m_data.width);
1987
1988 if (m_data.id == TEST_ID_HIT_T_EXT)
1989 {
1990 for (deUint32 z = 0; z < m_data.depth; ++z)
1991 for (deUint32 y = 0; y < m_data.height; ++y)
1992 for (deUint32 x = 0; x < m_data.width; ++x)
1993 {
1994 const float a = float(x) / float(m_data.width);
1995 const float b = 1.0f + float(y) / float(m_data.height);
1996 const float f = 0.03125f + 0.25f * a / b;
1997
1998 result.push_back(f);
1999 }
2000 }
2001 else if (m_data.id == TEST_ID_RAY_T_MIN_EXT)
2002 {
2003 for (deUint32 z = 0; z < m_data.depth; ++z)
2004 for (deUint32 y = 0; y < m_data.height; ++y)
2005 for (deUint32 x = 0; x < m_data.width; ++x)
2006 {
2007 const float a = float(x) / float(m_data.width);
2008 const float b = 1.0f + float(y) / float(m_data.height);
2009 const float f = 0.25f * a / b;
2010
2011 result.push_back(f);
2012 }
2013 }
2014 else if (m_data.id == TEST_ID_RAY_T_MAX_EXT)
2015 {
2016 for (deUint32 z = 0; z < m_data.depth; ++z)
2017 for (deUint32 y = 0; y < m_data.height; ++y)
2018 for (deUint32 x = 0; x < m_data.width; ++x)
2019 {
2020 const float a = float(x) / float(m_data.width);
2021 const float b = 1.0f + float(y) / float(m_data.height);
2022 const float c = 0.25f * a / b;
2023 // In a miss shader, the value is identical to the parameter passed into traceRayEXT().
2024 const float m = 0.75f + c;
2025 // In the closest-hit shader, the value reflects the closest distance to the intersected primitive.
2026 // In the any-hit shader, it reflects the distance to the primitive currently being intersected.
2027 // In the intersection shader, it reflects the distance to the closest primitive intersected so far.
2028 const float n = 0.03125f + c;
2029 const bool normalRow = (y & 1) != 0;
2030 const bool doublePrimitive = (x & 1) != 0;
2031 const float s = normalRow ? m
2032 : doublePrimitive ? 0.4375f + c
2033 : float(DEFAULT_UINT_CLEAR_VALUE) / float(FIXED_POINT_DIVISOR);
2034 const float f = (m_data.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR) ? s
2035 : (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR) ? m
2036 : n;
2037
2038 result.push_back(f);
2039 }
2040 }
2041 else
2042 {
2043 TCU_THROW(InternalError, "Not implemented");
2044 }
2045
2046 return result;
2047 }
2048
expectedVectorValuesBuffer(void)2049 std::vector<float> RayTracingBuiltinLaunchTestInstance::expectedVectorValuesBuffer (void)
2050 {
2051 const deUint32 imageDepth = 4;
2052 const deUint32 expectedFloats = imageDepth * m_data.height * m_data.width;
2053 std::vector<float> result (expectedFloats, float(DEFAULT_UINT_CLEAR_VALUE) / float(FIXED_POINT_DIVISOR));
2054
2055 if (m_data.id == TEST_ID_WORLD_RAY_ORIGIN_EXT)
2056 {
2057 deUint32 pos = 0;
2058
2059 for (deUint32 y = 0; y < m_data.height; ++y)
2060 for (deUint32 x = 0; x < m_data.width; ++x)
2061 result[pos++] = (0.5f + float(x)) / float(m_data.width);
2062
2063 for (deUint32 y = 0; y < m_data.height; ++y)
2064 for (deUint32 x = 0; x < m_data.width; ++x)
2065 result[pos++] = (0.5f + float(y)) / float(m_data.height);
2066
2067 for (deUint32 y = 0; y < m_data.height; ++y)
2068 for (deUint32 x = 0; x < m_data.width; ++x)
2069 result[pos++] = 0.0f;
2070 }
2071 else if (m_data.id == TEST_ID_WORLD_RAY_DIRECTION_EXT)
2072 {
2073 deUint32 pos = 0;
2074
2075 for (deUint32 y = 0; y < m_data.height; ++y)
2076 for (deUint32 x = 0; x < m_data.width; ++x)
2077 result[pos++] = 0.0f;
2078
2079 for (deUint32 y = 0; y < m_data.height; ++y)
2080 for (deUint32 x = 0; x < m_data.width; ++x)
2081 result[pos++] = 0.0f;
2082
2083 for (deUint32 y = 0; y < m_data.height; ++y)
2084 for (deUint32 x = 0; x < m_data.width; ++x)
2085 result[pos++] = -1.0f;
2086 }
2087 else if (m_data.id == TEST_ID_OBJECT_RAY_ORIGIN_EXT)
2088 {
2089 deUint32 pos = 0;
2090
2091 for (deUint32 y = 0; y < m_data.height; ++y)
2092 for (deUint32 x = 0; x < m_data.width; ++x)
2093 {
2094 const deUint32 instanceId = y / (m_data.height / m_data.instancesGroupCount);
2095 const float offset = (instanceId & 1) ? 1.0f / 8.0f : 0.0f;
2096
2097 result[pos++] = (0.5f + float(x) - offset) / float(m_data.width);
2098 }
2099
2100 for (deUint32 y = 0; y < m_data.height; ++y)
2101 for (deUint32 x = 0; x < m_data.width; ++x)
2102 {
2103 const deUint32 instanceId = y / (m_data.height / m_data.instancesGroupCount);
2104 const float offset = (instanceId & 2) ? 1.0f / 16.0f : 0.0f;
2105
2106 result[pos++] = (0.5f + float(y) - offset) / float(m_data.height);
2107 }
2108
2109 for (deUint32 y = 0; y < m_data.height; ++y)
2110 for (deUint32 x = 0; x < m_data.width; ++x)
2111 result[pos++] = 0.0f;
2112 }
2113 else if (m_data.id == TEST_ID_OBJECT_RAY_DIRECTION_EXT)
2114 {
2115 deUint32 pos = 0;
2116
2117 for (deUint32 y = 0; y < m_data.height; ++y)
2118 for (deUint32 x = 0; x < m_data.width; ++x)
2119 result[pos++] = 0.0f;
2120
2121 for (deUint32 y = 0; y < m_data.height; ++y)
2122 for (deUint32 x = 0; x < m_data.width; ++x)
2123 result[pos++] = 0.0f;
2124
2125 for (deUint32 y = 0; y < m_data.height; ++y)
2126 for (deUint32 x = 0; x < m_data.width; ++x)
2127 result[pos++] = -1.0f;
2128 }
2129 else
2130 {
2131 TCU_THROW(InternalError, "Not implemented");
2132 }
2133
2134 return result;
2135 }
2136
expectedMatrixValuesBuffer(void)2137 std::vector<float> RayTracingBuiltinLaunchTestInstance::expectedMatrixValuesBuffer (void)
2138 {
2139 const deUint32 colCount = 4;
2140 const deUint32 rowCount = 3;
2141 const deUint32 imageDepth = 4 * 4;
2142 const deUint32 zStride = m_data.height * m_data.width;
2143 const deUint32 expectedFloats = imageDepth * m_data.height * m_data.width;
2144 std::vector<float> result (expectedFloats, float(DEFAULT_UINT_CLEAR_VALUE) / float(FIXED_POINT_DIVISOR));
2145
2146 if (m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT ||
2147 m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT ||
2148 m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT ||
2149 m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT)
2150 {
2151 const int translateColumnNumber = 3;
2152 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;
2153 const float translateX = translateSign * (1.0f / 8.0f) / float(m_data.width);
2154 const float translateY = translateSign * (1.0f / 16.0f) / float(m_data.height);
2155
2156 for (deUint32 y = 0; y < m_data.height; ++y)
2157 {
2158 const deUint32 instanceId = y / (m_data.height / m_data.instancesGroupCount);
2159
2160 for (deUint32 x = 0; x < m_data.width; ++x)
2161 {
2162 tcu::Matrix<float, rowCount, colCount> m;
2163 const deUint32 elem0Pos = x + m_data.width * y;
2164
2165 if (instanceId & 1)
2166 m[translateColumnNumber][0] = translateX;
2167
2168 if (instanceId & 2)
2169 m[translateColumnNumber][1] = translateY;
2170
2171 for (deUint32 rowNdx = 0; rowNdx < rowCount; ++rowNdx)
2172 for (deUint32 colNdx = 0; colNdx < colCount; ++colNdx)
2173 {
2174 const deUint32 z = rowNdx * colCount + colNdx;
2175 const deUint32 pos = elem0Pos + zStride * z;
2176
2177 result[pos] = m[colNdx][rowNdx];
2178 }
2179 }
2180 }
2181 }
2182 else
2183 {
2184 TCU_THROW(InternalError, "Not implemented");
2185 }
2186
2187 return result;
2188 }
2189
validateIntBuffer(de::MovePtr<BufferWithMemory> buffer)2190 bool RayTracingBuiltinLaunchTestInstance::validateIntBuffer (de::MovePtr<BufferWithMemory> buffer)
2191 {
2192 const deInt32* bufferPtr = (deInt32*)buffer->getAllocation().getHostPtr();
2193 const vector<deInt32> expectedValues = expectedIntValuesBuffer();
2194 tcu::TestLog& log = m_context.getTestContext().getLog();
2195 deUint32 failures = 0;
2196 deUint32 pos = 0;
2197
2198 for (deUint32 z = 0; z < m_data.depth; ++z)
2199 for (deUint32 y = 0; y < m_data.height; ++y)
2200 for (deUint32 x = 0; x < m_data.width; ++x)
2201 {
2202 if (bufferPtr[pos] != expectedValues[pos])
2203 failures++;
2204
2205 ++pos;
2206 }
2207
2208 if (failures != 0)
2209 {
2210 const char * names[] = { "Retrieved:", "Expected:" };
2211 for (deUint32 n = 0; n < 2; ++n)
2212 {
2213 const deInt32* loggedData = (n == 0) ? bufferPtr : expectedValues.data();
2214 std::stringstream css;
2215
2216 pos = 0;
2217
2218 for (deUint32 z = 0; z < m_data.depth; ++z)
2219 for (deUint32 y = 0; y < m_data.height; ++y)
2220 {
2221 for (deUint32 x = 0; x < m_data.width; ++x)
2222 {
2223 if (bufferPtr[pos] == expectedValues[pos])
2224 css << "____,";
2225 else
2226 css << std::hex << std::setw(4) << loggedData[pos] << ",";
2227
2228 pos++;
2229 }
2230
2231 css << std::endl;
2232 }
2233
2234 log << tcu::TestLog::Message << names[n] << tcu::TestLog::EndMessage;
2235 log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
2236 }
2237 }
2238
2239 return failures == 0;
2240 }
2241
validateFloatBuffer(de::MovePtr<BufferWithMemory> buffer)2242 bool RayTracingBuiltinLaunchTestInstance::validateFloatBuffer (de::MovePtr<BufferWithMemory> buffer)
2243 {
2244 const float eps = float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
2245 const deInt32* bufferPtr = (deInt32*)buffer->getAllocation().getHostPtr();
2246 const vector<float> expectedValues = expectedFloatValuesBuffer();
2247 tcu::TestLog& log = m_context.getTestContext().getLog();
2248 deUint32 failures = 0;
2249 deUint32 pos = 0;
2250
2251 for (deUint32 z = 0; z < m_data.depth; ++z)
2252 for (deUint32 y = 0; y < m_data.height; ++y)
2253 for (deUint32 x = 0; x < m_data.width; ++x)
2254 {
2255 const float retrievedValue = float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2256
2257 if (deFloatAbs(retrievedValue - expectedValues[pos]) > eps)
2258 failures++;
2259
2260 ++pos;
2261 }
2262
2263 if (failures != 0)
2264 {
2265 const char * names[] = { "Retrieved:", "Expected:" };
2266
2267 for (deUint32 n = 0; n < 2; ++n)
2268 {
2269 std::stringstream css;
2270
2271 pos = 0;
2272
2273 for (deUint32 z = 0; z < m_data.depth; ++z)
2274 for (deUint32 y = 0; y < m_data.height; ++y)
2275 {
2276 for (deUint32 x = 0; x < m_data.width; ++x)
2277 {
2278 const float retrievedValue = float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2279 const float expectedValue = expectedValues[pos];
2280
2281 if (deFloatAbs(retrievedValue - expectedValue) > eps)
2282 css << std::setprecision(8) << std::setw(12) << (n == 0 ? retrievedValue : expectedValue) << ",";
2283 else
2284 css << "____________,";
2285
2286 pos++;
2287 }
2288
2289 css << std::endl;
2290 }
2291
2292 log << tcu::TestLog::Message << names[n] << tcu::TestLog::EndMessage;
2293 log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
2294 }
2295 }
2296
2297 return failures == 0;
2298 }
2299
validateVectorBuffer(de::MovePtr<BufferWithMemory> buffer)2300 bool RayTracingBuiltinLaunchTestInstance::validateVectorBuffer (de::MovePtr<BufferWithMemory> buffer)
2301 {
2302 const float eps = float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
2303 const deInt32* bufferPtr = (deInt32*)buffer->getAllocation().getHostPtr();
2304 const vector<float> expectedValues = expectedVectorValuesBuffer();
2305 const deUint32 depth = 3u; // vec3
2306 tcu::TestLog& log = m_context.getTestContext().getLog();
2307 deUint32 failures = 0;
2308 deUint32 pos = 0;
2309
2310 DE_ASSERT(depth <= m_data.depth);
2311
2312 for (deUint32 z = 0; z < depth; ++z)
2313 for (deUint32 y = 0; y < m_data.height; ++y)
2314 for (deUint32 x = 0; x < m_data.width; ++x)
2315 {
2316 const float retrievedValue = float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2317
2318 if (deFloatAbs(retrievedValue - expectedValues[pos]) > eps)
2319 failures++;
2320
2321 ++pos;
2322 }
2323
2324 if (failures != 0)
2325 {
2326 const char* names[] = { "Retrieved", "Expected " };
2327 std::stringstream css;
2328
2329 for (deUint32 y = 0; y < m_data.height; ++y)
2330 {
2331 for (deUint32 x = 0; x < m_data.width; ++x)
2332 {
2333 for (deUint32 n = 0; n < 2; ++n)
2334 {
2335 css << names[n] << " at (" << x << "," << y << ") {";
2336
2337 for (deUint32 z = 0; z < depth; ++z)
2338 {
2339 pos = x + m_data.width * (y + m_data.height * z);
2340
2341 const float retrievedValue = float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2342 const float expectedValue = expectedValues[pos];
2343
2344 if (deFloatAbs(retrievedValue - expectedValue) > eps)
2345 css << std::setprecision(8) << std::setw(12) << (n == 0 ? retrievedValue : expectedValue) << ",";
2346 else
2347 css << "____________,";
2348 }
2349
2350 css << "}" << std::endl;
2351 }
2352 }
2353 }
2354
2355 log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
2356 }
2357
2358 return failures == 0;
2359 }
2360
validateMatrixBuffer(de::MovePtr<BufferWithMemory> buffer)2361 bool RayTracingBuiltinLaunchTestInstance::validateMatrixBuffer (de::MovePtr<BufferWithMemory> buffer)
2362 {
2363 const float eps = float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
2364 const deInt32* bufferPtr = (deInt32*)buffer->getAllocation().getHostPtr();
2365 const vector<float> expectedValues = expectedMatrixValuesBuffer();
2366 const deUint32 depth = 12u; // mat3x4 or mat4x3
2367 tcu::TestLog& log = m_context.getTestContext().getLog();
2368 deUint32 failures = 0;
2369 deUint32 pos = 0;
2370
2371 DE_ASSERT(depth <= m_data.depth);
2372
2373 for (deUint32 z = 0; z < depth; ++z)
2374 for (deUint32 y = 0; y < m_data.height; ++y)
2375 for (deUint32 x = 0; x < m_data.width; ++x)
2376 {
2377 const float retrievedValue = float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2378
2379 if (deFloatAbs(retrievedValue - expectedValues[pos]) > eps)
2380 failures++;
2381
2382 ++pos;
2383 }
2384
2385 if (failures != 0)
2386 {
2387 const char* names[] = { "Retrieved", "Expected" };
2388 std::stringstream css;
2389
2390 for (deUint32 y = 0; y < m_data.height; ++y)
2391 {
2392 for (deUint32 x = 0; x < m_data.width; ++x)
2393 {
2394 css << "At (" << x << "," << y << ")" << std::endl;
2395 for (deUint32 n = 0; n < 2; ++n)
2396 {
2397 css << names[n] << std::endl << "{" << std::endl;
2398
2399 for (deUint32 z = 0; z < depth; ++z)
2400 {
2401 pos = x + m_data.width * (y + m_data.height * z);
2402
2403 const float retrievedValue = float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2404 const float expectedValue = expectedValues[pos];
2405
2406 if (z % 4 == 0)
2407 css << " {";
2408
2409 if (deFloatAbs(retrievedValue - expectedValue) > eps)
2410 css << std::setprecision(5) << std::setw(9) << (n == 0 ? retrievedValue : expectedValue) << ",";
2411 else
2412 css << "_________,";
2413
2414 if (z % 4 == 3)
2415 css << "}" << std::endl;
2416 }
2417
2418 css << "}" << std::endl;
2419 }
2420 }
2421 }
2422
2423 log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
2424 }
2425
2426 return failures == 0;
2427 }
2428
iterate(void)2429 tcu::TestStatus RayTracingBuiltinLaunchTestInstance::iterate (void)
2430 {
2431 checkSupportInInstance();
2432
2433 de::MovePtr<BufferWithMemory> buffer = runTest();
2434 const bool ok = m_data.fixedPointMatrixOutput ? validateMatrixBuffer(buffer)
2435 : m_data.fixedPointVectorOutput ? validateVectorBuffer(buffer)
2436 : m_data.fixedPointScalarOutput ? validateFloatBuffer(buffer)
2437 : validateIntBuffer(buffer);
2438
2439 if (ok)
2440 return tcu::TestStatus::pass("pass");
2441 else
2442 return tcu::TestStatus::fail("fail");
2443 }
2444
2445 static const struct Stages
2446 {
2447 const char* name;
2448 VkShaderStageFlagBits stage;
2449 }
2450 stages[]
2451 {
2452 { "rgen", VK_SHADER_STAGE_RAYGEN_BIT_KHR },
2453 { "ahit", VK_SHADER_STAGE_ANY_HIT_BIT_KHR },
2454 { "chit", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR },
2455 { "sect", VK_SHADER_STAGE_INTERSECTION_BIT_KHR },
2456 { "miss", VK_SHADER_STAGE_MISS_BIT_KHR },
2457 { "call", VK_SHADER_STAGE_CALLABLE_BIT_KHR },
2458 };
2459
2460 static const struct GeomTypes
2461 {
2462 const char* name;
2463 GeomType geomType;
2464 }
2465 geomTypes[] =
2466 {
2467 { "triangles", GEOM_TYPE_TRIANGLES },
2468 { "aabs", GEOM_TYPE_AABBS },
2469 };
2470
createLaunchTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * builtinGroup,TestId id,const char * name,const VkShaderStageFlags shaderStageFlags)2471 void createLaunchTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)
2472 {
2473 const struct
2474 {
2475 deUint32 width;
2476 deUint32 height;
2477 deUint32 depth;
2478 }
2479 sizes[] =
2480 {
2481 { 1, 1, 1 },
2482 { 16, 16, 16 },
2483 { 256, 256, 1 },
2484 { 16384, 1, 1 },
2485 { 1, 16384, 1 },
2486 { 1, 1, 16384 },
2487 { 128, 128, 128 },
2488 { 2048, 4096, 1 },
2489 { 317, 3331, 1 },
2490 { 1, 1331, 111 },
2491 };
2492
2493 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, de::toLower(name).c_str(), ""));
2494
2495 for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
2496 {
2497 if ((shaderStageFlags & stages[stageNdx].stage) == 0)
2498 continue;
2499
2500 for (size_t sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
2501 {
2502 const deUint32 width = sizes[sizeNdx].width;
2503 const deUint32 height = sizes[sizeNdx].height;
2504 const deUint32 depth = sizes[sizeNdx].depth;
2505 const bool plain = isPlain(width, height, depth);
2506 const deUint32 k = (plain ? 1 : 6);
2507 const deUint32 largestGroup = k * width * height * depth;
2508 const deUint32 squaresGroupCount = largestGroup;
2509 const deUint32 geometriesGroupCount = 1;
2510 const deUint32 instancesGroupCount = 1;
2511 const CaseDef caseDef =
2512 {
2513 id, // TestId id;
2514 name, // const char* name;
2515 width, // deUint32 width;
2516 height, // deUint32 height;
2517 depth, // deUint32 depth;
2518 depth, // deUint32 raysDepth;
2519 VK_FORMAT_R32_SINT, // VkFormat format;
2520 false, // bool fixedPointScalarOutput;
2521 false, // bool fixedPointVectorOutput;
2522 false, // bool fixedPointMatrixOutput;
2523 GEOM_TYPE_TRIANGLES, // GeomType geomType;
2524 squaresGroupCount, // deUint32 squaresGroupCount;
2525 geometriesGroupCount, // deUint32 geometriesGroupCount;
2526 instancesGroupCount, // deUint32 instancesGroupCount;
2527 stages[stageNdx].stage, // VkShaderStageFlagBits stage;
2528 false, // bool skipTriangles;
2529 false, // bool skipAABSs;
2530 false, // bool opaque;
2531 false, // bool frontFace;
2532 0u, // VkPipelineCreateFlags pipelineCreateFlags;
2533 false, // bool useSpecConstants;
2534 };
2535 const std::string suffix = de::toString(caseDef.width) + '_' + de::toString(caseDef.height) + '_' + de::toString(caseDef.depth);
2536 const std::string testName = string(stages[stageNdx].name) + '_' + suffix;
2537
2538 group->addChild(new RayTracingTestCase(testCtx, testName.c_str(), "", caseDef));
2539 }
2540 }
2541
2542 builtinGroup->addChild(group.release());
2543 }
2544
createScalarTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * builtinGroup,TestId id,const char * name,const VkShaderStageFlags shaderStageFlags)2545 void createScalarTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)
2546 {
2547 const struct
2548 {
2549 deUint32 width;
2550 deUint32 height;
2551 TestId id;
2552 }
2553 sizes[] =
2554 {
2555 { 16, 16, TEST_ID_HIT_KIND_EXT },
2556 { 16, 16, TEST_ID_HIT_T_EXT },
2557 { 16, 16, TEST_ID_RAY_T_MIN_EXT },
2558 { 16, 16, TEST_ID_RAY_T_MAX_EXT },
2559 { 32, 32, TEST_ID_LAST },
2560 { 64, 64, TEST_ID_LAST },
2561 { 256, 256, TEST_ID_LAST },
2562 };
2563 const bool fourGeometryGroups = id == TEST_ID_HIT_KIND_EXT
2564 || id == TEST_ID_HIT_T_EXT
2565 || id == TEST_ID_RAY_T_MIN_EXT
2566 || id == TEST_ID_RAY_T_MAX_EXT;
2567 const bool fixedPointScalarOutput = id == TEST_ID_HIT_T_EXT
2568 || id == TEST_ID_RAY_T_MIN_EXT
2569 || id == TEST_ID_RAY_T_MAX_EXT;
2570 const deUint32 imageDepth = 1;
2571 const deUint32 rayDepth = 1;
2572
2573 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, de::toLower(name).c_str(), ""));
2574
2575 for (size_t geomTypesNdx = 0; geomTypesNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypesNdx)
2576 for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
2577 {
2578 const GeomType geomType = geomTypes[geomTypesNdx].geomType;
2579
2580 if ((shaderStageFlags & stages[stageNdx].stage) == 0)
2581 continue;
2582
2583 if (stages[stageNdx].stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR && geomTypes[geomTypesNdx].geomType == GEOM_TYPE_TRIANGLES)
2584 continue;
2585
2586 bool testAdded = false;
2587 bool generalTestsStarted = false;
2588
2589 for (size_t sizesNdx = 0; sizesNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizesNdx)
2590 {
2591 const bool specializedTest = (sizes[sizesNdx].id != TEST_ID_LAST);
2592 const deUint32 width = sizes[sizesNdx].width;
2593 const deUint32 height = sizes[sizesNdx].height;
2594 const deUint32 instancesGroupCount = fourGeometryGroups ? 1 : 4;
2595 const deUint32 geometriesGroupCount = fourGeometryGroups ? 4 : 8;
2596 const deUint32 largestGroup = width * height / geometriesGroupCount / instancesGroupCount;
2597 const deUint32 squaresGroupCount = largestGroup;
2598 const CaseDef caseDef =
2599 {
2600 id, // TestId id;
2601 name, // const char* name;
2602 width, // deUint32 width;
2603 height, // deUint32 height;
2604 imageDepth, // deUint32 depth;
2605 rayDepth, // deUint32 raysDepth;
2606 VK_FORMAT_R32_SINT, // VkFormat format;
2607 fixedPointScalarOutput, // bool fixedPointScalarOutput;
2608 false, // bool fixedPointVectorOutput;
2609 false, // bool fixedPointMatrixOutput;
2610 geomType, // GeomType geomType;
2611 squaresGroupCount, // deUint32 squaresGroupCount;
2612 geometriesGroupCount, // deUint32 geometriesGroupCount;
2613 instancesGroupCount, // deUint32 instancesGroupCount;
2614 stages[stageNdx].stage, // VkShaderStageFlagBits stage;
2615 false, // bool skipTriangles;
2616 false, // bool skipAABSs;
2617 false, // bool opaque;
2618 false, // bool frontFace;
2619 0u, // VkPipelineCreateFlags pipelineCreateFlags;
2620 false, // bool useSpecConstants;
2621 };
2622 const std::string suffix = '_' + de::toString(caseDef.width) + '_' + de::toString(caseDef.height);
2623 const std::string testName = string(stages[stageNdx].name) + '_' + geomTypes[geomTypesNdx].name + (specializedTest ? "" : suffix);
2624
2625 if (specializedTest)
2626 {
2627 DE_UNREF(generalTestsStarted);
2628 DE_ASSERT(!generalTestsStarted);
2629
2630 if (sizes[sizesNdx].id != id)
2631 continue;
2632 }
2633 else
2634 {
2635 generalTestsStarted = true;
2636 }
2637
2638 group->addChild(new RayTracingTestCase(testCtx, testName.c_str(), "", caseDef));
2639 testAdded = true;
2640
2641 if (specializedTest)
2642 break;
2643 }
2644
2645 DE_ASSERT(testAdded);
2646 DE_UNREF(testAdded);
2647 }
2648
2649 builtinGroup->addChild(group.release());
2650 }
2651
createRayFlagsTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * builtinGroup,TestId id,const char * name,const VkShaderStageFlags shaderStageFlags)2652 void createRayFlagsTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)
2653 {
2654 const deUint32 width = 16;
2655 const deUint32 height = 16;
2656 const deUint32 imageDepth = 1;
2657 const deUint32 rayDepth = 1;
2658
2659 const struct Opaques
2660 {
2661 const char* name;
2662 bool flag;
2663 }
2664 opaques[] =
2665 {
2666 { "opaque", true },
2667 { "noopaque", false },
2668 };
2669 const struct Faces
2670 {
2671 const char* name;
2672 bool flag;
2673 }
2674 faces[] =
2675 {
2676 { "frontface", true },
2677 { "backface", false },
2678 };
2679 const struct SkipRayFlags
2680 {
2681 const char* name;
2682 bool skipTriangles;
2683 bool skipAABBs;
2684 }
2685 skipRayFlags[] =
2686 {
2687 { "raynoskipflags", false, false },
2688 { "rayskiptriangles", true, false },
2689 { "rayskipaabbs", false, true },
2690 { "rayskipboth", true, true },
2691 };
2692 const struct PipelineFlags
2693 {
2694 const char* name;
2695 VkPipelineCreateFlags flag;
2696 }
2697 pipelineFlags[] =
2698 {
2699 { "pipelinenoskipflags", static_cast<VkPipelineCreateFlags>(0) },
2700 { "pipelineskiptriangles", VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR },
2701 { "pipelineskipaabbs", VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR },
2702 { "pipelineskipboth", VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR | VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR },
2703 };
2704
2705 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, de::toLower(name).c_str(), ""));
2706
2707 for (size_t geomTypesNdx = 0; geomTypesNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypesNdx)
2708 {
2709 const GeomType geomType = geomTypes[geomTypesNdx].geomType;
2710 de::MovePtr<tcu::TestCaseGroup> geomGroup (new tcu::TestCaseGroup(testCtx, geomTypes[geomTypesNdx].name, ""));
2711
2712 for (size_t skipRayFlagsNdx = 0; skipRayFlagsNdx < DE_LENGTH_OF_ARRAY(skipRayFlags); ++skipRayFlagsNdx)
2713 {
2714 de::MovePtr<tcu::TestCaseGroup> rayFlagsGroup (new tcu::TestCaseGroup(testCtx, skipRayFlags[skipRayFlagsNdx].name, ""));
2715
2716 for (size_t pipelineFlagsNdx = 0; pipelineFlagsNdx < DE_LENGTH_OF_ARRAY(pipelineFlags); ++pipelineFlagsNdx)
2717 {
2718 de::MovePtr<tcu::TestCaseGroup> pipelineFlagsGroup (new tcu::TestCaseGroup(testCtx, pipelineFlags[pipelineFlagsNdx].name, ""));
2719
2720 for (size_t opaquesNdx = 0; opaquesNdx < DE_LENGTH_OF_ARRAY(opaques); ++opaquesNdx)
2721 for (size_t facesNdx = 0; facesNdx < DE_LENGTH_OF_ARRAY(faces); ++facesNdx)
2722 {
2723 const std::string geomPropertiesGroupName = string(opaques[opaquesNdx].name) + '_' + string(faces[facesNdx].name);
2724 de::MovePtr<tcu::TestCaseGroup> geomPropertiesGroup (new tcu::TestCaseGroup(testCtx, geomPropertiesGroupName.c_str(), ""));
2725
2726 for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
2727 {
2728 if ((shaderStageFlags & stages[stageNdx].stage) == 0)
2729 continue;
2730
2731 if (stages[stageNdx].stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR && geomTypes[geomTypesNdx].geomType == GEOM_TYPE_TRIANGLES)
2732 continue;
2733
2734 const deUint32 instancesGroupCount = 1;
2735 const deUint32 geometriesGroupCount = 1;
2736 const deUint32 largestGroup = width * height / geometriesGroupCount / instancesGroupCount;
2737 const deUint32 squaresGroupCount = largestGroup;
2738 const CaseDef caseDef =
2739 {
2740 id, // TestId id;
2741 name, // const char* name;
2742 width, // deUint32 width;
2743 height, // deUint32 height;
2744 imageDepth, // deUint32 depth;
2745 rayDepth, // deUint32 raysDepth;
2746 VK_FORMAT_R32_SINT, // VkFormat format;
2747 false, // bool fixedPointScalarOutput;
2748 false, // bool fixedPointVectorOutput;
2749 false, // bool fixedPointMatrixOutput;
2750 geomType, // GeomType geomType;
2751 squaresGroupCount, // deUint32 squaresGroupCount;
2752 geometriesGroupCount, // deUint32 geometriesGroupCount;
2753 instancesGroupCount, // deUint32 instancesGroupCount;
2754 stages[stageNdx].stage, // VkShaderStageFlagBits stage;
2755 skipRayFlags[skipRayFlagsNdx].skipTriangles, // bool skipTriangles;
2756 skipRayFlags[skipRayFlagsNdx].skipAABBs, // bool skipAABSs;
2757 opaques[opaquesNdx].flag, // bool opaque;
2758 faces[facesNdx].flag, // bool frontFace;
2759 pipelineFlags[pipelineFlagsNdx].flag, // VkPipelineCreateFlags pipelineCreateFlags;
2760 false, // bool useSpecConstants;
2761 };
2762 const std::string testName = string(stages[stageNdx].name) ;
2763
2764 geomPropertiesGroup->addChild(new RayTracingTestCase(testCtx, testName.c_str(), "", caseDef));
2765 }
2766
2767 pipelineFlagsGroup->addChild(geomPropertiesGroup.release());
2768 }
2769
2770 rayFlagsGroup->addChild(pipelineFlagsGroup.release());
2771 }
2772
2773 geomGroup->addChild(rayFlagsGroup.release());
2774 }
2775
2776 group->addChild(geomGroup.release());
2777 }
2778
2779 builtinGroup->addChild(group.release());
2780 }
2781
createMultiOutputTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * builtinGroup,TestId id,const char * name,const VkShaderStageFlags shaderStageFlags)2782 void createMultiOutputTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)
2783 {
2784 const bool fixedPointVectorOutput = id == TEST_ID_WORLD_RAY_ORIGIN_EXT
2785 || id == TEST_ID_WORLD_RAY_DIRECTION_EXT
2786 || id == TEST_ID_OBJECT_RAY_ORIGIN_EXT
2787 || id == TEST_ID_OBJECT_RAY_DIRECTION_EXT;
2788 const bool fixedPointMatrixOutput = id == TEST_ID_OBJECT_TO_WORLD_EXT
2789 || id == TEST_ID_WORLD_TO_OBJECT_EXT
2790 || id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT
2791 || id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT;
2792 const deUint32 imageDepth = fixedPointMatrixOutput ? 4 * 4
2793 : fixedPointVectorOutput ? 4
2794 : 0;
2795 const deUint32 rayDepth = 1;
2796
2797 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, de::toLower(name).c_str(), ""));
2798
2799 DE_ASSERT(imageDepth != 0);
2800
2801 for (size_t geomTypesNdx = 0; geomTypesNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypesNdx)
2802 for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
2803 {
2804 const GeomType geomType = geomTypes[geomTypesNdx].geomType;
2805
2806 if ((shaderStageFlags & stages[stageNdx].stage) == 0)
2807 continue;
2808
2809 if (stages[stageNdx].stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR && geomTypes[geomTypesNdx].geomType == GEOM_TYPE_TRIANGLES)
2810 continue;
2811
2812 const deUint32 width = 4;
2813 const deUint32 height = 4;
2814 const deUint32 instancesGroupCount = 4;
2815 const deUint32 geometriesGroupCount = 1;
2816 const deUint32 largestGroup = width * height / geometriesGroupCount / instancesGroupCount;
2817 const deUint32 squaresGroupCount = largestGroup;
2818 const CaseDef caseDef =
2819 {
2820 id, // TestId id;
2821 name, // const char* name;
2822 width, // deUint32 width;
2823 height, // deUint32 height;
2824 imageDepth, // deUint32 depth;
2825 rayDepth, // deUint32 raysDepth;
2826 VK_FORMAT_R32_SINT, // VkFormat format;
2827 false, // bool fixedPointScalarOutput;
2828 fixedPointVectorOutput, // bool fixedPointVectorOutput;
2829 fixedPointMatrixOutput, // bool fixedPointMatrixOutput;
2830 geomType, // GeomType geomType;
2831 squaresGroupCount, // deUint32 squaresGroupCount;
2832 geometriesGroupCount, // deUint32 geometriesGroupCount;
2833 instancesGroupCount, // deUint32 instancesGroupCount;
2834 stages[stageNdx].stage, // VkShaderStageFlagBits stage;
2835 false, // bool rayFlagSkipTriangles;
2836 false, // bool rayFlagSkipAABSs;
2837 false, // bool opaque;
2838 false, // bool frontFace;
2839 0u, // VkPipelineCreateFlags pipelineCreateFlags;
2840 false, // bool useSpecConstants;
2841 };
2842 const std::string testName = string(stages[stageNdx].name) + '_' + geomTypes[geomTypesNdx].name;
2843
2844 group->addChild(new RayTracingTestCase(testCtx, testName.c_str(), "", caseDef));
2845 }
2846
2847 builtinGroup->addChild(group.release());
2848 }
2849 } // anonymous
2850
createBuiltinTests(tcu::TestContext & testCtx)2851 tcu::TestCaseGroup* createBuiltinTests (tcu::TestContext& testCtx)
2852 {
2853 typedef void CreateBuiltinTestsFunc (tcu::TestContext& testCtx, tcu::TestCaseGroup* group, TestId id, const char* name, const VkShaderStageFlags);
2854
2855 const VkShaderStageFlagBits R = VK_SHADER_STAGE_RAYGEN_BIT_KHR;
2856 const VkShaderStageFlagBits A = VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
2857 const VkShaderStageFlagBits C = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
2858 const VkShaderStageFlagBits M = VK_SHADER_STAGE_MISS_BIT_KHR;
2859 const VkShaderStageFlagBits I = VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
2860 const VkShaderStageFlagBits L = VK_SHADER_STAGE_CALLABLE_BIT_KHR;
2861
2862 const struct
2863 {
2864 TestId id;
2865 const char* name;
2866 VkShaderStageFlags stages;
2867 CreateBuiltinTestsFunc* createBuiltinTestsFunc;
2868 }
2869 tests[] =
2870 {
2871 { TEST_ID_LAUNCH_ID_EXT, "LaunchIDEXT" , R | A | C | I | M | L , createLaunchTests },
2872 { TEST_ID_LAUNCH_SIZE_EXT, "LaunchSizeEXT" , R | A | C | I | M | L , createLaunchTests },
2873 { TEST_ID_PRIMITIVE_ID, "PrimitiveID" , A | C | I , createScalarTests },
2874 { TEST_ID_INSTANCE_ID, "InstanceID" , A | C | I , createScalarTests },
2875 { TEST_ID_INSTANCE_CUSTOM_INDEX_EXT, "InstanceCustomIndexEXT", A | C | I , createScalarTests },
2876 { TEST_ID_GEOMETRY_INDEX_EXT, "GeometryIndexEXT" , A | C | I , createScalarTests },
2877 { TEST_ID_WORLD_RAY_ORIGIN_EXT, "WorldRayOriginEXT" , A | C | I | M , createMultiOutputTests },
2878 { TEST_ID_WORLD_RAY_DIRECTION_EXT, "WorldRayDirectionEXT" , A | C | I | M , createMultiOutputTests },
2879 { TEST_ID_OBJECT_RAY_ORIGIN_EXT, "ObjectRayOriginEXT" , A | C | I , createMultiOutputTests },
2880 { TEST_ID_OBJECT_RAY_DIRECTION_EXT, "ObjectRayDirectionEXT" , A | C | I , createMultiOutputTests },
2881 { TEST_ID_RAY_T_MIN_EXT, "RayTminEXT" , A | C | I | M , createScalarTests },
2882 { TEST_ID_RAY_T_MAX_EXT, "RayTmaxEXT" , A | C | I | M , createScalarTests },
2883 { TEST_ID_INCOMING_RAY_FLAGS_EXT, "IncomingRayFlagsEXT" , A | C | I | M , createRayFlagsTests },
2884 { TEST_ID_HIT_T_EXT, "HitTEXT" , A | C , createScalarTests },
2885 { TEST_ID_HIT_KIND_EXT, "HitKindEXT" , A | C , createScalarTests },
2886 { TEST_ID_OBJECT_TO_WORLD_EXT, "ObjectToWorldEXT" , A | C | I , createMultiOutputTests },
2887 { TEST_ID_WORLD_TO_OBJECT_EXT, "WorldToObjectEXT" , A | C | I , createMultiOutputTests },
2888 { TEST_ID_OBJECT_TO_WORLD_3X4_EXT, "ObjectToWorld3x4EXT" , A | C | I , createMultiOutputTests },
2889 { TEST_ID_WORLD_TO_OBJECT_3X4_EXT, "WorldToObject3x4EXT" , A | C | I , createMultiOutputTests },
2890 };
2891
2892 de::MovePtr<tcu::TestCaseGroup> builtinGroup(new tcu::TestCaseGroup(testCtx, "builtin", "Ray tracing shader builtin tests"));
2893
2894 for (size_t testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
2895 tests[testNdx].createBuiltinTestsFunc(testCtx, builtinGroup.get(), tests[testNdx].id, tests[testNdx].name, tests[testNdx].stages);
2896
2897 return builtinGroup.release();
2898 }
2899
createSpecConstantTests(tcu::TestContext & testCtx)2900 tcu::TestCaseGroup* createSpecConstantTests (tcu::TestContext& testCtx)
2901 {
2902 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "spec_constants", "Test using spec constants in ray tracing shader stages"));
2903
2904 const VkShaderStageFlags stageFlags = VK_SHADER_STAGE_RAYGEN_BIT_KHR
2905 | VK_SHADER_STAGE_ANY_HIT_BIT_KHR
2906 | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
2907 | VK_SHADER_STAGE_MISS_BIT_KHR
2908 | VK_SHADER_STAGE_INTERSECTION_BIT_KHR
2909 | VK_SHADER_STAGE_CALLABLE_BIT_KHR;
2910 const deUint32 width = 256u;
2911 const deUint32 height = 256u;
2912 const deUint32 depth = 1u;
2913 const bool plain = isPlain(width, height, depth);
2914 const deUint32 k = (plain ? 1 : 6);
2915 const deUint32 largestGroup = k * width * height * depth;
2916 const deUint32 squaresGroupCount = largestGroup;
2917 const deUint32 geometriesGroupCount = 1;
2918 const deUint32 instancesGroupCount = 1;
2919
2920 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
2921 {
2922 if ((stageFlags & stages[stageNdx].stage) == 0)
2923 continue;
2924
2925 const CaseDef caseDef =
2926 {
2927 TEST_ID_LAUNCH_ID_EXT, // TestId id;
2928 "LaunchIDEXT", // const char* name;
2929 width, // deUint32 width;
2930 height, // deUint32 height;
2931 depth, // deUint32 depth;
2932 depth, // deUint32 raysDepth;
2933 VK_FORMAT_R32_SINT, // VkFormat format;
2934 false, // bool fixedPointScalarOutput;
2935 false, // bool fixedPointVectorOutput;
2936 false, // bool fixedPointMatrixOutput;
2937 GEOM_TYPE_TRIANGLES, // GeomType geomType;
2938 squaresGroupCount, // deUint32 squaresGroupCount;
2939 geometriesGroupCount, // deUint32 geometriesGroupCount;
2940 instancesGroupCount, // deUint32 instancesGroupCount;
2941 stages[stageNdx].stage, // VkShaderStageFlagBits stage;
2942 false, // bool skipTriangles;
2943 false, // bool skipAABSs;
2944 false, // bool opaque;
2945 false, // bool frontFace;
2946 0u, // VkPipelineCreateFlags pipelineCreateFlags;
2947 true, // bool useSpecConstants;
2948 };
2949
2950 group->addChild(new RayTracingTestCase(testCtx, stages[stageNdx].name, "", caseDef));
2951 }
2952
2953 return group.release();
2954 }
2955
2956 } // RayTracing
2957 } // vkt
2958