• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2020 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *	  http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Ray Query Builtin tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktRayQueryBuiltinTests.hpp"
25 
26 #include "vkDefs.hpp"
27 
28 #include "vktTestCase.hpp"
29 #include "vktCustomInstancesDevices.hpp"
30 #include "vktTestGroupUtil.hpp"
31 #include "vkCmdUtil.hpp"
32 #include "vkObjUtil.hpp"
33 #include "vkBuilderUtil.hpp"
34 #include "vkBarrierUtil.hpp"
35 #include "vkBufferWithMemory.hpp"
36 #include "vkImageWithMemory.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkImageUtil.hpp"
39 #include "deRandom.hpp"
40 #include "tcuTexture.hpp"
41 #include "tcuTextureUtil.hpp"
42 #include "tcuTestLog.hpp"
43 #include "tcuImageCompare.hpp"
44 #include "tcuCommandLine.hpp"
45 
46 #include "vkRayTracingUtil.hpp"
47 
48 namespace vkt
49 {
50 	namespace RayQuery
51 	{
52 		namespace
53 		{
54 			using namespace vk;
55 			using namespace vkt;
56 
57 			static const VkFlags	ALL_RAY_TRACING_STAGES = VK_SHADER_STAGE_RAYGEN_BIT_KHR
58 				| VK_SHADER_STAGE_ANY_HIT_BIT_KHR
59 				| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
60 				| VK_SHADER_STAGE_MISS_BIT_KHR
61 				| VK_SHADER_STAGE_INTERSECTION_BIT_KHR
62 				| VK_SHADER_STAGE_CALLABLE_BIT_KHR;
63 
64 			enum TestType
65 			{
66 				TEST_TYPE_FLOW = 0,
67 				TEST_TYPE_PRIMITIVE_ID,
68 				TEST_TYPE_INSTANCE_ID,
69 				TEST_TYPE_INSTANCE_CUSTOM_INDEX,
70 				TEST_TYPE_INTERSECTION_T_KHR,
71 				TEST_TYPE_OBJECT_RAY_ORIGIN_KHR,
72 				TEST_TYPE_OBJECT_RAY_DIRECTION_KHR,
73 				TEST_TYPE_OBJECT_TO_WORLD_KHR,
74 				TEST_TYPE_WORLD_TO_OBJECT_KHR,
75 				TEST_TYPE_NULL_ACCELERATION_STRUCTURE,
76 				TEST_TYPE_USING_WRAPPER_FUNCTION,
77 				TEST_TYPE_GET_RAY_TMIN,
78 				TEST_TYPE_GET_WORLD_RAY_ORIGIN,
79 				TEST_TYPE_GET_WORLD_RAY_DIRECTION,
80 				TEST_TYPE_GET_INTERSECTION_CANDIDATE_AABB_OPAQUE,
81 				TEST_TYPE_GET_INTERSECTION_FRONT_FACE_CANDIDATE,
82 				TEST_TYPE_GET_INTERSECTION_FRONT_FACE_COMMITTED,
83 				TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_CANDIDATE,
84 				TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_COMMITTED,
85 				TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_CANDIDATE,
86 				TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_COMMITTED,
87 				TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_CANDIDATE,
88 				TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_COMMITTED,
89 				TEST_TYPE_RAY_QUERY_TERMINATE,
90 				TEST_TYPE_GET_INTERSECTION_TYPE_CANDIDATE,
91 				TEST_TYPE_GET_INTERSECTION_TYPE_COMMITTED,
92 
93 				TEST_TYPE_LAST
94 			};
95 
96 			enum GeomType
97 			{
98 				GEOM_TYPE_TRIANGLES,
99 				GEOM_TYPE_AABBS,
100 				GEOM_TYPE_LAST,
101 			};
102 
103 			const deUint32	TEST_WIDTH = 8;
104 			const deUint32	TEST_HEIGHT = 8;
105 			const deUint32	FIXED_POINT_DIVISOR = 1024 * 1024;
106 			const deUint32	FIXED_POINT_ALLOWED_ERROR = static_cast<deUint32>(float(1e-3f) * FIXED_POINT_DIVISOR);
107 
108 			struct TestParams;
109 
110 			// Similar to a subset of the test context but allows us to plug in a custom device when needed.
111 			// Note TestEnvironment objects do not own the resources they point to.
112 			struct TestEnvironment
113 			{
114 				const InstanceInterface*	vki;
115 				VkPhysicalDevice			physicalDevice;
116 				const DeviceInterface*		vkd;
117 				VkDevice					device;
118 				Allocator*					allocator;
119 				VkQueue						queue;
120 				deUint32					queueFamilyIndex;
121 				BinaryCollection*			binaryCollection;
122 				tcu::TestLog*				log;
123 			};
124 
125 			typedef void (*CheckSupportFunc)(Context& context, const TestParams& testParams);
126 			typedef void (*InitProgramsFunc)(SourceCollections& programCollection, const TestParams& testParams);
127 			typedef const std::string(*ShaderBodyTextFunc)(const TestParams& testParams);
128 
129 			class PipelineConfiguration
130 			{
131 			public:
PipelineConfiguration()132 				PipelineConfiguration() {}
~PipelineConfiguration()133 				virtual			~PipelineConfiguration() {}
134 
135 				virtual void	initConfiguration(const TestEnvironment& env,
136 					TestParams& testParams) = 0;
137 				virtual void	fillCommandBuffer(const TestEnvironment& env,
138 					TestParams& testParams,
139 					VkCommandBuffer					commandBuffer,
140 					const VkAccelerationStructureKHR* rayQueryTopAccelerationStructurePtr,
141 					const VkDescriptorImageInfo& resultImageInfo) = 0;
142 			};
143 
144 			class TestConfiguration
145 			{
146 			public:
TestConfiguration(Context & context)147 				TestConfiguration(Context& context)
148 					: m_bottomAccelerationStructures()
149 					, m_topAccelerationStructure()
150 					, m_expected()
151 					, m_testEnvironment()
152 				{
153 					prepareTestEnvironment(context);
154 				}
~TestConfiguration()155 				virtual															~TestConfiguration()
156 				{
157 				}
158 
159 				const TestEnvironment&						getTestEnvironment			() const;
160 				virtual const VkAccelerationStructureKHR*	initAccelerationStructures	(TestParams& testParams, VkCommandBuffer cmdBuffer) = 0;
161 				virtual bool								verify						(BufferWithMemory* resultBuffer, TestParams& testParams);
162 
163 			protected:
164 				void										prepareTestEnvironment		(Context& context);
165 
166 				std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	m_bottomAccelerationStructures;
167 				de::SharedPtr<TopLevelAccelerationStructure>					m_topAccelerationStructure;
168 				std::vector<deInt32>											m_expected;
169 				de::MovePtr<TestEnvironment>									m_testEnvironment;
170 			};
171 
172 			class TestConfigurationFloat : public TestConfiguration
173 			{
174 			public:
TestConfigurationFloat(Context & context)175 				TestConfigurationFloat(Context& context)
176 					: TestConfiguration(context)
177 				{
178 				}
~TestConfigurationFloat()179 				virtual															~TestConfigurationFloat()
180 				{
181 				}
182 				virtual bool													verify(BufferWithMemory* resultBuffer,
183 					TestParams& testParams) override;
184 			};
185 
186 			class TestConfigurationVector : public TestConfiguration
187 			{
188 			public:
TestConfigurationVector(Context & context,bool useStrictComponentMatching=true)189 				TestConfigurationVector(Context& context, bool useStrictComponentMatching = true)
190 					: TestConfiguration(context),
191 					m_useStrictComponentMatching(useStrictComponentMatching)
192 				{
193 				}
~TestConfigurationVector()194 				virtual															~TestConfigurationVector()
195 				{
196 				}
197 				virtual bool													verify(BufferWithMemory* resultBuffer,
198 					TestParams& testParams) override;
199 
200 			private:
201 				bool m_useStrictComponentMatching;
202 			};
203 
204 			class TestConfigurationMatrix : public TestConfiguration
205 			{
206 			public:
TestConfigurationMatrix(Context & context)207 				TestConfigurationMatrix(Context& context)
208 					: TestConfiguration(context)
209 				{
210 				}
~TestConfigurationMatrix()211 				virtual															~TestConfigurationMatrix()
212 				{
213 				}
214 				virtual bool													verify(BufferWithMemory* resultBuffer,
215 					TestParams& testParams) override;
216 			};
217 
218 			struct TestParams
219 			{
220 				deUint32				width;
221 				deUint32				height;
222 				deUint32				depth;
223 				TestType				testType;
224 				VkShaderStageFlagBits	stage;
225 				GeomType				geomType;
226 				deUint32				squaresGroupCount;
227 				deUint32				geometriesGroupCount;
228 				deUint32				instancesGroupCount;
229 				VkFormat				format;
230 				CheckSupportFunc		pipelineCheckSupport;
231 				InitProgramsFunc		pipelineInitPrograms;
232 				ShaderBodyTextFunc		testConfigShaderBodyText;
233 				bool					isSPIRV;						// determines if shader body is defined in SPIR-V
234 				CheckSupportFunc		testConfigCheckSupport;
235 			};
236 
getShaderGroupHandleSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)237 			deUint32 getShaderGroupHandleSize(const InstanceInterface& vki,
238 				const VkPhysicalDevice	physicalDevice)
239 			{
240 				de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
241 
242 				rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
243 
244 				return rayTracingPropertiesKHR->getShaderGroupHandleSize();
245 			}
246 
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)247 			deUint32 getShaderGroupBaseAlignment(const InstanceInterface& vki,
248 				const VkPhysicalDevice	physicalDevice)
249 			{
250 				de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
251 
252 				rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
253 
254 				return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
255 			}
256 
makeImageCreateInfo(VkFormat format,deUint32 width,deUint32 height,deUint32 depth,VkImageType imageType=VK_IMAGE_TYPE_3D,VkImageUsageFlags usageFlags=VK_IMAGE_USAGE_STORAGE_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT)257 			VkImageCreateInfo makeImageCreateInfo(VkFormat				format,
258 				deUint32				width,
259 				deUint32				height,
260 				deUint32				depth,
261 				VkImageType			imageType = VK_IMAGE_TYPE_3D,
262 				VkImageUsageFlags	usageFlags = VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
263 			{
264 				const VkImageCreateInfo	imageCreateInfo =
265 				{
266 					VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType;
267 					DE_NULL,								// const void*				pNext;
268 					(VkImageCreateFlags)0u,					// VkImageCreateFlags		flags;
269 					imageType,								// VkImageType				imageType;
270 					format,									// VkFormat					format;
271 					makeExtent3D(width, height, depth),		// VkExtent3D				extent;
272 					1u,										// deUint32					mipLevels;
273 					1u,										// deUint32					arrayLayers;
274 					VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples;
275 					VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling;
276 					usageFlags,								// VkImageUsageFlags		usage;
277 					VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode;
278 					0u,										// deUint32					queueFamilyIndexCount;
279 					DE_NULL,								// const deUint32*			pQueueFamilyIndices;
280 					VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout;
281 				};
282 
283 				return imageCreateInfo;
284 			}
285 
getMissPassthrough(void)286 			static const std::string getMissPassthrough(void)
287 			{
288 				const std::string missPassthrough =
289 					"#version 460 core\n"
290 					"#extension GL_EXT_ray_tracing : require\n"
291 					"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
292 					"\n"
293 					"void main()\n"
294 					"{\n"
295 					"}\n";
296 
297 				return missPassthrough;
298 			}
299 
getHitPassthrough(void)300 			static const std::string getHitPassthrough(void)
301 			{
302 				const std::string hitPassthrough =
303 					"#version 460 core\n"
304 					"#extension GL_EXT_ray_tracing : require\n"
305 					"hitAttributeEXT vec3 attribs;\n"
306 					"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
307 					"\n"
308 					"void main()\n"
309 					"{\n"
310 					"}\n";
311 
312 				return hitPassthrough;
313 			}
314 
getGraphicsPassthrough(void)315 			static const std::string getGraphicsPassthrough(void)
316 			{
317 				std::ostringstream src;
318 
319 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
320 					<< "\n"
321 					<< "void main(void)\n"
322 					<< "{\n"
323 					<< "}\n";
324 
325 				return src.str();
326 			}
327 
getVertexPassthrough(void)328 			static const std::string getVertexPassthrough(void)
329 			{
330 				std::ostringstream src;
331 
332 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
333 					<< "\n"
334 					<< "layout(location = 0) in vec4 in_position;\n"
335 					<< "\n"
336 					<< "void main(void)\n"
337 					<< "{\n"
338 					<< "  gl_Position = in_position;\n"
339 					<< "}\n";
340 
341 				return src.str();
342 			}
343 
getGeomName(bool writePointSize)344 			static const std::string getGeomName (bool writePointSize)
345 			{
346 				std::ostringstream str;
347 				str << "geom" << (writePointSize ? "_point_size" : "");
348 				return str.str();
349 			}
350 
351 			class GraphicsConfiguration : public PipelineConfiguration
352 			{
353 			public:
354 				static void						checkSupport(Context& context,
355 					const TestParams& testParams);
356 				static void						initPrograms(SourceCollections& programCollection,
357 					const TestParams& testParams);
358 
359 				GraphicsConfiguration();
~GraphicsConfiguration()360 				virtual							~GraphicsConfiguration() {}
361 
362 				void							initVertexBuffer(const TestEnvironment& env,
363 					TestParams& testParams);
364 				Move<VkPipeline>				makeGraphicsPipeline(const TestEnvironment& env,
365 					TestParams& testParams);
366 				virtual void					initConfiguration(const TestEnvironment& env,
367 					TestParams& testParams) override;
368 				virtual void					fillCommandBuffer(const TestEnvironment& env,
369 					TestParams& testParams,
370 					VkCommandBuffer					commandBuffer,
371 					const VkAccelerationStructureKHR* rayQueryTopAccelerationStructurePtr,
372 					const VkDescriptorImageInfo& resultImageInfo) override;
373 
374 			private:
375 				Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
376 				Move<VkDescriptorPool>			m_descriptorPool;
377 				Move<VkDescriptorSet>			m_descriptorSet;
378 
379 				VkFormat						m_framebufferFormat;
380 				Move<VkImage>					m_framebufferImage;
381 				de::MovePtr<Allocation>			m_framebufferImageAlloc;
382 				Move<VkImageView>				m_framebufferAttachment;
383 
384 				Move<VkShaderModule>			m_vertShaderModule;
385 				Move<VkShaderModule>			m_geomShaderModule;
386 				Move<VkShaderModule>			m_tescShaderModule;
387 				Move<VkShaderModule>			m_teseShaderModule;
388 				Move<VkShaderModule>			m_fragShaderModule;
389 
390 				Move<VkRenderPass>				m_renderPass;
391 				Move<VkFramebuffer>				m_framebuffer;
392 				Move<VkPipelineLayout>			m_pipelineLayout;
393 				Move<VkPipeline>				m_pipeline;
394 
395 				deUint32						m_vertexCount;
396 				Move<VkBuffer>					m_vertexBuffer;
397 				de::MovePtr<Allocation>			m_vertexBufferAlloc;
398 			};
399 
GraphicsConfiguration()400 			GraphicsConfiguration::GraphicsConfiguration()
401 				: PipelineConfiguration()
402 				, m_descriptorSetLayout()
403 				, m_descriptorPool()
404 				, m_descriptorSet()
405 				, m_framebufferFormat(VK_FORMAT_R8G8B8A8_UNORM)
406 				, m_framebufferImage()
407 				, m_framebufferImageAlloc()
408 				, m_framebufferAttachment()
409 				, m_vertShaderModule()
410 				, m_geomShaderModule()
411 				, m_tescShaderModule()
412 				, m_teseShaderModule()
413 				, m_fragShaderModule()
414 				, m_renderPass()
415 				, m_framebuffer()
416 				, m_pipelineLayout()
417 				, m_pipeline()
418 				, m_vertexCount(0)
419 				, m_vertexBuffer()
420 				, m_vertexBufferAlloc()
421 			{
422 			}
423 
checkSupport(Context & context,const TestParams & testParams)424 			void GraphicsConfiguration::checkSupport(Context& context,
425 				const TestParams& testParams)
426 			{
427 				switch (testParams.stage)
428 				{
429 				case VK_SHADER_STAGE_VERTEX_BIT:
430 				case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
431 				case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
432 				case VK_SHADER_STAGE_GEOMETRY_BIT:
433 					context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
434 					break;
435 				default:
436 					break;
437 				}
438 
439 				switch (testParams.stage)
440 				{
441 				case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
442 				case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
443 					context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
444 					break;
445 				case VK_SHADER_STAGE_GEOMETRY_BIT:
446 					context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
447 					break;
448 				default:
449 					break;
450 				}
451 			}
452 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)453 			void GraphicsConfiguration::initPrograms(SourceCollections& programCollection,
454 				const TestParams& testParams)
455 			{
456 				const vk::ShaderBuildOptions	buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
457 
458 				const std::string				testShaderBody = testParams.testConfigShaderBodyText(testParams);
459 
460 				switch (testParams.stage)
461 				{
462 				case VK_SHADER_STAGE_VERTEX_BIT:
463 				{
464 					{
465 						std::ostringstream src;
466 						src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
467 							<< "#extension GL_EXT_ray_query : require\n"
468 							<< "#extension GL_EXT_ray_tracing : require\n"
469 							<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
470 							<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
471 							<< "\n"
472 							<< "void testFunc(ivec3 pos, ivec3 size)\n"
473 							<< "{\n"
474 							<< testShaderBody
475 							<< "}\n"
476 							<< "\n"
477 							<< "void main(void)\n"
478 							<< "{\n"
479 							<< "  const int   posId    = int(gl_VertexIndex / 3);\n"
480 							<< "  const int   vertId   = int(gl_VertexIndex % 3);\n"
481 							<< "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
482 							<< "  const ivec3 pos      = ivec3(posId % size.x, posId / size.x, 0);\n"
483 							<< "\n"
484 							<< "  if (vertId == 0)\n"
485 							<< "  {\n"
486 							<< "    testFunc(pos, size);\n"
487 							<< "  }\n"
488 							<< "}\n";
489 
490 						programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
491 					}
492 
493 					programCollection.glslSources.add("frag") << glu::FragmentSource(getGraphicsPassthrough()) << buildOptions;
494 
495 					break;
496 				}
497 
498 				case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
499 				{
500 					{
501 						std::ostringstream src;
502 						src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
503 							<< "\n"
504 							<< "layout(location = 0) in vec4 in_position;\n"
505 							<< "out gl_PerVertex\n"
506 							<< "{\n"
507 							<< "  vec4 gl_Position;\n"
508 							<< "};\n"
509 							<< "\n"
510 							<< "void main(void)\n"
511 							<< "{\n"
512 							<< "  gl_Position = in_position;\n"
513 							<< "}\n";
514 
515 						programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
516 					}
517 
518 					{
519 						std::ostringstream src;
520 						src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
521 							<< "#extension GL_EXT_tessellation_shader : require\n"
522 							<< "#extension GL_EXT_ray_query : require\n"
523 							<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
524 							<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
525 							<< "in gl_PerVertex\n"
526 							<< "{\n"
527 							<< "  vec4 gl_Position;\n"
528 							<< "} gl_in[];\n"
529 							<< "layout(vertices = 4) out;\n"
530 							<< "out gl_PerVertex\n"
531 							<< "{\n"
532 							<< "  vec4 gl_Position;\n"
533 							<< "} gl_out[];\n"
534 							<< "\n"
535 							<< "void testFunc(ivec3 pos, ivec3 size)\n"
536 							<< "{\n"
537 							<< testShaderBody
538 							<< "}\n"
539 							<< "\n"
540 							<< "void main(void)\n"
541 							<< "{\n"
542 							<< "\n"
543 							<< "  if (gl_InvocationID == 0)\n"
544 							<< "  {\n"
545 							<< "    const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
546 							<< "    for (int y = 0; y < size.y; y++)\n"
547 							<< "    for (int x = 0; x < size.x; x++)\n"
548 							<< "    {\n"
549 							<< "      const ivec3 pos = ivec3(x, y, 0);\n"
550 							<< "      testFunc(pos, size);\n"
551 							<< "    }\n"
552 							<< "  }\n"
553 							<< "\n"
554 							<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
555 							<< "  gl_TessLevelInner[0] = 1;\n"
556 							<< "  gl_TessLevelInner[1] = 1;\n"
557 							<< "  gl_TessLevelOuter[gl_InvocationID] = 1;\n"
558 							<< "}\n";
559 
560 						programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions;
561 					}
562 
563 					{
564 						std::ostringstream src;
565 						src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
566 							<< "#extension GL_EXT_tessellation_shader : require\n"
567 							<< "layout(quads, equal_spacing, ccw) in;\n"
568 							<< "in gl_PerVertex\n"
569 							<< "{\n"
570 							<< "  vec4 gl_Position;\n"
571 							<< "} gl_in[];\n"
572 							<< "\n"
573 							<< "void main(void)\n"
574 							<< "{\n"
575 							<< "  gl_Position = gl_in[0].gl_Position;\n"
576 							<< "}\n";
577 
578 						programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions;
579 					}
580 
581 					break;
582 				}
583 
584 				case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
585 				{
586 					{
587 						std::ostringstream src;
588 						src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
589 							<< "\n"
590 							<< "layout(location = 0) in vec4 in_position;\n"
591 							<< "out gl_PerVertex"
592 							<< "{\n"
593 							<< "  vec4 gl_Position;\n"
594 							<< "};\n"
595 							<< "\n"
596 							<< "void main(void)\n"
597 							<< "{\n"
598 							<< "  gl_Position = in_position;\n"
599 							<< "}\n";
600 
601 						programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
602 					}
603 
604 					{
605 						std::ostringstream src;
606 						src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
607 							<< "#extension GL_EXT_tessellation_shader : require\n"
608 							<< "in gl_PerVertex\n"
609 							<< "{\n"
610 							<< "  vec4 gl_Position;\n"
611 							<< "} gl_in[];\n"
612 							<< "layout(vertices = 4) out;\n"
613 							<< "out gl_PerVertex\n"
614 							<< "{\n"
615 							<< "  vec4 gl_Position;\n"
616 							<< "} gl_out[];\n"
617 							<< "\n"
618 							<< "void main(void)\n"
619 							<< "{\n"
620 							<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
621 							<< "  gl_TessLevelInner[0] = 1;\n"
622 							<< "  gl_TessLevelInner[1] = 1;\n"
623 							<< "  gl_TessLevelOuter[gl_InvocationID] = 1;\n"
624 							<< "}\n";
625 
626 						programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions;
627 					}
628 
629 					{
630 						std::ostringstream src;
631 						src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
632 							<< "#extension GL_EXT_tessellation_shader : require\n"
633 							<< "#extension GL_EXT_ray_query : require\n"
634 							<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
635 							<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
636 							<< "layout(quads, equal_spacing, ccw) in;\n"
637 							<< "in gl_PerVertex\n"
638 							<< "{\n"
639 							<< "  vec4 gl_Position;\n"
640 							<< "} gl_in[];\n"
641 							<< "\n"
642 							<< "void testFunc(ivec3 pos, ivec3 size)\n"
643 							<< "{\n"
644 							<< testShaderBody
645 							<< "}\n"
646 							<< "\n"
647 							<< "void main(void)\n"
648 							<< "{\n"
649 							<< "  const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
650 							<< "\n"
651 							<< "  if (gl_PrimitiveID == 0)\n"
652 							<< "  {\n"
653 							<< "    const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
654 							<< "    for (int y = 0; y < size.y; y++)\n"
655 							<< "    for (int x = 0; x < size.x; x++)\n"
656 							<< "    {\n"
657 							<< "      const ivec3 pos = ivec3(x, y, 0);\n"
658 							<< "      testFunc(pos, size);\n"
659 							<< "    }\n"
660 							<< "  }\n"
661 							<< "\n"
662 							<< "  gl_Position = gl_in[0].gl_Position;\n"
663 							<< "}\n";
664 
665 						programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions;
666 					}
667 
668 					break;
669 				}
670 
671 				case VK_SHADER_STAGE_GEOMETRY_BIT:
672 				{
673 					programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions;
674 
675 					for (deUint32 i = 0; i < 2; ++i)
676 					{
677 						const bool writePointSize = i == 1;
678 						std::string pointSize = writePointSize ? "    gl_PointSize = 1.0f;\n" : "";
679 
680 						std::ostringstream src;
681 						src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
682 							<< "#extension GL_EXT_ray_query : require\n"
683 							<< "layout(triangles) in;\n"
684 							<< "layout(points, max_vertices = 1) out;\n"
685 							<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
686 							<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
687 							<< "\n"
688 							<< "void testFunc(ivec3 pos, ivec3 size)\n"
689 							<< "{\n"
690 							<< testShaderBody
691 							<< "}\n"
692 							<< "\n"
693 							<< "void main(void)\n"
694 							<< "{\n"
695 							<< "  const int   posId    = int(gl_PrimitiveIDIn);\n"
696 							<< "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
697 							<< "  const ivec3 pos      = ivec3(posId % size.x, posId / size.x, 0);\n"
698 							<< "\n"
699 							<< "  testFunc(pos, size);\n"
700 							<< pointSize
701 							<< "}\n";
702 
703 						programCollection.glslSources.add(getGeomName(writePointSize)) << glu::GeometrySource(src.str()) << buildOptions;
704 					}
705 
706 					break;
707 				}
708 
709 				case VK_SHADER_STAGE_FRAGMENT_BIT:
710 				{
711 					programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions;
712 
713 					{
714 						std::ostringstream src;
715 						src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
716 							<< "#extension GL_EXT_ray_query : require\n"
717 							<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
718 							<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
719 							<< "\n"
720 							<< "void testFunc(ivec3 pos, ivec3 size)\n"
721 							<< "{\n"
722 							<< testShaderBody
723 							<< "}\n"
724 							<< "\n"
725 							<< "void main(void)\n"
726 							<< "{\n"
727 							<< "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
728 							<< "  const ivec3 pos      = ivec3(int(gl_FragCoord.x - 0.5f), int(gl_FragCoord.y - 0.5f), 0);\n"
729 							<< "\n"
730 							<< "  testFunc(pos, size);\n"
731 							<< "}\n";
732 
733 						programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()) << buildOptions;
734 					}
735 
736 					break;
737 				}
738 
739 				default:
740 					TCU_THROW(InternalError, "Unknown stage");
741 				}
742 			}
743 
initVertexBuffer(const TestEnvironment & env,TestParams & testParams)744 			void GraphicsConfiguration::initVertexBuffer(const TestEnvironment& env,
745 				TestParams& testParams)
746 			{
747 				const DeviceInterface&	vkd = *env.vkd;
748 				const VkDevice			device = env.device;
749 				Allocator&				allocator = *env.allocator;
750 				const deUint32			width = testParams.width;
751 				const deUint32			height = testParams.height;
752 				std::vector<tcu::Vec4>	vertices;
753 
754 				switch (testParams.stage)
755 				{
756 				case VK_SHADER_STAGE_VERTEX_BIT:
757 				{
758 					const float z = 0.0f;
759 					const float w = 1.0f;
760 
761 					vertices.reserve(3 * height * width);
762 
763 					for (deUint32 y = 0; y < height; ++y)
764 						for (deUint32 x = 0; x < width; ++x)
765 						{
766 							const float	x0 = float(x + 0) / float(width);
767 							const float	y0 = float(y + 0) / float(height);
768 							const float	x1 = float(x + 1) / float(width);
769 							const float	y1 = float(y + 1) / float(height);
770 							const float	xm = (x0 + x1) / 2.0f;
771 							const float	ym = (y0 + y1) / 2.0f;
772 
773 							vertices.push_back(tcu::Vec4(x0, y0, z, w));
774 							vertices.push_back(tcu::Vec4(xm, y1, z, w));
775 							vertices.push_back(tcu::Vec4(x1, ym, z, w));
776 						}
777 
778 					break;
779 				}
780 
781 				case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
782 				{
783 					const float		z = 0.0f;
784 					const float		w = 1.0f;
785 					const tcu::Vec4	a = tcu::Vec4(-1.0f, -1.0f, z, w);
786 					const tcu::Vec4	b = tcu::Vec4(+1.0f, -1.0f, z, w);
787 					const tcu::Vec4	c = tcu::Vec4(+1.0f, +1.0f, z, w);
788 					const tcu::Vec4	d = tcu::Vec4(-1.0f, +1.0f, z, w);
789 
790 					vertices.push_back(a);
791 					vertices.push_back(b);
792 					vertices.push_back(c);
793 					vertices.push_back(d);
794 
795 					break;
796 				}
797 
798 				case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
799 				{
800 					const float		z = 0.0f;
801 					const float		w = 1.0f;
802 					const tcu::Vec4	a = tcu::Vec4(-1.0f, -1.0f, z, w);
803 					const tcu::Vec4	b = tcu::Vec4(+1.0f, -1.0f, z, w);
804 					const tcu::Vec4	c = tcu::Vec4(+1.0f, +1.0f, z, w);
805 					const tcu::Vec4	d = tcu::Vec4(-1.0f, +1.0f, z, w);
806 
807 					vertices.push_back(a);
808 					vertices.push_back(b);
809 					vertices.push_back(c);
810 					vertices.push_back(d);
811 
812 					break;
813 				}
814 
815 				case VK_SHADER_STAGE_GEOMETRY_BIT:
816 				{
817 					const float z = 0.0f;
818 					const float w = 1.0f;
819 
820 					vertices.reserve(3 * height * width);
821 
822 					for (deUint32 y = 0; y < height; ++y)
823 						for (deUint32 x = 0; x < width; ++x)
824 						{
825 							const float	x0 = float(x + 0) / float(width);
826 							const float	y0 = float(y + 0) / float(height);
827 							const float	x1 = float(x + 1) / float(width);
828 							const float	y1 = float(y + 1) / float(height);
829 							const float	xm = (x0 + x1) / 2.0f;
830 							const float	ym = (y0 + y1) / 2.0f;
831 
832 							vertices.push_back(tcu::Vec4(x0, y0, z, w));
833 							vertices.push_back(tcu::Vec4(xm, y1, z, w));
834 							vertices.push_back(tcu::Vec4(x1, ym, z, w));
835 						}
836 
837 					break;
838 				}
839 
840 				case VK_SHADER_STAGE_FRAGMENT_BIT:
841 				{
842 					const float		z = 1.0f;
843 					const float		w = 1.0f;
844 					const tcu::Vec4	a = tcu::Vec4(-1.0f, -1.0f, z, w);
845 					const tcu::Vec4	b = tcu::Vec4(+1.0f, -1.0f, z, w);
846 					const tcu::Vec4	c = tcu::Vec4(-1.0f, +1.0f, z, w);
847 					const tcu::Vec4	d = tcu::Vec4(+1.0f, +1.0f, z, w);
848 
849 					vertices.push_back(a);
850 					vertices.push_back(b);
851 					vertices.push_back(c);
852 
853 					vertices.push_back(b);
854 					vertices.push_back(c);
855 					vertices.push_back(d);
856 
857 					break;
858 				}
859 
860 				default:
861 					TCU_THROW(InternalError, "Unknown stage");
862 
863 				}
864 
865 				// Initialize vertex buffer
866 				{
867 					const VkDeviceSize			vertexBufferSize = sizeof(vertices[0][0]) * vertices[0].SIZE * vertices.size();
868 					const VkBufferCreateInfo	vertexBufferCreateInfo = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
869 
870 					m_vertexCount = static_cast<deUint32>(vertices.size());
871 					m_vertexBuffer = createBuffer(vkd, device, &vertexBufferCreateInfo);
872 					m_vertexBufferAlloc = bindBuffer(vkd, device, allocator, *m_vertexBuffer, vk::MemoryRequirement::HostVisible);
873 
874 					deMemcpy(m_vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexBufferSize);
875 					flushAlloc(vkd, device, *m_vertexBufferAlloc);
876 				}
877 			}
878 
makeGraphicsPipeline(const TestEnvironment & env,TestParams & testParams)879 			Move<VkPipeline> GraphicsConfiguration::makeGraphicsPipeline(const TestEnvironment& env,
880 				TestParams& testParams)
881 			{
882 				const DeviceInterface&			vkd = *env.vkd;
883 				const VkDevice					device = env.device;
884 				const bool						tessStageTest = (testParams.stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || testParams.stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
885 				const VkPrimitiveTopology		topology = tessStageTest ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
886 				const deUint32					patchControlPoints = tessStageTest ? 4 : 0;
887 				const std::vector<VkViewport>	viewports(1, makeViewport(testParams.width, testParams.height));
888 				const std::vector<VkRect2D>		scissors(1, makeRect2D(testParams.width, testParams.height));
889 
890 				return vk::makeGraphicsPipeline(vkd,
891 					device,
892 					*m_pipelineLayout,
893 					*m_vertShaderModule,
894 					*m_tescShaderModule,
895 					*m_teseShaderModule,
896 					*m_geomShaderModule,
897 					*m_fragShaderModule,
898 					*m_renderPass,
899 					viewports,
900 					scissors,
901 					topology,
902 					0,
903 					patchControlPoints);
904 			}
905 
initConfiguration(const TestEnvironment & env,TestParams & testParams)906 			void GraphicsConfiguration::initConfiguration(const TestEnvironment& env,
907 				TestParams& testParams)
908 			{
909 				const InstanceInterface&	vki = *env.vki;
910 				const DeviceInterface&		vkd = *env.vkd;
911 				const VkPhysicalDevice		physicalDevice = env.physicalDevice;
912 				const VkDevice				device = env.device;
913 				Allocator&					allocator = *env.allocator;
914 				vk::BinaryCollection&		collection = *env.binaryCollection;
915 				VkShaderStageFlags			shaders = static_cast<VkShaderStageFlags>(0);
916 				deUint32					shaderCount = 0;
917 
918 				VkPhysicalDeviceFeatures features;
919 				vki.getPhysicalDeviceFeatures(physicalDevice, &features);
920 				const bool					pointSizeRequired = features.shaderTessellationAndGeometryPointSize;
921 
922 				if (collection.contains("vert")) shaders |= VK_SHADER_STAGE_VERTEX_BIT;
923 				if (collection.contains(getGeomName(pointSizeRequired))) shaders |= VK_SHADER_STAGE_GEOMETRY_BIT;
924 				if (collection.contains("tesc")) shaders |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
925 				if (collection.contains("tese")) shaders |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
926 				if (collection.contains("frag")) shaders |= VK_SHADER_STAGE_FRAGMENT_BIT;
927 
928 				for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
929 					shaderCount++;
930 
931 				if (collection.contains(getGeomName(!pointSizeRequired))) --shaderCount;
932 
933 				if (shaderCount != (deUint32)dePop32(shaders))
934 					TCU_THROW(InternalError, "Unused shaders detected in the collection");
935 
936 				if (0 != (shaders & VK_SHADER_STAGE_VERTEX_BIT))					m_vertShaderModule = createShaderModule(vkd, device, collection.get("vert"), 0);
937 				if (0 != (shaders & VK_SHADER_STAGE_GEOMETRY_BIT))					m_geomShaderModule = createShaderModule(vkd, device, collection.get(getGeomName(pointSizeRequired)), 0);
938 				if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT))		m_tescShaderModule = createShaderModule(vkd, device, collection.get("tesc"), 0);
939 				if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))	m_teseShaderModule = createShaderModule(vkd, device, collection.get("tese"), 0);
940 				if (0 != (shaders & VK_SHADER_STAGE_FRAGMENT_BIT))					m_fragShaderModule = createShaderModule(vkd, device, collection.get("frag"), 0);
941 
942 				m_descriptorSetLayout = DescriptorSetLayoutBuilder()
943 					.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL_GRAPHICS)
944 					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL_GRAPHICS)
945 					.build(vkd, device);
946 				m_descriptorPool = DescriptorPoolBuilder()
947 					.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
948 					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
949 					.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
950 				m_descriptorSet = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
951 				m_framebufferImage = makeImage(vkd, device, makeImageCreateInfo(m_framebufferFormat, testParams.width, testParams.height, 1u, VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
952 				m_framebufferImageAlloc = bindImage(vkd, device, allocator, *m_framebufferImage, MemoryRequirement::Any);
953 				m_framebufferAttachment = makeImageView(vkd, device, *m_framebufferImage, VK_IMAGE_VIEW_TYPE_2D, m_framebufferFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
954 				m_renderPass = makeRenderPass(vkd, device, m_framebufferFormat);
955 				m_framebuffer = makeFramebuffer(vkd, device, *m_renderPass, *m_framebufferAttachment, testParams.width, testParams.height);
956 				m_pipelineLayout = makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
957 				m_pipeline = makeGraphicsPipeline(env, testParams);
958 
959 				initVertexBuffer(env, testParams);
960 			}
961 
fillCommandBuffer(const TestEnvironment & env,TestParams & testParams,VkCommandBuffer cmdBuffer,const VkAccelerationStructureKHR * rayQueryTopAccelerationStructurePtr,const VkDescriptorImageInfo & resultImageInfo)962 			void GraphicsConfiguration::fillCommandBuffer(const TestEnvironment& env,
963 				TestParams& testParams,
964 				VkCommandBuffer						cmdBuffer,
965 				const VkAccelerationStructureKHR* rayQueryTopAccelerationStructurePtr,
966 				const VkDescriptorImageInfo& resultImageInfo)
967 			{
968 				const DeviceInterface&								vkd												= *env.vkd;
969 				const VkDevice										device											= env.device;
970 				const VkDeviceSize									vertexBufferOffset								= 0;
971 				const VkWriteDescriptorSetAccelerationStructureKHR	rayQueryAccelerationStructureWriteDescriptorSet	=
972 				{
973 					VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
974 					DE_NULL,															//  const void*							pNext;
975 					1u,																	//  deUint32							accelerationStructureCount;
976 					rayQueryTopAccelerationStructurePtr,								//  const VkAccelerationStructureKHR*	pAccelerationStructures;
977 				};
978 
979 				DescriptorSetUpdateBuilder()
980 					.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
981 					.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
982 					.update(vkd, device);
983 
984 				vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
985 				vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
986 				vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
987 
988 				beginRenderPass(vkd, cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, testParams.width, testParams.height), tcu::UVec4());
989 
990 				vkd.cmdDraw(cmdBuffer, m_vertexCount, 1u, 0u, 0u);
991 
992 				endRenderPass(vkd, cmdBuffer);
993 			}
994 
995 			class ComputeConfiguration : public PipelineConfiguration
996 			{
997 			public:
998 				ComputeConfiguration();
~ComputeConfiguration()999 				virtual						~ComputeConfiguration() {}
1000 
1001 				static void					checkSupport(Context& context,
1002 					const TestParams& testParams);
1003 				static void					initPrograms(SourceCollections& programCollection,
1004 					const TestParams& testParams);
1005 
1006 				virtual void				initConfiguration(const TestEnvironment& env,
1007 					TestParams& testParams) override;
1008 				virtual void				fillCommandBuffer(const TestEnvironment& env,
1009 					TestParams& testParams,
1010 					VkCommandBuffer					commandBuffer,
1011 					const VkAccelerationStructureKHR* rayQueryTopAccelerationStructurePtr,
1012 					const VkDescriptorImageInfo& resultImageInfo) override;
1013 
1014 			protected:
1015 				Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
1016 				Move<VkDescriptorPool>		m_descriptorPool;
1017 				Move<VkDescriptorSet>		m_descriptorSet;
1018 				Move<VkPipelineLayout>		m_pipelineLayout;
1019 
1020 				Move<VkShaderModule>		m_shaderModule;
1021 
1022 				Move<VkPipeline>			m_pipeline;
1023 			};
1024 
ComputeConfiguration()1025 			ComputeConfiguration::ComputeConfiguration()
1026 				: PipelineConfiguration()
1027 				, m_descriptorSetLayout()
1028 				, m_descriptorPool()
1029 				, m_descriptorSet()
1030 				, m_pipelineLayout()
1031 
1032 				, m_shaderModule()
1033 
1034 				, m_pipeline()
1035 			{
1036 			}
1037 
checkSupport(Context & context,const TestParams & testParams)1038 			void ComputeConfiguration::checkSupport(Context& context,
1039 				const TestParams& testParams)
1040 			{
1041 				DE_UNREF(context);
1042 				DE_UNREF(testParams);
1043 			}
1044 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)1045 			void ComputeConfiguration::initPrograms(SourceCollections& programCollection,
1046 				const TestParams& testParams)
1047 			{
1048 				DE_ASSERT(testParams.stage == VK_SHADER_STAGE_COMPUTE_BIT);
1049 
1050 				if (testParams.isSPIRV)
1051 				{
1052 					const vk::SpirVAsmBuildOptions spvBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true);
1053 
1054 					programCollection.spirvAsmSources.add("comp") << testParams.testConfigShaderBodyText(testParams) << spvBuildOptions;
1055 				}
1056 				else
1057 				{
1058 					const vk::ShaderBuildOptions	buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1059 					const std::string				testShaderBody = testParams.testConfigShaderBodyText(testParams);
1060 					const std::string				testBody =
1061 						"  ivec3       pos      = ivec3(gl_WorkGroupID);\n"
1062 						"  ivec3       size     = ivec3(gl_NumWorkGroups);\n"
1063 						+ testShaderBody;
1064 
1065 					std::stringstream css;
1066 					css <<
1067 						"#version 460 core\n"
1068 						"#extension GL_EXT_ray_query : require\n"
1069 						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1070 						"layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1071 						"\n"
1072 						"void main()\n"
1073 						"{\n"
1074 						<< testBody <<
1075 						"}\n";
1076 
1077 					programCollection.glslSources.add("comp") << glu::ComputeSource(updateRayTracingGLSL(css.str())) << buildOptions;
1078 				}
1079 			}
1080 
initConfiguration(const TestEnvironment & env,TestParams & testParams)1081 			void ComputeConfiguration::initConfiguration(const TestEnvironment& env,
1082 				TestParams& testParams)
1083 			{
1084 				DE_UNREF(testParams);
1085 
1086 				const DeviceInterface&	vkd = *env.vkd;
1087 				const VkDevice			device = env.device;
1088 				vk::BinaryCollection&	collection = *env.binaryCollection;
1089 
1090 				m_descriptorSetLayout = DescriptorSetLayoutBuilder()
1091 					.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
1092 					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_COMPUTE_BIT)
1093 					.build(vkd, device);
1094 				m_descriptorPool = DescriptorPoolBuilder()
1095 					.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1096 					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1097 					.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1098 				m_descriptorSet = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
1099 				m_pipelineLayout = makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
1100 				m_shaderModule = createShaderModule(vkd, device, collection.get("comp"), 0);
1101 				m_pipeline = makeComputePipeline(vkd, device, *m_pipelineLayout, *m_shaderModule);
1102 			}
1103 
fillCommandBuffer(const TestEnvironment & env,TestParams & testParams,VkCommandBuffer cmdBuffer,const VkAccelerationStructureKHR * rayQueryTopAccelerationStructurePtr,const VkDescriptorImageInfo & resultImageInfo)1104 			void ComputeConfiguration::fillCommandBuffer(const TestEnvironment& env,
1105 				TestParams& testParams,
1106 				VkCommandBuffer					cmdBuffer,
1107 				const VkAccelerationStructureKHR* rayQueryTopAccelerationStructurePtr,
1108 				const VkDescriptorImageInfo& resultImageInfo)
1109 			{
1110 				const DeviceInterface&								vkd												= *env.vkd;
1111 				const VkDevice										device											= env.device;
1112 				const VkWriteDescriptorSetAccelerationStructureKHR	rayQueryAccelerationStructureWriteDescriptorSet	=
1113 				{
1114 					VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
1115 					DE_NULL,															//  const void*							pNext;
1116 					1u,																	//  deUint32							accelerationStructureCount;
1117 					rayQueryTopAccelerationStructurePtr,								//  const VkAccelerationStructureKHR*	pAccelerationStructures;
1118 				};
1119 
1120 				DescriptorSetUpdateBuilder()
1121 					.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
1122 					.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
1123 					.update(vkd, device);
1124 
1125 				vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
1126 
1127 				vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline.get());
1128 
1129 				vkd.cmdDispatch(cmdBuffer, testParams.width, testParams.height, 1);
1130 			}
1131 
1132 			class RayTracingConfiguration : public PipelineConfiguration
1133 			{
1134 			public:
1135 				RayTracingConfiguration();
~RayTracingConfiguration()1136 				virtual											~RayTracingConfiguration() {}
1137 
1138 				static void										checkSupport(Context& context,
1139 					const TestParams& testParams);
1140 				static void										initPrograms(SourceCollections& programCollection,
1141 					const TestParams& testParams);
1142 
1143 				virtual void									initConfiguration(const TestEnvironment& env,
1144 					TestParams& testParams) override;
1145 				virtual void									fillCommandBuffer(const TestEnvironment& env,
1146 					TestParams& testParams,
1147 					VkCommandBuffer					commandBuffer,
1148 					const VkAccelerationStructureKHR* rayQueryTopAccelerationStructurePtr,
1149 					const VkDescriptorImageInfo& resultImageInfo) override;
1150 
1151 			protected:
1152 				de::MovePtr<BufferWithMemory>					createShaderBindingTable(const InstanceInterface& vki,
1153 					const DeviceInterface& vkd,
1154 					const VkDevice						device,
1155 					const VkPhysicalDevice				physicalDevice,
1156 					const VkPipeline					pipeline,
1157 					Allocator& allocator,
1158 					de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
1159 					const deUint32						group);
1160 
1161 			protected:
1162 				deUint32										m_shaders;
1163 				deUint32										m_raygenShaderGroup;
1164 				deUint32										m_missShaderGroup;
1165 				deUint32										m_hitShaderGroup;
1166 				deUint32										m_callableShaderGroup;
1167 				deUint32										m_shaderGroupCount;
1168 
1169 				Move<VkDescriptorSetLayout>						m_descriptorSetLayout;
1170 				Move<VkDescriptorPool>							m_descriptorPool;
1171 				Move<VkDescriptorSet>							m_descriptorSet;
1172 				Move<VkPipelineLayout>							m_pipelineLayout;
1173 
1174 				de::MovePtr<RayTracingPipeline>					m_rayTracingPipeline;
1175 				Move<VkPipeline>								m_pipeline;
1176 
1177 				de::MovePtr<BufferWithMemory>					m_raygenShaderBindingTable;
1178 				de::MovePtr<BufferWithMemory>					m_hitShaderBindingTable;
1179 				de::MovePtr<BufferWithMemory>					m_missShaderBindingTable;
1180 				de::MovePtr<BufferWithMemory>					m_callableShaderBindingTable;
1181 
1182 				VkStridedDeviceAddressRegionKHR					m_raygenShaderBindingTableRegion;
1183 				VkStridedDeviceAddressRegionKHR					m_missShaderBindingTableRegion;
1184 				VkStridedDeviceAddressRegionKHR					m_hitShaderBindingTableRegion;
1185 				VkStridedDeviceAddressRegionKHR					m_callableShaderBindingTableRegion;
1186 
1187 				de::SharedPtr<BottomLevelAccelerationStructure>	m_bottomLevelAccelerationStructure;
1188 				de::SharedPtr<TopLevelAccelerationStructure>	m_topLevelAccelerationStructure;
1189 			};
1190 
RayTracingConfiguration()1191 			RayTracingConfiguration::RayTracingConfiguration()
1192 				: m_shaders(0)
1193 				, m_raygenShaderGroup(~0u)
1194 				, m_missShaderGroup(~0u)
1195 				, m_hitShaderGroup(~0u)
1196 				, m_callableShaderGroup(~0u)
1197 				, m_shaderGroupCount(0)
1198 
1199 				, m_descriptorSetLayout()
1200 				, m_descriptorPool()
1201 				, m_descriptorSet()
1202 				, m_pipelineLayout()
1203 
1204 				, m_rayTracingPipeline()
1205 				, m_pipeline()
1206 
1207 				, m_raygenShaderBindingTable()
1208 				, m_hitShaderBindingTable()
1209 				, m_missShaderBindingTable()
1210 				, m_callableShaderBindingTable()
1211 
1212 				, m_raygenShaderBindingTableRegion()
1213 				, m_missShaderBindingTableRegion()
1214 				, m_hitShaderBindingTableRegion()
1215 				, m_callableShaderBindingTableRegion()
1216 
1217 				, m_bottomLevelAccelerationStructure()
1218 				, m_topLevelAccelerationStructure()
1219 			{
1220 			}
1221 
checkSupport(Context & context,const TestParams & testParams)1222 			void RayTracingConfiguration::checkSupport(Context& context,
1223 				const TestParams& testParams)
1224 			{
1225 				DE_UNREF(testParams);
1226 
1227 				context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1228 				const VkPhysicalDeviceRayTracingPipelineFeaturesKHR& rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
1229 				if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE)
1230 					TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1231 			}
1232 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)1233 			void RayTracingConfiguration::initPrograms(SourceCollections& programCollection,
1234 				const TestParams& testParams)
1235 			{
1236 				const vk::ShaderBuildOptions	buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1237 
1238 				const std::string				testShaderBody = testParams.testConfigShaderBodyText(testParams);
1239 				const std::string				testBody =
1240 					"  ivec3       pos      = ivec3(gl_LaunchIDEXT);\n"
1241 					"  ivec3       size     = ivec3(gl_LaunchSizeEXT);\n"
1242 					+ testShaderBody;
1243 
1244 				switch (testParams.stage)
1245 				{
1246 				case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
1247 				{
1248 					std::stringstream css;
1249 					css <<
1250 						"#version 460 core\n"
1251 						"#extension GL_EXT_ray_tracing : require\n"
1252 						"#extension GL_EXT_ray_query : require\n"
1253 						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1254 						"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1255 						"\n"
1256 						"void main()\n"
1257 						"{\n"
1258 						<< testBody <<
1259 						"}\n";
1260 
1261 					programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1262 
1263 					break;
1264 				}
1265 
1266 				case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
1267 				{
1268 					programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1269 
1270 					{
1271 						std::stringstream css;
1272 						css <<
1273 							"#version 460 core\n"
1274 							"#extension GL_EXT_ray_tracing : require\n"
1275 							"#extension GL_EXT_ray_query : require\n"
1276 							"hitAttributeEXT vec3 attribs;\n"
1277 							"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1278 							"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1279 							"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1280 							"\n"
1281 							"void main()\n"
1282 							"{\n"
1283 							<< testBody <<
1284 							"}\n";
1285 
1286 						programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1287 					}
1288 
1289 					programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1290 					programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1291 
1292 					break;
1293 				}
1294 
1295 				case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
1296 				{
1297 					programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1298 
1299 					{
1300 						std::stringstream css;
1301 						css <<
1302 							"#version 460 core\n"
1303 							"#extension GL_EXT_ray_tracing : require\n"
1304 							"#extension GL_EXT_ray_query : require\n"
1305 							"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1306 							"hitAttributeEXT vec3 attribs;\n"
1307 							"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1308 							"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1309 							"\n"
1310 							"void main()\n"
1311 							"{\n"
1312 							<< testBody <<
1313 							"}\n";
1314 
1315 						programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1316 					}
1317 
1318 					programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1319 					programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1320 
1321 					break;
1322 				}
1323 
1324 				case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
1325 				{
1326 					programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1327 
1328 					{
1329 						std::stringstream css;
1330 						css <<
1331 							"#version 460 core\n"
1332 							"#extension GL_EXT_ray_tracing : require\n"
1333 							"#extension GL_EXT_ray_query : require\n"
1334 							"hitAttributeEXT vec3 hitAttribute;\n"
1335 							"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1336 							"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1337 							"\n"
1338 							"void main()\n"
1339 							"{\n"
1340 							<< testBody <<
1341 							"  hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n"
1342 							"  reportIntersectionEXT(1.0f, 0);\n"
1343 							"}\n";
1344 
1345 						programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1346 					}
1347 
1348 					programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1349 					programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1350 					programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1351 
1352 					break;
1353 				}
1354 
1355 				case VK_SHADER_STAGE_MISS_BIT_KHR:
1356 				{
1357 					programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1358 
1359 					{
1360 						std::stringstream css;
1361 						css <<
1362 							"#version 460 core\n"
1363 							"#extension GL_EXT_ray_tracing : require\n"
1364 							"#extension GL_EXT_ray_query : require\n"
1365 							"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1366 							"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1367 							"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1368 							"\n"
1369 							"void main()\n"
1370 							"{\n"
1371 							<< testBody <<
1372 							"}\n";
1373 
1374 						programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1375 					}
1376 
1377 					programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1378 					programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1379 
1380 					break;
1381 				}
1382 
1383 				case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
1384 				{
1385 					{
1386 						std::stringstream css;
1387 						css <<
1388 							"#version 460 core\n"
1389 							"#extension GL_EXT_ray_tracing : require\n"
1390 							"#extension GL_EXT_ray_query : require\n"
1391 							"layout(location = 0) callableDataEXT float dummy;"
1392 							"layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1393 							"\n"
1394 							"void main()\n"
1395 							"{\n"
1396 							"  executeCallableEXT(0, 0);\n"
1397 							"}\n";
1398 
1399 						programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1400 					}
1401 
1402 					{
1403 						std::stringstream css;
1404 						css <<
1405 							"#version 460 core\n"
1406 							"#extension GL_EXT_ray_tracing : require\n"
1407 							"#extension GL_EXT_ray_query : require\n"
1408 							"layout(location = 0) callableDataInEXT float dummy;"
1409 							"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1410 							"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1411 							"\n"
1412 							"void main()\n"
1413 							"{\n"
1414 							<< testBody <<
1415 							"}\n";
1416 
1417 						programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
1418 					}
1419 
1420 					programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1421 					programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1422 					programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1423 
1424 					break;
1425 				}
1426 
1427 				default:
1428 					TCU_THROW(InternalError, "Unknown stage");
1429 				}
1430 			}
1431 
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)1432 			de::MovePtr<BufferWithMemory> RayTracingConfiguration::createShaderBindingTable(const InstanceInterface& vki,
1433 				const DeviceInterface& vkd,
1434 				const VkDevice						device,
1435 				const VkPhysicalDevice				physicalDevice,
1436 				const VkPipeline					pipeline,
1437 				Allocator& allocator,
1438 				de::MovePtr<RayTracingPipeline>& rayTracingPipeline,
1439 				const deUint32						group)
1440 			{
1441 				de::MovePtr<BufferWithMemory>	shaderBindingTable;
1442 
1443 				if (group < m_shaderGroupCount)
1444 				{
1445 					const deUint32	shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice);
1446 					const deUint32	shaderGroupBaseAlignment = getShaderGroupBaseAlignment(vki, physicalDevice);
1447 
1448 					shaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, group, 1u);
1449 				}
1450 
1451 				return shaderBindingTable;
1452 			}
1453 
initConfiguration(const TestEnvironment & env,TestParams & testParams)1454 			void RayTracingConfiguration::initConfiguration(const TestEnvironment& env,
1455 				TestParams& testParams)
1456 			{
1457 				DE_UNREF(testParams);
1458 
1459 				const InstanceInterface&	vki = *env.vki;
1460 				const DeviceInterface&		vkd = *env.vkd;
1461 				const VkDevice				device = env.device;
1462 				const VkPhysicalDevice		physicalDevice = env.physicalDevice;
1463 				vk::BinaryCollection&		collection = *env.binaryCollection;
1464 				Allocator&					allocator = *env.allocator;
1465 				const deUint32				shaderGroupHandleSize = getShaderGroupHandleSize(vki, physicalDevice);
1466 				const VkShaderStageFlags	hitStages = VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
1467 				deUint32					shaderCount = 0;
1468 
1469 				m_shaderGroupCount = 0;
1470 
1471 				if (collection.contains("rgen")) m_shaders |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
1472 				if (collection.contains("ahit")) m_shaders |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
1473 				if (collection.contains("chit")) m_shaders |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
1474 				if (collection.contains("miss")) m_shaders |= VK_SHADER_STAGE_MISS_BIT_KHR;
1475 				if (collection.contains("sect")) m_shaders |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
1476 				if (collection.contains("call")) m_shaders |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
1477 
1478 				for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
1479 					shaderCount++;
1480 
1481 				if (shaderCount != (deUint32)dePop32(m_shaders))
1482 					TCU_THROW(InternalError, "Unused shaders detected in the collection");
1483 
1484 				if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))
1485 					m_raygenShaderGroup = m_shaderGroupCount++;
1486 
1487 				if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))
1488 					m_missShaderGroup = m_shaderGroupCount++;
1489 
1490 				if (0 != (m_shaders & hitStages))
1491 					m_hitShaderGroup = m_shaderGroupCount++;
1492 
1493 				if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))
1494 					m_callableShaderGroup = m_shaderGroupCount++;
1495 
1496 				m_rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
1497 
1498 				m_descriptorSetLayout = DescriptorSetLayoutBuilder()
1499 					.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
1500 					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1501 					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1502 					.build(vkd, device);
1503 				m_descriptorPool = DescriptorPoolBuilder()
1504 					.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1505 					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1506 					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1507 					.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1508 				m_descriptorSet = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
1509 
1510 				if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))			m_rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, collection.get("rgen"), 0), m_raygenShaderGroup);
1511 				if (0 != (m_shaders & VK_SHADER_STAGE_ANY_HIT_BIT_KHR))			m_rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR, createShaderModule(vkd, device, collection.get("ahit"), 0), m_hitShaderGroup);
1512 				if (0 != (m_shaders & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR))		m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, collection.get("chit"), 0), m_hitShaderGroup);
1513 				if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))			m_rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, collection.get("miss"), 0), m_missShaderGroup);
1514 				if (0 != (m_shaders & VK_SHADER_STAGE_INTERSECTION_BIT_KHR))	m_rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR, createShaderModule(vkd, device, collection.get("sect"), 0), m_hitShaderGroup);
1515 				if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))		m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, collection.get("call"), 0), m_callableShaderGroup);
1516 
1517 				m_pipelineLayout = makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
1518 				m_pipeline = m_rayTracingPipeline->createPipeline(vkd, device, *m_pipelineLayout);
1519 
1520 				m_raygenShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_raygenShaderGroup);
1521 				m_missShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_missShaderGroup);
1522 				m_hitShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_hitShaderGroup);
1523 				m_callableShaderBindingTable = createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_callableShaderGroup);
1524 
1525 				m_raygenShaderBindingTableRegion = m_raygenShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, m_raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1526 				m_missShaderBindingTableRegion = m_missShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, m_missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1527 				m_hitShaderBindingTableRegion = m_hitShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, m_hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1528 				m_callableShaderBindingTableRegion = m_callableShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, m_callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1529 			}
1530 
fillCommandBuffer(const TestEnvironment & env,TestParams & testParams,VkCommandBuffer commandBuffer,const VkAccelerationStructureKHR * rayQueryTopAccelerationStructurePtr,const VkDescriptorImageInfo & resultImageInfo)1531 			void RayTracingConfiguration::fillCommandBuffer(const TestEnvironment& env,
1532 				TestParams& testParams,
1533 				VkCommandBuffer					commandBuffer,
1534 				const VkAccelerationStructureKHR* rayQueryTopAccelerationStructurePtr,
1535 				const VkDescriptorImageInfo& resultImageInfo)
1536 			{
1537 				const DeviceInterface&							vkd									= *env.vkd;
1538 				const VkDevice									device								= env.device;
1539 				Allocator&										allocator							= *env.allocator;
1540 				de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure	= makeBottomLevelAccelerationStructure();
1541 				de::MovePtr<TopLevelAccelerationStructure>		topLevelAccelerationStructure		= makeTopLevelAccelerationStructure();
1542 
1543 				m_bottomLevelAccelerationStructure = de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release());
1544 				m_bottomLevelAccelerationStructure->setDefaultGeometryData(testParams.stage);
1545 				m_bottomLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1546 
1547 				m_topLevelAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(topLevelAccelerationStructure.release());
1548 				m_topLevelAccelerationStructure->setInstanceCount(1);
1549 				m_topLevelAccelerationStructure->addInstance(m_bottomLevelAccelerationStructure);
1550 				m_topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1551 
1552 				const TopLevelAccelerationStructure* topLevelAccelerationStructurePtr = m_topLevelAccelerationStructure.get();
1553 				const VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet =
1554 				{
1555 					VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
1556 					DE_NULL,															//  const void*							pNext;
1557 					1u,																	//  deUint32							accelerationStructureCount;
1558 					topLevelAccelerationStructurePtr->getPtr(),							//  const VkAccelerationStructureKHR*	pAccelerationStructures;
1559 				};
1560 				const VkWriteDescriptorSetAccelerationStructureKHR	rayQueryAccelerationStructureWriteDescriptorSet =
1561 				{
1562 					VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
1563 					DE_NULL,															//  const void*							pNext;
1564 					1u,																	//  deUint32							accelerationStructureCount;
1565 					rayQueryTopAccelerationStructurePtr,								//  const VkAccelerationStructureKHR*	pAccelerationStructures;
1566 				};
1567 
1568 				DescriptorSetUpdateBuilder()
1569 					.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
1570 					.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1571 					.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
1572 					.update(vkd, device);
1573 
1574 				vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
1575 
1576 				vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, m_pipeline.get());
1577 
1578 				cmdTraceRays(vkd,
1579 					commandBuffer,
1580 					&m_raygenShaderBindingTableRegion,
1581 					&m_missShaderBindingTableRegion,
1582 					&m_hitShaderBindingTableRegion,
1583 					&m_callableShaderBindingTableRegion,
1584 					testParams.width, testParams.height, 1);
1585 			}
1586 
prepareTestEnvironment(Context & context)1587 			void TestConfiguration::prepareTestEnvironment (Context& context)
1588 			{
1589 				// By default, all data comes from the context.
1590 				m_testEnvironment = de::MovePtr<TestEnvironment>(new TestEnvironment
1591 				{
1592 					&context.getInstanceInterface(),		//	const InstanceInterface*	vki;
1593 					context.getPhysicalDevice(),			//	VkPhysicalDevice			physicalDevice;
1594 					&context.getDeviceInterface(),			//	const DeviceInterface*		vkd;
1595 					context.getDevice(),					//	VkDevice					device;
1596 					&context.getDefaultAllocator(),			//	Allocator*					allocator;
1597 					context.getUniversalQueue(),			//	VkQueue						queue;
1598 					context.getUniversalQueueFamilyIndex(),	//	deUint32					queueFamilyIndex;
1599 					&context.getBinaryCollection(),			//	BinaryCollection*			binaryCollection;
1600 					&context.getTestContext().getLog(),		//	tcu::TestLog*				log;
1601 				});
1602 			}
1603 
getTestEnvironment() const1604 			const TestEnvironment& TestConfiguration::getTestEnvironment () const
1605 			{
1606 				return *m_testEnvironment;
1607 			}
1608 
verify(BufferWithMemory * resultBuffer,TestParams & testParams)1609 			bool TestConfiguration::verify(BufferWithMemory* resultBuffer, TestParams& testParams)
1610 			{
1611 				tcu::TestLog&	log = *(m_testEnvironment->log);
1612 				const deUint32	width = testParams.width;
1613 				const deUint32	height = testParams.height;
1614 				const deInt32* resultPtr = (deInt32*)resultBuffer->getAllocation().getHostPtr();
1615 				const deInt32* expectedPtr = m_expected.data();
1616 				deUint32		failures = 0;
1617 				deUint32		pos = 0;
1618 
1619 				for (deUint32 y = 0; y < height; ++y)
1620 					for (deUint32 x = 0; x < width; ++x)
1621 					{
1622 						if (resultPtr[pos] != expectedPtr[pos])
1623 							failures++;
1624 
1625 						pos++;
1626 					}
1627 
1628 				if (failures != 0)
1629 				{
1630 					const char* names[] = { "Retrieved:", "Expected:" };
1631 
1632 					for (deUint32 n = 0; n < 2; ++n)
1633 					{
1634 						std::stringstream	css;
1635 
1636 						pos = 0;
1637 
1638 						for (deUint32 y = 0; y < height; ++y)
1639 						{
1640 							for (deUint32 x = 0; x < width; ++x)
1641 							{
1642 								if (resultPtr[pos] != expectedPtr[pos])
1643 									css << std::setw(12) << (n == 0 ? resultPtr[pos] : expectedPtr[pos]) << ",";
1644 								else
1645 									css << "____________,";
1646 
1647 								pos++;
1648 							}
1649 
1650 							css << std::endl;
1651 						}
1652 
1653 						log << tcu::TestLog::Message << names[n] << tcu::TestLog::EndMessage;
1654 						log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
1655 					}
1656 				}
1657 
1658 				return (failures == 0);
1659 			}
1660 
verify(BufferWithMemory * resultBuffer,TestParams & testParams)1661 			bool TestConfigurationFloat::verify(BufferWithMemory* resultBuffer, TestParams& testParams)
1662 			{
1663 				tcu::TestLog&	log = *(m_testEnvironment->log);
1664 				const float		eps = float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
1665 				const deUint32	width = testParams.width;
1666 				const deUint32	height = testParams.height;
1667 				const deInt32* resultPtr = (deInt32*)resultBuffer->getAllocation().getHostPtr();
1668 				const deInt32* expectedPtr = m_expected.data();
1669 				deUint32		failures = 0;
1670 				deUint32		pos = 0;
1671 
1672 				for (deUint32 y = 0; y < height; ++y)
1673 					for (deUint32 x = 0; x < width; ++x)
1674 					{
1675 						const float		retrievedValue = float(resultPtr[pos]) / float(FIXED_POINT_DIVISOR);
1676 						const float		expectedValue = float(expectedPtr[pos]) / float(FIXED_POINT_DIVISOR);
1677 
1678 						if (deFloatAbs(retrievedValue - expectedValue) > eps)
1679 							failures++;
1680 
1681 						pos++;
1682 					}
1683 
1684 				if (failures != 0)
1685 				{
1686 					const char* names[] = { "Retrieved:", "Expected:" };
1687 
1688 					for (deUint32 n = 0; n < 2; ++n)
1689 					{
1690 						std::stringstream	css;
1691 
1692 						pos = 0;
1693 
1694 						for (deUint32 y = 0; y < height; ++y)
1695 						{
1696 							for (deUint32 x = 0; x < width; ++x)
1697 							{
1698 								const float	retrievedValue = float(resultPtr[pos]) / float(FIXED_POINT_DIVISOR);
1699 								const float	expectedValue = float(expectedPtr[pos]) / float(FIXED_POINT_DIVISOR);
1700 
1701 								if (deFloatAbs(retrievedValue - expectedValue) > eps)
1702 									css << std::setprecision(8) << std::setw(12) << (n == 0 ? retrievedValue : expectedValue) << ",";
1703 								else
1704 									css << "____________,";
1705 
1706 								pos++;
1707 							}
1708 
1709 							css << std::endl;
1710 						}
1711 
1712 						log << tcu::TestLog::Message << names[n] << tcu::TestLog::EndMessage;
1713 						log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
1714 					}
1715 				}
1716 
1717 				return (failures == 0);
1718 			}
1719 
verify(BufferWithMemory * resultBuffer,TestParams & testParams)1720 			bool TestConfigurationVector::verify(BufferWithMemory* resultBuffer, TestParams& testParams)
1721 			{
1722 				tcu::TestLog&	log = *(m_testEnvironment->log);
1723 				const float		eps = float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
1724 				const deUint32	width = testParams.width;
1725 				const deUint32	height = testParams.height;
1726 				const deUint32	depth = 3u; // vec3
1727 				const deInt32* resultPtr = (deInt32*)resultBuffer->getAllocation().getHostPtr();
1728 				const deInt32* expectedPtr = m_expected.data();
1729 				deUint32		failures = 0;
1730 				deUint32		pos = 0;
1731 
1732 				if (m_useStrictComponentMatching)
1733 				{
1734 					for (deUint32 z = 0; z < depth; ++z)
1735 					{
1736 						for (deUint32 y = 0; y < height; ++y)
1737 						{
1738 							for (deUint32 x = 0; x < width; ++x)
1739 							{
1740 								const float	retrievedValue = float(resultPtr[pos]) / float(FIXED_POINT_DIVISOR);
1741 								const float	expectedValue = float(expectedPtr[pos]) / float(FIXED_POINT_DIVISOR);
1742 
1743 								if (deFloatAbs(retrievedValue - expectedValue) > eps)
1744 									failures++;
1745 
1746 								++pos;
1747 							}
1748 						}
1749 					}
1750 				}
1751 				else
1752 				{
1753 					// This path is taken for barycentric coords, which can be returned in any order.
1754 					//
1755 					// We need to ensure that:
1756 					// 1. Each component value found in the retrieved value has a match in the expected value vec.
1757 					// 2. Only one mapping exists per each component in the expected value vec.
1758 					const auto	nSquares = width * height;
1759 
1760 					for (deUint32 y = 0; y < height; ++y)
1761 					{
1762 						for (deUint32 x = 0; x < width; ++x)
1763 						{
1764 							bool		expectedVectorComponentUsed[3] = { false };
1765 							const auto	squareNdx = y * width + x;
1766 
1767 							for (deUint32 retrievedComponentNdx = 0; retrievedComponentNdx < 3 /* vec3 */; ++retrievedComponentNdx)
1768 							{
1769 								const float	retrievedValue = float(resultPtr[nSquares * retrievedComponentNdx + squareNdx]) / float(FIXED_POINT_DIVISOR);
1770 
1771 								for (deUint32 expectedComponentNdx = 0; expectedComponentNdx < 3 /* vec3 */; ++expectedComponentNdx)
1772 								{
1773 									const float	expectedValue = float(expectedPtr[nSquares * expectedComponentNdx + squareNdx]) / float(FIXED_POINT_DIVISOR);
1774 
1775 									if (deFloatAbs(retrievedValue - expectedValue) <= eps &&
1776 										expectedVectorComponentUsed[expectedComponentNdx] == false)
1777 									{
1778 										expectedVectorComponentUsed[expectedComponentNdx] = true;
1779 
1780 										break;
1781 									}
1782 
1783 									++pos;
1784 								}
1785 							}
1786 
1787 							if (expectedVectorComponentUsed[0] == false ||
1788 								expectedVectorComponentUsed[1] == false ||
1789 								expectedVectorComponentUsed[2] == false)
1790 							{
1791 								++failures;
1792 							}
1793 						}
1794 					}
1795 				}
1796 
1797 				if (failures != 0)
1798 				{
1799 					const char* names[] = {
1800 						"Retrieved",
1801 						(m_useStrictComponentMatching) ? "Expected"
1802 														: "Expected (component order is irrelevant)"
1803 					};
1804 
1805 					std::stringstream css;
1806 
1807 					for (deUint32 y = 0; y < height; ++y)
1808 					{
1809 						for (deUint32 x = 0; x < width; ++x)
1810 						{
1811 							for (deUint32 n = 0; n < 2; ++n)
1812 							{
1813 								css << names[n] << " at (" << x << "," << y << ") {";
1814 
1815 								for (deUint32 z = 0; z < depth; ++z)
1816 								{
1817 									pos = x + width * (y + height * z);
1818 
1819 									const float	retrievedValue = float(resultPtr[pos]) / float(FIXED_POINT_DIVISOR);
1820 									const float	expectedValue = float(expectedPtr[pos]) / float(FIXED_POINT_DIVISOR);
1821 
1822 									if (deFloatAbs(retrievedValue - expectedValue) > eps ||
1823 										m_useStrictComponentMatching == false)
1824 									{
1825 										css << std::setprecision(8) << std::setw(12) << (n == 0 ? retrievedValue : expectedValue) << ",";
1826 									}
1827 									else
1828 										css << "____________,";
1829 								}
1830 
1831 								css << "}" << std::endl;
1832 							}
1833 						}
1834 					}
1835 
1836 					log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
1837 				}
1838 
1839 				return failures == 0;
1840 			}
1841 
verify(BufferWithMemory * resultBuffer,TestParams & testParams)1842 			bool TestConfigurationMatrix::verify(BufferWithMemory* resultBuffer, TestParams& testParams)
1843 			{
1844 				tcu::TestLog&	log = *(m_testEnvironment->log);
1845 				const float		eps = float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
1846 				const deUint32	width = testParams.width;
1847 				const deUint32	height = testParams.height;
1848 				const deUint32	depth = 12u; // mat3x4 or mat4x3
1849 				const deInt32* resultPtr = (deInt32*)resultBuffer->getAllocation().getHostPtr();
1850 				const deInt32* expectedPtr = m_expected.data();
1851 				deUint32		failures = 0;
1852 				deUint32		pos = 0;
1853 
1854 				for (deUint32 z = 0; z < depth; ++z)
1855 					for (deUint32 y = 0; y < height; ++y)
1856 						for (deUint32 x = 0; x < width; ++x)
1857 						{
1858 							const float	retrievedValue = float(resultPtr[pos]) / float(FIXED_POINT_DIVISOR);
1859 							const float	expectedValue = float(expectedPtr[pos]) / float(FIXED_POINT_DIVISOR);
1860 
1861 							if (deFloatAbs(retrievedValue - expectedValue) > eps)
1862 								failures++;
1863 
1864 							++pos;
1865 						}
1866 
1867 				if (failures != 0)
1868 				{
1869 					const char* names[] = { "Retrieved", "Expected" };
1870 					std::stringstream	css;
1871 
1872 					for (deUint32 y = 0; y < height; ++y)
1873 					{
1874 						for (deUint32 x = 0; x < width; ++x)
1875 						{
1876 							css << "At (" << x << "," << y << ")" << std::endl;
1877 							for (deUint32 n = 0; n < 2; ++n)
1878 							{
1879 								css << names[n] << std::endl << "{" << std::endl;
1880 
1881 								for (deUint32 z = 0; z < depth; ++z)
1882 								{
1883 									pos = x + width * (y + height * z);
1884 
1885 									const float	retrievedValue = float(resultPtr[pos]) / float(FIXED_POINT_DIVISOR);
1886 									const float	expectedValue = float(expectedPtr[pos]) / float(FIXED_POINT_DIVISOR);
1887 
1888 									if (z % 4 == 0)
1889 										css << "    {";
1890 
1891 									if (deFloatAbs(retrievedValue - expectedValue) > eps)
1892 										css << std::setprecision(5) << std::setw(9) << (n == 0 ? retrievedValue : expectedValue) << ",";
1893 									else
1894 										css << "_________,";
1895 
1896 									if (z % 4 == 3)
1897 										css << "}" << std::endl;
1898 								}
1899 
1900 								css << "}" << std::endl;
1901 							}
1902 						}
1903 					}
1904 
1905 					log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
1906 				}
1907 
1908 				return failures == 0;
1909 			}
1910 
1911 			class TestConfigurationFlow : public TestConfiguration
1912 			{
1913 			public:
TestConfigurationFlow(Context & context)1914 				TestConfigurationFlow (Context& context) : TestConfiguration(context) {}
1915 
1916 				static const std::string					getShaderBodyText(const TestParams& testParams);
1917 
1918 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
1919 					VkCommandBuffer					cmdBuffer) override;
1920 			};
1921 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)1922 			const VkAccelerationStructureKHR* TestConfigurationFlow::initAccelerationStructures(TestParams& testParams,
1923 				VkCommandBuffer	cmdBuffer)
1924 			{
1925 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
1926 				const VkDevice								device = m_testEnvironment->device;
1927 				Allocator&									allocator = *m_testEnvironment->allocator;
1928 				const deUint32								width = testParams.width;
1929 				const deUint32								height = testParams.height;
1930 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
1931 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
1932 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
1933 				const bool									triangles = (testParams.geomType == GEOM_TYPE_TRIANGLES);
1934 				const float									z = -1.0f;
1935 				tcu::UVec2									startPos = tcu::UVec2(0, 0);
1936 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1937 
1938 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
1939 
1940 				m_expected = std::vector<deInt32>(width * height, 1);
1941 
1942 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
1943 
1944 				for (size_t instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
1945 				{
1946 					de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1947 
1948 					for (size_t geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
1949 					{
1950 						std::vector<tcu::Vec3>	geometryData;
1951 
1952 						geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
1953 
1954 						for (size_t squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
1955 						{
1956 							const deUint32	n = width * startPos.y() + startPos.x();
1957 							const deUint32	m = n + 1;
1958 							const float		x0 = float(startPos.x() + 0) / float(width);
1959 							const float		y0 = float(startPos.y() + 0) / float(height);
1960 							const float		x1 = float(startPos.x() + 1) / float(width);
1961 							const float		y1 = float(startPos.y() + 1) / float(height);
1962 
1963 							if (triangles)
1964 							{
1965 								const float	xm = (x0 + x1) / 2.0f;
1966 								const float	ym = (y0 + y1) / 2.0f;
1967 
1968 								geometryData.push_back(tcu::Vec3(x0, y0, z));
1969 								geometryData.push_back(tcu::Vec3(xm, y1, z));
1970 								geometryData.push_back(tcu::Vec3(x1, ym, z));
1971 							}
1972 							else
1973 							{
1974 								geometryData.push_back(tcu::Vec3(x0, y0, z));
1975 								geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
1976 							}
1977 
1978 							startPos.y() = m / width;
1979 							startPos.x() = m % width;
1980 						}
1981 
1982 						rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
1983 					}
1984 
1985 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
1986 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
1987 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back());
1988 				}
1989 
1990 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
1991 
1992 				return m_topAccelerationStructure.get()->getPtr();
1993 			}
1994 
getShaderBodyText(const TestParams & testParams)1995 			const std::string TestConfigurationFlow::getShaderBodyText(const TestParams& testParams)
1996 			{
1997 				if (testParams.geomType == GEOM_TYPE_AABBS)
1998 				{
1999 					const std::string result =
2000 						"  uint        rayFlags = 0;\n"
2001 						"  uint        cullMask = 0xFF;\n"
2002 						"  float       tmin     = 0.0;\n"
2003 						"  float       tmax     = 9.0;\n"
2004 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
2005 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
2006 						"  uint        value    = 4;\n"
2007 						"  rayQueryEXT rayQuery;\n"
2008 						"\n"
2009 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
2010 						"\n"
2011 						"  if (rayQueryProceedEXT(rayQuery))\n"
2012 						"  {\n"
2013 						"    value--;\n"
2014 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
2015 						"    {\n"
2016 						"      value--;\n"
2017 						"      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n"
2018 						"\n"
2019 						"      rayQueryProceedEXT(rayQuery);\n"
2020 						"\n"
2021 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
2022 						"        value--;\n"
2023 						"    }\n"
2024 						"  }\n"
2025 						"\n"
2026 						"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2027 
2028 					return result;
2029 				}
2030 				else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
2031 				{
2032 					const std::string result =
2033 						"  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
2034 						"  uint        cullMask = 0xFF;\n"
2035 						"  float       tmin     = 0.0;\n"
2036 						"  float       tmax     = 9.0;\n"
2037 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
2038 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
2039 						"  uint        value    = 4;\n"
2040 						"  rayQueryEXT rayQuery;\n"
2041 						"\n"
2042 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
2043 						"\n"
2044 						"  if (rayQueryProceedEXT(rayQuery))\n"
2045 						"  {\n"
2046 						"    value--;\n"
2047 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
2048 						"    {\n"
2049 						"      value--;\n"
2050 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
2051 						"\n"
2052 						"      rayQueryProceedEXT(rayQuery);\n"
2053 						"\n"
2054 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
2055 						"        value--;\n"
2056 						"    }\n"
2057 						"  }\n"
2058 						"\n"
2059 						"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2060 
2061 					return result;
2062 				}
2063 				else
2064 				{
2065 					TCU_THROW(InternalError, "Unknown geometry type");
2066 				}
2067 			}
2068 
2069 			class TestConfigurationPrimitiveId : public TestConfiguration
2070 			{
2071 			public:
TestConfigurationPrimitiveId(Context & context)2072 				TestConfigurationPrimitiveId (Context& context) : TestConfiguration(context) {}
2073 				static const std::string					getShaderBodyText(const TestParams& testParams);
2074 
2075 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
2076 					VkCommandBuffer					cmdBuffer) override;
2077 			};
2078 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)2079 			const VkAccelerationStructureKHR* TestConfigurationPrimitiveId::initAccelerationStructures(TestParams& testParams,
2080 				VkCommandBuffer	cmdBuffer)
2081 			{
2082 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
2083 				const VkDevice								device = m_testEnvironment->device;
2084 				Allocator&									allocator = *m_testEnvironment->allocator;
2085 				const deUint32								width = testParams.width;
2086 				const deUint32								height = testParams.height;
2087 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
2088 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
2089 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
2090 				const bool									triangles = (testParams.geomType == GEOM_TYPE_TRIANGLES);
2091 				const float									z = -1.0f;
2092 				tcu::UVec2									startPos = tcu::UVec2(0, 0);
2093 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
2094 
2095 				DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
2096 
2097 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
2098 
2099 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
2100 
2101 				m_expected.resize(width * height);
2102 
2103 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
2104 				{
2105 					de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
2106 
2107 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
2108 					{
2109 						std::vector<tcu::Vec3>	geometryData;
2110 
2111 						geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
2112 
2113 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2114 						{
2115 							const deUint32	n = width * startPos.y() + startPos.x();
2116 							const deUint32	m = (n + 11) % (width * height);
2117 							const float		x0 = float(startPos.x() + 0) / float(width);
2118 							const float		y0 = float(startPos.y() + 0) / float(height);
2119 							const float		x1 = float(startPos.x() + 1) / float(width);
2120 							const float		y1 = float(startPos.y() + 1) / float(height);
2121 
2122 							if (triangles)
2123 							{
2124 								const float	xm = (x0 + x1) / 2.0f;
2125 								const float	ym = (y0 + y1) / 2.0f;
2126 
2127 								geometryData.push_back(tcu::Vec3(x0, y0, z));
2128 								geometryData.push_back(tcu::Vec3(xm, y1, z));
2129 								geometryData.push_back(tcu::Vec3(x1, ym, z));
2130 							}
2131 							else
2132 							{
2133 								geometryData.push_back(tcu::Vec3(x0, y0, z));
2134 								geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
2135 							}
2136 
2137 							m_expected[n] = squareNdx;
2138 
2139 							startPos.y() = m / width;
2140 							startPos.x() = m % width;
2141 						}
2142 
2143 						rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
2144 					}
2145 
2146 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2147 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
2148 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4, instanceNdx + 1);
2149 				}
2150 
2151 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2152 
2153 				return m_topAccelerationStructure.get()->getPtr();
2154 			}
2155 
getShaderBodyText(const TestParams & testParams)2156 			const std::string TestConfigurationPrimitiveId::getShaderBodyText(const TestParams& testParams)
2157 			{
2158 				if (testParams.geomType == GEOM_TYPE_AABBS)
2159 				{
2160 					const std::string result =
2161 						"  uint        rayFlags = 0;\n"
2162 						"  uint        cullMask = 0xFF;\n"
2163 						"  float       tmin     = 0.0;\n"
2164 						"  float       tmax     = 9.0;\n"
2165 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
2166 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
2167 						"  uint        value    = -1;\n"
2168 						"  rayQueryEXT rayQuery;\n"
2169 						"\n"
2170 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
2171 						"\n"
2172 						"  if (rayQueryProceedEXT(rayQuery))\n"
2173 						"  {\n"
2174 						"    value--;\n"
2175 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
2176 						"    {\n"
2177 						"      value--;\n"
2178 						"      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n"
2179 						"\n"
2180 						"      rayQueryProceedEXT(rayQuery);\n"
2181 						"\n"
2182 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
2183 						"        value = rayQueryGetIntersectionPrimitiveIndexEXT(rayQuery, true);\n"
2184 						"    }\n"
2185 						"  }\n"
2186 						"\n"
2187 						"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2188 
2189 					return result;
2190 				}
2191 				else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
2192 				{
2193 					const std::string result =
2194 						"  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
2195 						"  uint        cullMask = 0xFF;\n"
2196 						"  float       tmin     = 0.0;\n"
2197 						"  float       tmax     = 9.0;\n"
2198 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
2199 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
2200 						"  uint        value    = -1;\n"
2201 						"  rayQueryEXT rayQuery;\n"
2202 						"\n"
2203 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
2204 						"\n"
2205 						"  if (rayQueryProceedEXT(rayQuery))\n"
2206 						"  {\n"
2207 						"    value--;\n"
2208 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
2209 						"    {\n"
2210 						"      value--;\n"
2211 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
2212 						"\n"
2213 						"      rayQueryProceedEXT(rayQuery);\n"
2214 						"\n"
2215 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
2216 						"        value = rayQueryGetIntersectionPrimitiveIndexEXT(rayQuery, true);\n"
2217 						"    }\n"
2218 						"  }\n"
2219 						"\n"
2220 						"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2221 
2222 					return result;
2223 				}
2224 				else
2225 				{
2226 					TCU_THROW(InternalError, "Unknown geometry type");
2227 				}
2228 			}
2229 
2230 			class TestConfigurationGetRayTMin : public TestConfiguration
2231 			{
2232 			public:
TestConfigurationGetRayTMin(Context & context)2233 				TestConfigurationGetRayTMin (Context& context) : TestConfiguration(context) {}
2234 				static const std::string					getShaderBodyText(const TestParams& testParams);
2235 
2236 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
2237 					VkCommandBuffer					cmdBuffer) override;
2238 			};
2239 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)2240 			const VkAccelerationStructureKHR* TestConfigurationGetRayTMin::initAccelerationStructures(TestParams& testParams, VkCommandBuffer cmdBuffer)
2241 			{
2242 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
2243 				const VkDevice								device = m_testEnvironment->device;
2244 				Allocator&									allocator = *m_testEnvironment->allocator;
2245 				const deUint32								width = testParams.width;
2246 				const deUint32								height = testParams.height;
2247 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
2248 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
2249 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
2250 				const bool									usesTriangles = (testParams.geomType == GEOM_TYPE_TRIANGLES);
2251 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
2252 
2253 				DE_ASSERT(instancesGroupCount == 1);
2254 				DE_ASSERT(geometriesGroupCount == 1);
2255 				DE_ASSERT(squaresGroupCount == width * height);
2256 
2257 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
2258 
2259 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
2260 
2261 				m_expected.resize(width * height);
2262 
2263 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
2264 				{
2265 					de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
2266 
2267 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
2268 					{
2269 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2270 						{
2271 							std::vector<tcu::Vec3> geometryData;
2272 
2273 							const auto squareX = (squareNdx % width);
2274 							const auto squareY = (squareNdx / width);
2275 
2276 							const float x0 = float(squareX + 0) / float(width);
2277 							const float y0 = float(squareY + 0) / float(height);
2278 							const float x1 = float(squareX + 1) / float(width);
2279 							const float y1 = float(squareY + 1) / float(height);
2280 
2281 							if (usesTriangles)
2282 							{
2283 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
2284 								geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
2285 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
2286 
2287 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
2288 								geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
2289 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
2290 							}
2291 							else
2292 							{
2293 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
2294 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
2295 							}
2296 
2297 							rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, usesTriangles);
2298 						}
2299 					}
2300 
2301 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2302 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
2303 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4, instanceNdx + 1);
2304 				}
2305 
2306 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2307 
2308 				for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2309 				{
2310 					const float expected_value = 1.0f + static_cast<float>(squareNdx) / static_cast<float>(squaresGroupCount);
2311 					const auto  expected_value_i32 = static_cast<deInt32>(expected_value * FIXED_POINT_DIVISOR);
2312 
2313 					m_expected.at(squareNdx) = expected_value_i32;
2314 				}
2315 
2316 				return m_topAccelerationStructure.get()->getPtr();
2317 			}
2318 
getShaderBodyText(const TestParams & testParams)2319 			const std::string TestConfigurationGetRayTMin::getShaderBodyText(const TestParams& testParams)
2320 			{
2321 				if (testParams.geomType == GEOM_TYPE_AABBS ||
2322 					testParams.geomType == GEOM_TYPE_TRIANGLES)
2323 				{
2324 					const std::string result =
2325 						"  uint        rayFlags = 0;\n"
2326 						"  uint        cullMask = 0xFF;\n"
2327 						"  float       tmin     = 1.0 + float(pos.y * size.x + pos.x) / float(size.x * size.y);\n"
2328 						"  float       tmax     = 9.0;\n"
2329 						"  vec3        origin   = vec3(0.0, 0.0, -1.0);\n"
2330 						"  vec3        direct   = vec3(0.0, 0.0,  1.0);\n"
2331 						"  rayQueryEXT rayQuery;\n"
2332 						"\n"
2333 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
2334 						"\n"
2335 						"  while (rayQueryProceedEXT(rayQuery))\n"
2336 						"  {\n"
2337 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
2338 						"      {\n"
2339 						"          rayQueryConfirmIntersectionEXT(rayQuery);\n"
2340 						"      }\n"
2341 						"  }\n"
2342 						"\n"
2343 						"  float result_fp32 = rayQueryGetRayTMinEXT(rayQuery);\n"
2344 						"  imageStore(result, pos, ivec4(int(result_fp32 * " + de::toString(FIXED_POINT_DIVISOR) + "), 0, 0, 0));\n";
2345 
2346 					return result;
2347 				}
2348 				else
2349 				{
2350 					TCU_THROW(InternalError, "Unknown geometry type");
2351 				}
2352 			}
2353 
2354 			class TestConfigurationGetWorldRayOrigin : public TestConfigurationVector
2355 			{
2356 			public:
TestConfigurationGetWorldRayOrigin(Context & context)2357 				TestConfigurationGetWorldRayOrigin (Context& context) : TestConfigurationVector(context) {}
2358 				static const std::string					getShaderBodyText(const TestParams& testParams);
2359 
2360 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
2361 					VkCommandBuffer					cmdBuffer) override;
2362 			};
2363 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)2364 			const VkAccelerationStructureKHR* TestConfigurationGetWorldRayOrigin::initAccelerationStructures(TestParams& testParams, VkCommandBuffer cmdBuffer)
2365 			{
2366 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
2367 				const VkDevice								device = m_testEnvironment->device;
2368 				Allocator&									allocator = *m_testEnvironment->allocator;
2369 				const deUint32								width = testParams.width;
2370 				const deUint32								height = testParams.height;
2371 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
2372 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
2373 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
2374 				const bool									usesTriangles = (testParams.geomType == GEOM_TYPE_TRIANGLES);
2375 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
2376 
2377 				DE_ASSERT(instancesGroupCount == 1);
2378 				DE_ASSERT(geometriesGroupCount == 1);
2379 				DE_ASSERT(squaresGroupCount == width * height);
2380 
2381 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
2382 
2383 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
2384 
2385 				m_expected.resize(width * height * 4 /* components */);
2386 
2387 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
2388 				{
2389 					de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
2390 
2391 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
2392 					{
2393 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2394 						{
2395 							std::vector<tcu::Vec3> geometryData;
2396 
2397 							const auto squareX = (squareNdx % width);
2398 							const auto squareY = (squareNdx / width);
2399 
2400 							const float x0 = float(squareX + 0) / float(width);
2401 							const float y0 = float(squareY + 0) / float(height);
2402 							const float x1 = float(squareX + 1) / float(width);
2403 							const float y1 = float(squareY + 1) / float(height);
2404 
2405 							if (usesTriangles)
2406 							{
2407 								geometryData.push_back(tcu::Vec3(x0, y0, -0.2f));
2408 								geometryData.push_back(tcu::Vec3(x0, y1, -0.2f));
2409 								geometryData.push_back(tcu::Vec3(x1, y1, -0.2f));
2410 
2411 								geometryData.push_back(tcu::Vec3(x1, y1, -0.2f));
2412 								geometryData.push_back(tcu::Vec3(x1, y0, -0.2f));
2413 								geometryData.push_back(tcu::Vec3(x0, y0, -0.2f));
2414 							}
2415 							else
2416 							{
2417 								geometryData.push_back(tcu::Vec3(x0, y0, -0.2f));
2418 								geometryData.push_back(tcu::Vec3(x1, y1, -0.2f));
2419 							}
2420 
2421 							rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, usesTriangles);
2422 						}
2423 					}
2424 
2425 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2426 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
2427 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4, instanceNdx + 1);
2428 				}
2429 
2430 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2431 
2432 				for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2433 				{
2434 					const auto squareX = squareNdx % width;
2435 					const auto squareY = squareNdx / width;
2436 
2437 					const float expected_values[3] =
2438 					{
2439 						(float(squareX) + 0.5f)		/ float(width),
2440 						(float(squareY) + 0.5f)		/ float(height),
2441 						float(squareX + squareY)	/ float(width + height),
2442 					};
2443 
2444 					const deInt32 expected_value_i32vec3[3] =
2445 					{
2446 						static_cast<deInt32>(expected_values[0] * FIXED_POINT_DIVISOR),
2447 						static_cast<deInt32>(expected_values[1] * FIXED_POINT_DIVISOR),
2448 						static_cast<deInt32>(expected_values[2] * FIXED_POINT_DIVISOR),
2449 					};
2450 
2451 					/* m_expected data layout is:
2452 					 *
2453 					 * XXXXXXXX ..
2454 					 * YYYYYYYY ..
2455 					 * ZZZZZZZZ ..
2456 					 * WWWWWWWW
2457 					 */
2458 					m_expected.at(0 * squaresGroupCount + squareNdx) = expected_value_i32vec3[0];
2459 					m_expected.at(1 * squaresGroupCount + squareNdx) = expected_value_i32vec3[1];
2460 					m_expected.at(2 * squaresGroupCount + squareNdx) = expected_value_i32vec3[2];
2461 					m_expected.at(3 * squaresGroupCount + squareNdx) = 0;
2462 				}
2463 
2464 				return m_topAccelerationStructure.get()->getPtr();
2465 			}
2466 
getShaderBodyText(const TestParams & testParams)2467 			const std::string TestConfigurationGetWorldRayOrigin::getShaderBodyText(const TestParams& testParams)
2468 			{
2469 				if (testParams.geomType == GEOM_TYPE_AABBS ||
2470 					testParams.geomType == GEOM_TYPE_TRIANGLES)
2471 				{
2472 					const std::string result =
2473 						"  uint        rayFlags = 0;\n"
2474 						"  uint        cullMask = 0xFF;\n"
2475 						"  float       tmin     = 0.00001;\n"
2476 						"  float       tmax     = 9.0;\n"
2477 						"  vec3        origin   = vec3((float(pos.x) + 0.5)/ float(size.x), float(float(pos.y) + 0.5) / float(size.y), float(pos.x + pos.y) / float(size.x + size.y));\n"
2478 						"  vec3        direct   = vec3(0, 0, -1);\n"
2479 						"  rayQueryEXT rayQuery;\n"
2480 						"\n"
2481 						"  bool intersection_found = false;\n"
2482 						"\n"
2483 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
2484 						"\n"
2485 						"  while (rayQueryProceedEXT(rayQuery))\n"
2486 						"  {\n"
2487 						"      intersection_found = true;\n"
2488 						"\n"
2489 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
2490 						"  }\n"
2491 						"\n"
2492 						"  vec3 result_fp32 = (intersection_found) ? rayQueryGetWorldRayOriginEXT(rayQuery)\n"
2493 						"                                          : vec3(1234.0, 5678, 9.0);\n"
2494 						"\n"
2495 						"  imageStore(result, ivec3(pos.xy, 0), ivec4(result_fp32.x * " + de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0) );\n"
2496 						"  imageStore(result, ivec3(pos.xy, 1), ivec4(result_fp32.y * " + de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0) );\n"
2497 						"  imageStore(result, ivec3(pos.xy, 2), ivec4(result_fp32.z * " + de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0) );\n";
2498 
2499 					return result;
2500 				}
2501 				else
2502 				{
2503 					TCU_THROW(InternalError, "Unknown geometry type");
2504 				}
2505 			}
2506 
2507 			class TestConfigurationGetWorldRayDirection : public TestConfigurationVector
2508 			{
2509 			public:
TestConfigurationGetWorldRayDirection(Context & context)2510 				TestConfigurationGetWorldRayDirection (Context& context) : TestConfigurationVector(context) {}
2511 				static const std::string					getShaderBodyText(const TestParams& testParams);
2512 
2513 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
2514 					VkCommandBuffer					cmdBuffer) override;
2515 			};
2516 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)2517 			const VkAccelerationStructureKHR* TestConfigurationGetWorldRayDirection::initAccelerationStructures(TestParams& testParams, VkCommandBuffer cmdBuffer)
2518 			{
2519 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
2520 				const VkDevice								device = m_testEnvironment->device;
2521 				Allocator&									allocator = *m_testEnvironment->allocator;
2522 				const deUint32								width = testParams.width;
2523 				const deUint32								height = testParams.height;
2524 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
2525 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
2526 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
2527 				const bool									usesTriangles = (testParams.geomType == GEOM_TYPE_TRIANGLES);
2528 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
2529 
2530 				DE_ASSERT(instancesGroupCount == 1);
2531 				DE_ASSERT(geometriesGroupCount == 1);
2532 				DE_ASSERT(squaresGroupCount == width * height);
2533 
2534 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
2535 
2536 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
2537 
2538 				m_expected.resize(width * height * 3 /* components in vec3 */);
2539 
2540 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
2541 				{
2542 					de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
2543 
2544 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
2545 					{
2546 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2547 						{
2548 							std::vector<tcu::Vec3> geometryData;
2549 
2550 							const auto squareX = (squareNdx % width);
2551 							const auto squareY = (squareNdx / width);
2552 
2553 							const float x0 = float(squareX + 0) / float(width);
2554 							const float y0 = float(squareY + 0) / float(height);
2555 							const float x1 = float(squareX + 1) / float(width);
2556 							const float y1 = float(squareY + 1) / float(height);
2557 
2558 							if (usesTriangles)
2559 							{
2560 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
2561 								geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
2562 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
2563 
2564 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
2565 								geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
2566 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
2567 							}
2568 							else
2569 							{
2570 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
2571 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
2572 							}
2573 
2574 							rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, usesTriangles);
2575 						}
2576 					}
2577 
2578 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2579 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
2580 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4, instanceNdx + 1);
2581 				}
2582 
2583 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2584 
2585 				const auto normalize = [](const tcu::Vec3& in_vec3)
2586 				{
2587 					const auto distance = deFloatSqrt(in_vec3[0] * in_vec3[0] + in_vec3[1] * in_vec3[1] + in_vec3[2] * in_vec3[2]);
2588 
2589 					return tcu::Vec3(in_vec3[0] / distance, in_vec3[1] / distance, in_vec3[2] / distance);
2590 				};
2591 
2592 				for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2593 				{
2594 					const auto squareX = squareNdx % width;
2595 					const auto squareY = squareNdx / width;
2596 
2597 					const auto origin = tcu::Vec3(0.5f, 0.5f, -1.0f);
2598 					const auto target = tcu::Vec3((float(squareX) + 0.5f) / float(width), (float(squareY) + 0.5f) / float(height), 0.0);
2599 					const auto dir_vector = target - origin;
2600 					const auto dir_vector_normalized = normalize(dir_vector);
2601 
2602 					const deInt32 expected_value_i32vec3[3] =
2603 					{
2604 						static_cast<deInt32>(dir_vector_normalized[0] * FIXED_POINT_DIVISOR),
2605 						static_cast<deInt32>(dir_vector_normalized[1] * FIXED_POINT_DIVISOR),
2606 						static_cast<deInt32>(dir_vector_normalized[2] * FIXED_POINT_DIVISOR),
2607 					};
2608 
2609 					/* Data layout for m_expected is:
2610 					 *
2611 					 * XXXX...XX
2612 					 * YYYY...YY
2613 					 * ZZZZ...ZZ
2614 					 * WWWW...WW
2615 					 */
2616 					m_expected.at(0 * squaresGroupCount + squareNdx) = expected_value_i32vec3[0];
2617 					m_expected.at(1 * squaresGroupCount + squareNdx) = expected_value_i32vec3[1];
2618 					m_expected.at(2 * squaresGroupCount + squareNdx) = expected_value_i32vec3[2];
2619 				}
2620 
2621 				return m_topAccelerationStructure.get()->getPtr();
2622 			}
2623 
getShaderBodyText(const TestParams & testParams)2624 			const std::string TestConfigurationGetWorldRayDirection::getShaderBodyText(const TestParams& testParams)
2625 			{
2626 				if (testParams.geomType == GEOM_TYPE_AABBS ||
2627 					testParams.geomType == GEOM_TYPE_TRIANGLES)
2628 				{
2629 					const std::string result =
2630 						"  uint        rayFlags = 0;\n"
2631 						"  uint        cullMask = 0xFF;\n"
2632 						"  float       tmin     = 0.00001;\n"
2633 						"  float       tmax     = 9.0;\n"
2634 						"  vec3        origin   = vec3(0.5, 0.5, -1.0);\n"
2635 						"  vec3        target   = vec3(float(float(pos.x) + 0.5) / float(size.x), float(float(pos.y) + 0.5) / float(size.y), 0.0);\n"
2636 						"  vec3        direct   = normalize(target - origin);\n"
2637 						"  rayQueryEXT rayQuery;\n"
2638 						"\n"
2639 						"  bool intersection_found = false;\n"
2640 						"\n"
2641 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
2642 						"\n"
2643 						"  while (rayQueryProceedEXT(rayQuery))\n"
2644 						"  {\n"
2645 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
2646 						"\n"
2647 						"      intersection_found = true;\n"
2648 						"  }\n"
2649 						"\n"
2650 						"  vec3 result_fp32 = (intersection_found) ? rayQueryGetWorldRayDirectionEXT(rayQuery)\n"
2651 						"                                          : vec3(1234.0, 5678.0, 9.0);\n"
2652 						"\n"
2653 						"  imageStore(result, ivec3(pos.xy, 0), ivec4(result_fp32.x * " + de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0) );\n"
2654 						"  imageStore(result, ivec3(pos.xy, 1), ivec4(result_fp32.y * " + de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0) );\n"
2655 						"  imageStore(result, ivec3(pos.xy, 2), ivec4(result_fp32.z * " + de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0) );\n";
2656 
2657 					return result;
2658 				}
2659 				else
2660 				{
2661 					TCU_THROW(InternalError, "Unknown geometry type");
2662 				}
2663 			}
2664 
2665 			class TestConfigurationInstanceId : public TestConfiguration
2666 			{
2667 			public:
TestConfigurationInstanceId(Context & context)2668 				TestConfigurationInstanceId (Context& context) : TestConfiguration(context) {}
2669 				static const std::string					getShaderBodyText(const TestParams& testParams);
2670 
2671 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
2672 					VkCommandBuffer					cmdBuffer) override;
2673 			};
2674 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)2675 			const VkAccelerationStructureKHR* TestConfigurationInstanceId::initAccelerationStructures(TestParams& testParams,
2676 				VkCommandBuffer	cmdBuffer)
2677 			{
2678 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
2679 				const VkDevice								device = m_testEnvironment->device;
2680 				Allocator&									allocator = *m_testEnvironment->allocator;
2681 				const deUint32								width = testParams.width;
2682 				const deUint32								height = testParams.height;
2683 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
2684 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
2685 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
2686 				const bool									triangles = (testParams.geomType == GEOM_TYPE_TRIANGLES);
2687 				const float									z = -1.0f;
2688 				tcu::UVec2									startPos = tcu::UVec2(0, 0);
2689 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
2690 
2691 				DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
2692 
2693 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
2694 
2695 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
2696 
2697 				m_expected.resize(width * height);
2698 
2699 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
2700 				{
2701 					de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
2702 
2703 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
2704 					{
2705 						std::vector<tcu::Vec3>	geometryData;
2706 
2707 						geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
2708 
2709 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2710 						{
2711 							const deUint32	n = width * startPos.y() + startPos.x();
2712 							const deUint32	m = (n + 11) % (width * height);
2713 							const float		x0 = float(startPos.x() + 0) / float(width);
2714 							const float		y0 = float(startPos.y() + 0) / float(height);
2715 							const float		x1 = float(startPos.x() + 1) / float(width);
2716 							const float		y1 = float(startPos.y() + 1) / float(height);
2717 
2718 							m_expected[n] = instanceNdx;
2719 
2720 							if (triangles)
2721 							{
2722 								const float	xm = (x0 + x1) / 2.0f;
2723 								const float	ym = (y0 + y1) / 2.0f;
2724 
2725 								geometryData.push_back(tcu::Vec3(x0, y0, z));
2726 								geometryData.push_back(tcu::Vec3(xm, y1, z));
2727 								geometryData.push_back(tcu::Vec3(x1, ym, z));
2728 							}
2729 							else
2730 							{
2731 								geometryData.push_back(tcu::Vec3(x0, y0, z));
2732 								geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
2733 							}
2734 
2735 							startPos.y() = m / width;
2736 							startPos.x() = m % width;
2737 						}
2738 
2739 						rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
2740 					}
2741 
2742 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2743 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
2744 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4, instanceNdx + 1);
2745 				}
2746 
2747 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2748 
2749 				return m_topAccelerationStructure.get()->getPtr();
2750 			}
2751 
getShaderBodyText(const TestParams & testParams)2752 			const std::string TestConfigurationInstanceId::getShaderBodyText(const TestParams& testParams)
2753 			{
2754 				if (testParams.geomType == GEOM_TYPE_AABBS)
2755 				{
2756 					const std::string result =
2757 						"  uint        rayFlags = 0;\n"
2758 						"  uint        cullMask = 0xFF;\n"
2759 						"  float       tmin     = 0.0;\n"
2760 						"  float       tmax     = 9.0;\n"
2761 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
2762 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
2763 						"  uint        value    = -1;\n"
2764 						"  rayQueryEXT rayQuery;\n"
2765 						"\n"
2766 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
2767 						"\n"
2768 						"  if (rayQueryProceedEXT(rayQuery))\n"
2769 						"  {\n"
2770 						"    value--;\n"
2771 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
2772 						"    {\n"
2773 						"      value--;\n"
2774 						"      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n"
2775 						"\n"
2776 						"      rayQueryProceedEXT(rayQuery);\n"
2777 						"\n"
2778 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
2779 						"        value = rayQueryGetIntersectionInstanceIdEXT(rayQuery, true);\n"
2780 						"    }\n"
2781 						"  }\n"
2782 						"\n"
2783 						"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2784 
2785 					return result;
2786 				}
2787 				else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
2788 				{
2789 					const std::string result =
2790 						"  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
2791 						"  uint        cullMask = 0xFF;\n"
2792 						"  float       tmin     = 0.0;\n"
2793 						"  float       tmax     = 9.0;\n"
2794 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
2795 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
2796 						"  uint        value    = -1;\n"
2797 						"  rayQueryEXT rayQuery;\n"
2798 						"\n"
2799 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
2800 						"\n"
2801 						"  if (rayQueryProceedEXT(rayQuery))\n"
2802 						"  {\n"
2803 						"    value--;\n"
2804 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
2805 						"    {\n"
2806 						"      value--;\n"
2807 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
2808 						"\n"
2809 						"      rayQueryProceedEXT(rayQuery);\n"
2810 						"\n"
2811 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
2812 						"        value = rayQueryGetIntersectionInstanceIdEXT(rayQuery, true);\n"
2813 						"    }\n"
2814 						"  }\n"
2815 						"\n"
2816 						"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2817 
2818 					return result;
2819 				}
2820 				else
2821 				{
2822 					TCU_THROW(InternalError, "Unknown geometry type");
2823 				}
2824 			}
2825 
2826 			class TestConfigurationInstanceCustomIndex : public TestConfiguration
2827 			{
2828 			public:
TestConfigurationInstanceCustomIndex(Context & context)2829 				TestConfigurationInstanceCustomIndex (Context& context) : TestConfiguration(context) {}
2830 				static const std::string					getShaderBodyText(const TestParams& testParams);
2831 
2832 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
2833 					VkCommandBuffer					cmdBuffer) override;
2834 			};
2835 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)2836 			const VkAccelerationStructureKHR* TestConfigurationInstanceCustomIndex::initAccelerationStructures(TestParams& testParams,
2837 				VkCommandBuffer	cmdBuffer)
2838 			{
2839 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
2840 				const VkDevice								device = m_testEnvironment->device;
2841 				Allocator&									allocator = *m_testEnvironment->allocator;
2842 				const deUint32								width = testParams.width;
2843 				const deUint32								height = testParams.height;
2844 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
2845 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
2846 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
2847 				const bool									triangles = (testParams.geomType == GEOM_TYPE_TRIANGLES);
2848 				const float									z = -1.0f;
2849 				tcu::UVec2									startPos = tcu::UVec2(0, 0);
2850 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
2851 
2852 				DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
2853 
2854 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
2855 
2856 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
2857 
2858 				m_expected.resize(width * height);
2859 
2860 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
2861 				{
2862 					de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
2863 
2864 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
2865 					{
2866 						std::vector<tcu::Vec3>	geometryData;
2867 
2868 						geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
2869 
2870 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
2871 						{
2872 							const deUint32	n = width * startPos.y() + startPos.x();
2873 							const deUint32	m = (n + 11) % (width * height);
2874 							const float		x0 = float(startPos.x() + 0) / float(width);
2875 							const float		y0 = float(startPos.y() + 0) / float(height);
2876 							const float		x1 = float(startPos.x() + 1) / float(width);
2877 							const float		y1 = float(startPos.y() + 1) / float(height);
2878 
2879 							m_expected[n] = instanceNdx + 1;
2880 
2881 							if (triangles)
2882 							{
2883 								const float	xm = (x0 + x1) / 2.0f;
2884 								const float	ym = (y0 + y1) / 2.0f;
2885 
2886 								geometryData.push_back(tcu::Vec3(x0, y0, z));
2887 								geometryData.push_back(tcu::Vec3(xm, y1, z));
2888 								geometryData.push_back(tcu::Vec3(x1, ym, z));
2889 							}
2890 							else
2891 							{
2892 								geometryData.push_back(tcu::Vec3(x0, y0, z));
2893 								geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
2894 							}
2895 
2896 							startPos.y() = m / width;
2897 							startPos.x() = m % width;
2898 						}
2899 
2900 						rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
2901 					}
2902 
2903 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2904 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
2905 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4, instanceNdx + 1);
2906 				}
2907 
2908 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
2909 
2910 				return m_topAccelerationStructure.get()->getPtr();
2911 			}
2912 
getShaderBodyText(const TestParams & testParams)2913 			const std::string TestConfigurationInstanceCustomIndex::getShaderBodyText(const TestParams& testParams)
2914 			{
2915 				if (testParams.geomType == GEOM_TYPE_AABBS)
2916 				{
2917 					const std::string result =
2918 						"  uint        rayFlags = 0;\n"
2919 						"  uint        cullMask = 0xFF;\n"
2920 						"  float       tmin     = 0.0;\n"
2921 						"  float       tmax     = 9.0;\n"
2922 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
2923 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
2924 						"  uint        value    = -1;\n"
2925 						"  rayQueryEXT rayQuery;\n"
2926 						"\n"
2927 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
2928 						"\n"
2929 						"  if (rayQueryProceedEXT(rayQuery))\n"
2930 						"  {\n"
2931 						"    value--;\n"
2932 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
2933 						"    {\n"
2934 						"      value--;\n"
2935 						"      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n"
2936 						"\n"
2937 						"      rayQueryProceedEXT(rayQuery);\n"
2938 						"\n"
2939 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
2940 						"        value = rayQueryGetIntersectionInstanceCustomIndexEXT(rayQuery, true);\n"
2941 						"    }\n"
2942 						"  }\n"
2943 						"\n"
2944 						"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2945 
2946 					return result;
2947 				}
2948 				else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
2949 				{
2950 					const std::string result =
2951 						"  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
2952 						"  uint        cullMask = 0xFF;\n"
2953 						"  float       tmin     = 0.0;\n"
2954 						"  float       tmax     = 9.0;\n"
2955 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
2956 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
2957 						"  uint        value    = -1;\n"
2958 						"  rayQueryEXT rayQuery;\n"
2959 						"\n"
2960 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
2961 						"\n"
2962 						"  if (rayQueryProceedEXT(rayQuery))\n"
2963 						"  {\n"
2964 						"    value--;\n"
2965 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
2966 						"    {\n"
2967 						"      value--;\n"
2968 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
2969 						"\n"
2970 						"      rayQueryProceedEXT(rayQuery);\n"
2971 						"\n"
2972 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
2973 						"        value = rayQueryGetIntersectionInstanceCustomIndexEXT(rayQuery, true);\n"
2974 						"    }\n"
2975 						"  }\n"
2976 						"\n"
2977 						"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2978 
2979 					return result;
2980 				}
2981 				else
2982 				{
2983 					TCU_THROW(InternalError, "Unknown geometry type");
2984 				}
2985 			}
2986 
2987 			class TestConfigurationIntersectionT : public TestConfigurationFloat
2988 			{
2989 			public:
TestConfigurationIntersectionT(Context & context)2990 				TestConfigurationIntersectionT (Context& context) : TestConfigurationFloat(context) {}
2991 				static const std::string					getShaderBodyText(const TestParams& testParams);
2992 
2993 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
2994 					VkCommandBuffer					cmdBuffer) override;
2995 			};
2996 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)2997 			const VkAccelerationStructureKHR* TestConfigurationIntersectionT::initAccelerationStructures(TestParams& testParams,
2998 				VkCommandBuffer	cmdBuffer)
2999 			{
3000 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
3001 				const VkDevice								device = m_testEnvironment->device;
3002 				Allocator&									allocator = *m_testEnvironment->allocator;
3003 				const deUint32								width = testParams.width;
3004 				const deUint32								height = testParams.height;
3005 				const bool									triangles = (testParams.geomType == GEOM_TYPE_TRIANGLES);
3006 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
3007 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
3008 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
3009 				tcu::UVec2									startPos = tcu::UVec2(0, 0);
3010 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
3011 
3012 				DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
3013 
3014 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
3015 
3016 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
3017 
3018 				m_expected.resize(width * height);
3019 
3020 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
3021 				{
3022 					de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
3023 
3024 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
3025 					{
3026 						std::vector<tcu::Vec3>	geometryData;
3027 
3028 						geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
3029 
3030 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
3031 						{
3032 							const deUint32	n = width * startPos.y() + startPos.x();
3033 							const deUint32	m = (n + 11) % (width * height);
3034 							const float		x0 = float(startPos.x() + 0) / float(width);
3035 							const float		y0 = float(startPos.y() + 0) / float(height);
3036 							const float		x1 = float(startPos.x() + 1) / float(width);
3037 							const float		y1 = float(startPos.y() + 1) / float(height);
3038 							const float		eps = 1.0f / float(FIXED_POINT_DIVISOR);
3039 							const float		z = -deFloatAbs(eps + float(startPos.x()) * float(startPos.y()) / float(width * height));
3040 
3041 							m_expected[n] = -int(z * FIXED_POINT_DIVISOR);
3042 
3043 							if (triangles)
3044 							{
3045 								const float	xm = (x0 + x1) / 2.0f;
3046 								const float	ym = (y0 + y1) / 2.0f;
3047 
3048 								geometryData.push_back(tcu::Vec3(x0, y0, z));
3049 								geometryData.push_back(tcu::Vec3(xm, y1, z));
3050 								geometryData.push_back(tcu::Vec3(x1, ym, z));
3051 
3052 							}
3053 							else
3054 							{
3055 								geometryData.push_back(tcu::Vec3(x0, y0, z));
3056 								geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
3057 							}
3058 
3059 							startPos.y() = m / width;
3060 							startPos.x() = m % width;
3061 						}
3062 
3063 						rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
3064 					}
3065 
3066 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3067 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
3068 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4);
3069 				}
3070 
3071 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3072 
3073 				return m_topAccelerationStructure.get()->getPtr();
3074 			}
3075 
getShaderBodyText(const TestParams & testParams)3076 			const std::string TestConfigurationIntersectionT::getShaderBodyText(const TestParams& testParams)
3077 			{
3078 				if (testParams.geomType == GEOM_TYPE_AABBS)
3079 				{
3080 					const std::string result =
3081 						"  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) + ";\n"
3082 						"  uint        rayFlags = 0;\n"
3083 						"  uint        cullMask = 0xFF;\n"
3084 						"  float       tmin     = 0.0;\n"
3085 						"  float       tmax     = 9.0;\n"
3086 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
3087 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3088 						"  int         value    = -k;\n"
3089 						"  const float t        = abs(float(pos.x * pos.y) / float (size.x * size.y));\n"
3090 						"  rayQueryEXT rayQuery;\n"
3091 						"\n"
3092 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
3093 						"\n"
3094 						"  if (rayQueryProceedEXT(rayQuery))\n"
3095 						"  {\n"
3096 						"    value -= k;\n"
3097 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
3098 						"    {\n"
3099 						"      value -= k;\n"
3100 						"      rayQueryGenerateIntersectionEXT(rayQuery, t);\n"
3101 						"\n"
3102 						"      rayQueryProceedEXT(rayQuery);\n"
3103 						"\n"
3104 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
3105 						"        value = int(k * rayQueryGetIntersectionTEXT(rayQuery, true));\n"
3106 						"    }\n"
3107 						"  }\n"
3108 						"\n"
3109 						"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
3110 
3111 					return result;
3112 				}
3113 				else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
3114 				{
3115 					const std::string result =
3116 						"  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) + ";\n"
3117 						"  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
3118 						"  uint        cullMask = 0xFF;\n"
3119 						"  float       tmin     = 0.0;\n"
3120 						"  float       tmax     = 9.0;\n"
3121 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
3122 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3123 						"  int         value    = -k;\n"
3124 						"  rayQueryEXT rayQuery;\n"
3125 						"\n"
3126 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
3127 						"\n"
3128 						"  if (rayQueryProceedEXT(rayQuery))\n"
3129 						"  {\n"
3130 						"    value -= k;\n"
3131 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
3132 						"    {\n"
3133 						"      value -= k;\n"
3134 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
3135 						"\n"
3136 						"      rayQueryProceedEXT(rayQuery);\n"
3137 						"\n"
3138 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
3139 						"        value = int(k * rayQueryGetIntersectionTEXT(rayQuery, true));\n"
3140 						"    }\n"
3141 						"  }\n"
3142 						"\n"
3143 						"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
3144 
3145 					return result;
3146 				}
3147 				else
3148 				{
3149 					TCU_THROW(InternalError, "Unknown geometry type");
3150 				}
3151 			}
3152 
3153 			class TestConfigurationObjectRayOrigin : public TestConfigurationVector
3154 			{
3155 			public:
TestConfigurationObjectRayOrigin(Context & context)3156 				TestConfigurationObjectRayOrigin (Context& context) : TestConfigurationVector(context) {}
3157 				static const std::string					getShaderBodyText(const TestParams& testParams);
3158 
3159 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
3160 					VkCommandBuffer					cmdBuffer) override;
3161 			};
3162 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)3163 			const VkAccelerationStructureKHR* TestConfigurationObjectRayOrigin::initAccelerationStructures(TestParams& testParams,
3164 				VkCommandBuffer	cmdBuffer)
3165 			{
3166 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
3167 				const VkDevice								device = m_testEnvironment->device;
3168 				Allocator&									allocator = *m_testEnvironment->allocator;
3169 				const deUint32								width = testParams.width;
3170 				const deUint32								height = testParams.height;
3171 				const deUint32								depth = testParams.depth;
3172 				const bool									triangles = (testParams.geomType == GEOM_TYPE_TRIANGLES);
3173 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
3174 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
3175 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
3176 				const float									z = -1.0f;
3177 				tcu::UVec2									startPos = tcu::UVec2(0, 0);
3178 				deUint32									pos = 0;
3179 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
3180 
3181 				DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
3182 
3183 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
3184 
3185 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
3186 
3187 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
3188 				{
3189 					de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
3190 
3191 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
3192 					{
3193 						std::vector<tcu::Vec3>	geometryData;
3194 
3195 						geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
3196 
3197 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
3198 						{
3199 							const deUint32	n = width * startPos.y() + startPos.x();
3200 							const deUint32	m = (n + 11) % (width * height);
3201 							const float		x0 = float(startPos.x() + 0) / float(width);
3202 							const float		y0 = float(startPos.y() + 0) / float(height);
3203 							const float		x1 = float(startPos.x() + 1) / float(width);
3204 							const float		y1 = float(startPos.y() + 1) / float(height);
3205 
3206 							if (triangles)
3207 							{
3208 								const float	xm = (x0 + x1) / 2.0f;
3209 								const float	ym = (y0 + y1) / 2.0f;
3210 
3211 								geometryData.push_back(tcu::Vec3(x0, y0, z));
3212 								geometryData.push_back(tcu::Vec3(xm, y1, z));
3213 								geometryData.push_back(tcu::Vec3(x1, ym, z));
3214 
3215 							}
3216 							else
3217 							{
3218 								geometryData.push_back(tcu::Vec3(x0, y0, z));
3219 								geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
3220 							}
3221 
3222 							startPos.y() = m / width;
3223 							startPos.x() = m % width;
3224 						}
3225 
3226 						rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
3227 					}
3228 
3229 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3230 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
3231 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4);
3232 				}
3233 
3234 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3235 
3236 				m_expected.resize(width * height * depth);
3237 				for (deUint32 y = 0; y < height; ++y)
3238 					for (deUint32 x = 0; x < width; ++x)
3239 						m_expected[pos++] = int(float(FIXED_POINT_DIVISOR) * (0.5f + float(x)) / float(width));
3240 
3241 				for (deUint32 y = 0; y < height; ++y)
3242 					for (deUint32 x = 0; x < width; ++x)
3243 						m_expected[pos++] = int(float(FIXED_POINT_DIVISOR) * (0.5f + float(y)) / float(height));
3244 
3245 				for (deUint32 y = 0; y < height; ++y)
3246 					for (deUint32 x = 0; x < width; ++x)
3247 						m_expected[pos++] = 0;
3248 
3249 				return m_topAccelerationStructure.get()->getPtr();
3250 			}
3251 
getShaderBodyText(const TestParams & testParams)3252 			const std::string TestConfigurationObjectRayOrigin::getShaderBodyText(const TestParams& testParams)
3253 			{
3254 				if (testParams.geomType == GEOM_TYPE_AABBS)
3255 				{
3256 					const std::string result =
3257 						"  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) + ";\n"
3258 						"  uint        rayFlags = 0;\n"
3259 						"  uint        cullMask = 0xFF;\n"
3260 						"  float       tmin     = 0.0;\n"
3261 						"  float       tmax     = 9.0;\n"
3262 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
3263 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3264 						"  ivec3       value    = ivec3(-k);\n"
3265 						"  const float t        = abs(float(pos.x * pos.y) / float (size.x * size.y));\n"
3266 						"  rayQueryEXT rayQuery;\n"
3267 						"\n"
3268 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
3269 						"\n"
3270 						"  if (rayQueryProceedEXT(rayQuery))\n"
3271 						"  {\n"
3272 						"    value -= ivec3(k);\n"
3273 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
3274 						"    {\n"
3275 						"      value -= ivec3(k);\n"
3276 						"      rayQueryGenerateIntersectionEXT(rayQuery, t);\n"
3277 						"\n"
3278 						"      rayQueryProceedEXT(rayQuery);\n"
3279 						"\n"
3280 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
3281 						"        value = ivec3(k * rayQueryGetIntersectionObjectRayOriginEXT(rayQuery, true));\n"
3282 						"    }\n"
3283 						"  }\n"
3284 						"\n"
3285 						"  imageStore(result, ivec3(pos.x, pos.y, 0), ivec4(value.x, 0, 0, 0));\n"
3286 						"  imageStore(result, ivec3(pos.x, pos.y, 1), ivec4(value.y, 0, 0, 0));\n"
3287 						"  imageStore(result, ivec3(pos.x, pos.y, 2), ivec4(value.z, 0, 0, 0));\n";
3288 
3289 					return result;
3290 				}
3291 				else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
3292 				{
3293 					const std::string result =
3294 						"  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) + ";\n"
3295 						"  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
3296 						"  uint        cullMask = 0xFF;\n"
3297 						"  float       tmin     = 0.0;\n"
3298 						"  float       tmax     = 9.0;\n"
3299 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
3300 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3301 						"  ivec3       value    = ivec3(-k);\n"
3302 						"  rayQueryEXT rayQuery;\n"
3303 						"\n"
3304 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
3305 						"\n"
3306 						"  if (rayQueryProceedEXT(rayQuery))\n"
3307 						"  {\n"
3308 						"    value -= ivec3(k);\n"
3309 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
3310 						"    {\n"
3311 						"      value -= ivec3(k);\n"
3312 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
3313 						"\n"
3314 						"      rayQueryProceedEXT(rayQuery);\n"
3315 						"\n"
3316 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
3317 						"        value = ivec3(k * rayQueryGetIntersectionObjectRayOriginEXT(rayQuery, true));\n"
3318 						"    }\n"
3319 						"  }\n"
3320 						"\n"
3321 						"  imageStore(result, ivec3(pos.x, pos.y, 0), ivec4(value.x, 0, 0, 0));\n"
3322 						"  imageStore(result, ivec3(pos.x, pos.y, 1), ivec4(value.y, 0, 0, 0));\n"
3323 						"  imageStore(result, ivec3(pos.x, pos.y, 2), ivec4(value.z, 0, 0, 0));\n";
3324 
3325 					return result;
3326 				}
3327 				else
3328 				{
3329 					TCU_THROW(InternalError, "Unknown geometry type");
3330 				}
3331 			}
3332 
3333 			class TestConfigurationObjectRayDirection : public TestConfigurationVector
3334 			{
3335 			public:
TestConfigurationObjectRayDirection(Context & context)3336 				TestConfigurationObjectRayDirection (Context& context) : TestConfigurationVector(context) {}
3337 				static const std::string					getShaderBodyText(const TestParams& testParams);
3338 
3339 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
3340 					VkCommandBuffer					cmdBuffer) override;
3341 			};
3342 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)3343 			const VkAccelerationStructureKHR* TestConfigurationObjectRayDirection::initAccelerationStructures(TestParams& testParams,
3344 				VkCommandBuffer	cmdBuffer)
3345 			{
3346 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
3347 				const VkDevice								device = m_testEnvironment->device;
3348 				Allocator&									allocator = *m_testEnvironment->allocator;
3349 				const deUint32								width = testParams.width;
3350 				const deUint32								height = testParams.height;
3351 				const deUint32								depth = testParams.depth;
3352 				const bool									triangles = (testParams.geomType == GEOM_TYPE_TRIANGLES);
3353 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
3354 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
3355 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
3356 				const float									z = -1.0f;
3357 				tcu::UVec2									startPos = tcu::UVec2(0, 0);
3358 				deUint32									pos = 0;
3359 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
3360 
3361 				DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
3362 
3363 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
3364 
3365 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
3366 
3367 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
3368 				{
3369 					de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
3370 
3371 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
3372 					{
3373 						std::vector<tcu::Vec3>	geometryData;
3374 
3375 						geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
3376 
3377 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
3378 						{
3379 							const deUint32	n = width * startPos.y() + startPos.x();
3380 							const deUint32	m = (n + 11) % (width * height);
3381 							const float		x0 = float(startPos.x() + 0) / float(width);
3382 							const float		y0 = float(startPos.y() + 0) / float(height);
3383 							const float		x1 = float(startPos.x() + 1) / float(width);
3384 							const float		y1 = float(startPos.y() + 1) / float(height);
3385 
3386 							if (triangles)
3387 							{
3388 								const float	xm = (x0 + x1) / 2.0f;
3389 								const float	ym = (y0 + y1) / 2.0f;
3390 
3391 								geometryData.push_back(tcu::Vec3(x0, y0, z));
3392 								geometryData.push_back(tcu::Vec3(xm, y1, z));
3393 								geometryData.push_back(tcu::Vec3(x1, ym, z));
3394 
3395 							}
3396 							else
3397 							{
3398 								geometryData.push_back(tcu::Vec3(x0, y0, z));
3399 								geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
3400 							}
3401 
3402 							startPos.y() = m / width;
3403 							startPos.x() = m % width;
3404 						}
3405 
3406 						rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
3407 					}
3408 
3409 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3410 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
3411 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4);
3412 				}
3413 
3414 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3415 
3416 				m_expected.resize(width * height * depth);
3417 				for (deUint32 y = 0; y < height; ++y)
3418 					for (deUint32 x = 0; x < width; ++x)
3419 						m_expected[pos++] = 0;
3420 
3421 				for (deUint32 y = 0; y < height; ++y)
3422 					for (deUint32 x = 0; x < width; ++x)
3423 						m_expected[pos++] = 0;
3424 
3425 				for (deUint32 y = 0; y < height; ++y)
3426 					for (deUint32 x = 0; x < width; ++x)
3427 						m_expected[pos++] = -static_cast<deInt32>(FIXED_POINT_DIVISOR);
3428 
3429 				return m_topAccelerationStructure.get()->getPtr();
3430 			}
3431 
getShaderBodyText(const TestParams & testParams)3432 			const std::string TestConfigurationObjectRayDirection::getShaderBodyText(const TestParams& testParams)
3433 			{
3434 				if (testParams.geomType == GEOM_TYPE_AABBS)
3435 				{
3436 					const std::string result =
3437 						"  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) + ";\n"
3438 						"  uint        rayFlags = 0;\n"
3439 						"  uint        cullMask = 0xFF;\n"
3440 						"  float       tmin     = 0.0;\n"
3441 						"  float       tmax     = 9.0;\n"
3442 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
3443 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3444 						"  ivec3       value    = ivec3(-k);\n"
3445 						"  const float t        = abs(float(pos.x * pos.y) / float (size.x * size.y));\n"
3446 						"  rayQueryEXT rayQuery;\n"
3447 						"\n"
3448 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
3449 						"\n"
3450 						"  if (rayQueryProceedEXT(rayQuery))\n"
3451 						"  {\n"
3452 						"    value -= ivec3(k);\n"
3453 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
3454 						"    {\n"
3455 						"      value -= ivec3(k);\n"
3456 						"      rayQueryGenerateIntersectionEXT(rayQuery, t);\n"
3457 						"\n"
3458 						"      rayQueryProceedEXT(rayQuery);\n"
3459 						"\n"
3460 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
3461 						"        value = ivec3(k * rayQueryGetIntersectionObjectRayDirectionEXT(rayQuery, true));\n"
3462 						"    }\n"
3463 						"  }\n"
3464 						"\n"
3465 						"  imageStore(result, ivec3(pos.x, pos.y, 0), ivec4(value.x, 0, 0, 0));\n"
3466 						"  imageStore(result, ivec3(pos.x, pos.y, 1), ivec4(value.y, 0, 0, 0));\n"
3467 						"  imageStore(result, ivec3(pos.x, pos.y, 2), ivec4(value.z, 0, 0, 0));\n";
3468 
3469 					return result;
3470 				}
3471 				else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
3472 				{
3473 					const std::string result =
3474 						"  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) + ";\n"
3475 						"  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
3476 						"  uint        cullMask = 0xFF;\n"
3477 						"  float       tmin     = 0.0;\n"
3478 						"  float       tmax     = 9.0;\n"
3479 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
3480 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3481 						"  ivec3       value    = ivec3(-k);\n"
3482 						"  rayQueryEXT rayQuery;\n"
3483 						"\n"
3484 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
3485 						"\n"
3486 						"  if (rayQueryProceedEXT(rayQuery))\n"
3487 						"  {\n"
3488 						"    value -= ivec3(k);\n"
3489 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
3490 						"    {\n"
3491 						"      value -= ivec3(k);\n"
3492 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
3493 						"\n"
3494 						"      rayQueryProceedEXT(rayQuery);\n"
3495 						"\n"
3496 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
3497 						"        value = ivec3(k * rayQueryGetIntersectionObjectRayDirectionEXT(rayQuery, true));\n"
3498 						"    }\n"
3499 						"  }\n"
3500 						"\n"
3501 						"  imageStore(result, ivec3(pos.x, pos.y, 0), ivec4(value.x, 0, 0, 0));\n"
3502 						"  imageStore(result, ivec3(pos.x, pos.y, 1), ivec4(value.y, 0, 0, 0));\n"
3503 						"  imageStore(result, ivec3(pos.x, pos.y, 2), ivec4(value.z, 0, 0, 0));\n";
3504 
3505 					return result;
3506 				}
3507 				else
3508 				{
3509 					TCU_THROW(InternalError, "Unknown geometry type");
3510 				}
3511 			}
3512 
3513 			class TestConfigurationObjectToWorld : public TestConfigurationMatrix
3514 			{
3515 			public:
TestConfigurationObjectToWorld(Context & context)3516 				TestConfigurationObjectToWorld (Context& context) : TestConfigurationMatrix(context) {}
3517 				static const std::string					getShaderBodyText(const TestParams& testParams);
3518 
3519 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
3520 					VkCommandBuffer					cmdBuffer) override;
3521 			};
3522 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)3523 			const VkAccelerationStructureKHR* TestConfigurationObjectToWorld::initAccelerationStructures(TestParams& testParams,
3524 				VkCommandBuffer	cmdBuffer)
3525 			{
3526 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
3527 				const VkDevice								device = m_testEnvironment->device;
3528 				Allocator&									allocator = *m_testEnvironment->allocator;
3529 				const deUint32								width = testParams.width;
3530 				const deUint32								height = testParams.height;
3531 				const bool									triangles = (testParams.geomType == GEOM_TYPE_TRIANGLES);
3532 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
3533 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
3534 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
3535 				const float									z = -1.0f;
3536 				tcu::UVec2									startPos = tcu::UVec2(0, 0);
3537 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
3538 
3539 				DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
3540 
3541 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
3542 
3543 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
3544 
3545 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
3546 				{
3547 					de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
3548 					VkTransformMatrixKHR							transform = identityMatrix3x4;
3549 
3550 					transform.matrix[0][3] = (1.0f / 8.0f) / float(width);
3551 					transform.matrix[1][3] = (1.0f / 16.0f) / float(height);
3552 
3553 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
3554 					{
3555 						std::vector<tcu::Vec3>	geometryData;
3556 
3557 						geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
3558 
3559 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
3560 						{
3561 							const deUint32	n = width * startPos.y() + startPos.x();
3562 							const deUint32	m = (n + 11) % (width * height);
3563 							const float		x0 = float(startPos.x() + 0) / float(width);
3564 							const float		y0 = float(startPos.y() + 0) / float(height);
3565 							const float		x1 = float(startPos.x() + 1) / float(width);
3566 							const float		y1 = float(startPos.y() + 1) / float(height);
3567 
3568 							if (triangles)
3569 							{
3570 								const float	xm = (x0 + x1) / 2.0f;
3571 								const float	ym = (y0 + y1) / 2.0f;
3572 
3573 								geometryData.push_back(tcu::Vec3(x0, y0, z));
3574 								geometryData.push_back(tcu::Vec3(xm, y1, z));
3575 								geometryData.push_back(tcu::Vec3(x1, ym, z));
3576 							}
3577 							else
3578 							{
3579 								geometryData.push_back(tcu::Vec3(x0, y0, z));
3580 								geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
3581 							}
3582 
3583 							startPos.y() = m / width;
3584 							startPos.x() = m % width;
3585 						}
3586 
3587 						rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
3588 					}
3589 
3590 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3591 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
3592 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), transform);
3593 				}
3594 
3595 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3596 
3597 				{
3598 					const deUint32							imageDepth = 4 * 4;
3599 					const int								translateColumnNumber = 3;
3600 					const deUint32							colCount = 4;
3601 					const deUint32							rowCount = 3;
3602 					const deUint32							zStride = height * width;
3603 					const deUint32							expectedFloats = imageDepth * zStride;
3604 					const float								translateX = (+1.0f / 8.0f) / float(width);
3605 					const float								translateY = (+1.0f / 16.0f) / float(height);
3606 					tcu::Matrix<float, rowCount, colCount>	m;
3607 
3608 					m[translateColumnNumber][0] = translateX;
3609 					m[translateColumnNumber][1] = translateY;
3610 
3611 					m_expected.resize(expectedFloats);
3612 
3613 					for (deUint32 y = 0; y < height; ++y)
3614 					{
3615 						for (deUint32 x = 0; x < width; ++x)
3616 						{
3617 							const deUint32	elem0Pos = x + width * y;
3618 
3619 							for (deUint32 rowNdx = 0; rowNdx < rowCount; ++rowNdx)
3620 								for (deUint32 colNdx = 0; colNdx < colCount; ++colNdx)
3621 								{
3622 									const deUint32	zNdx = rowNdx * colCount + colNdx;
3623 									const deUint32	posNdx = elem0Pos + zStride * zNdx;
3624 
3625 									m_expected[posNdx] = static_cast<deInt32>(FIXED_POINT_DIVISOR * m[colNdx][rowNdx]);
3626 								}
3627 						}
3628 					}
3629 				}
3630 
3631 				return m_topAccelerationStructure.get()->getPtr();
3632 			}
3633 
getShaderBodyText(const TestParams & testParams)3634 			const std::string TestConfigurationObjectToWorld::getShaderBodyText(const TestParams& testParams)
3635 			{
3636 				if (testParams.geomType == GEOM_TYPE_AABBS)
3637 				{
3638 					const std::string result =
3639 						"  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) + ";\n"
3640 						"  uint        rayFlags = 0;\n"
3641 						"  uint        cullMask = 0xFF;\n"
3642 						"  float       tmin     = 0.0;\n"
3643 						"  float       tmax     = 9.0;\n"
3644 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
3645 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3646 						"  mat4x3      value    = mat4x3(-k);\n"
3647 						"  const float t        = abs(float(pos.x * pos.y) / float (size.x * size.y));\n"
3648 						"  rayQueryEXT rayQuery;\n"
3649 						"\n"
3650 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
3651 						"\n"
3652 						"  if (rayQueryProceedEXT(rayQuery))\n"
3653 						"  {\n"
3654 						"    value -= mat4x3(k);\n"
3655 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
3656 						"    {\n"
3657 						"      value -= mat4x3(k);\n"
3658 						"      rayQueryGenerateIntersectionEXT(rayQuery, t);\n"
3659 						"\n"
3660 						"      rayQueryProceedEXT(rayQuery);\n"
3661 						"\n"
3662 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
3663 						"        value = mat4x3(k * rayQueryGetIntersectionObjectToWorldEXT(rayQuery, true));\n"
3664 						"    }\n"
3665 						"  }\n"
3666 						"\n"
3667 						"  int ndx = -1;\n"
3668 						"  for (int row = 0; row < 3; row++)\n"
3669 						"  for (int col = 0; col < 4; col++)\n"
3670 						"  {\n"
3671 						"    ndx++;\n"
3672 						"    ivec3 p = ivec3(pos.xy, ndx);\n"
3673 						"    float r = value[col][row];\n"
3674 						"    ivec4 c = ivec4(int(r),0,0,1);\n"
3675 						"    imageStore(result, p, c);\n"
3676 						"  }\n";
3677 
3678 					return result;
3679 				}
3680 				else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
3681 				{
3682 					const std::string result =
3683 						"  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) + ";\n"
3684 						"  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
3685 						"  uint        cullMask = 0xFF;\n"
3686 						"  float       tmin     = 0.0;\n"
3687 						"  float       tmax     = 9.0;\n"
3688 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
3689 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3690 						"  mat4x3      value    = mat4x3(-k);\n"
3691 						"  rayQueryEXT rayQuery;\n"
3692 						"\n"
3693 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
3694 						"\n"
3695 						"  if (rayQueryProceedEXT(rayQuery))\n"
3696 						"  {\n"
3697 						"    value -= mat4x3(k);\n"
3698 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
3699 						"    {\n"
3700 						"      value -= mat4x3(k);\n"
3701 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
3702 						"\n"
3703 						"      rayQueryProceedEXT(rayQuery);\n"
3704 						"\n"
3705 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
3706 						"        value = mat4x3(k * rayQueryGetIntersectionObjectToWorldEXT(rayQuery, true));\n"
3707 						"    }\n"
3708 						"  }\n"
3709 						"\n"
3710 						"  int ndx = -1;\n"
3711 						"  for (int row = 0; row < 3; row++)\n"
3712 						"  for (int col = 0; col < 4; col++)\n"
3713 						"  {\n"
3714 						"    ndx++;\n"
3715 						"    ivec3 p = ivec3(pos.xy, ndx);\n"
3716 						"    float r = value[col][row];\n"
3717 						"    ivec4 c = ivec4(int(r),0,0,1);\n"
3718 						"    imageStore(result, p, c);\n"
3719 						"  }\n";
3720 
3721 					return result;
3722 				}
3723 				else
3724 				{
3725 					TCU_THROW(InternalError, "Unknown geometry type");
3726 				}
3727 			}
3728 
3729 			class TestConfigurationWorldToObject : public TestConfigurationMatrix
3730 			{
3731 			public:
TestConfigurationWorldToObject(Context & context)3732 				TestConfigurationWorldToObject (Context& context) : TestConfigurationMatrix(context) {}
3733 				static const std::string					getShaderBodyText(const TestParams& testParams);
3734 
3735 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
3736 					VkCommandBuffer					cmdBuffer) override;
3737 			};
3738 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)3739 			const VkAccelerationStructureKHR* TestConfigurationWorldToObject::initAccelerationStructures(TestParams& testParams,
3740 				VkCommandBuffer	cmdBuffer)
3741 			{
3742 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
3743 				const VkDevice								device = m_testEnvironment->device;
3744 				Allocator&									allocator = *m_testEnvironment->allocator;
3745 				const deUint32								width = testParams.width;
3746 				const deUint32								height = testParams.height;
3747 				const bool									triangles = (testParams.geomType == GEOM_TYPE_TRIANGLES);
3748 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
3749 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
3750 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
3751 				const float									z = -1.0f;
3752 				tcu::UVec2									startPos = tcu::UVec2(0, 0);
3753 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
3754 
3755 				DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
3756 
3757 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
3758 
3759 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
3760 
3761 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
3762 				{
3763 					de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
3764 					VkTransformMatrixKHR							transform = identityMatrix3x4;
3765 
3766 					transform.matrix[0][3] = (1.0f / 8.0f) / float(width);
3767 					transform.matrix[1][3] = (1.0f / 16.0f) / float(height);
3768 
3769 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
3770 					{
3771 						std::vector<tcu::Vec3>	geometryData;
3772 
3773 						geometryData.reserve(squaresGroupCount * (triangles ? 3u : 2u));
3774 
3775 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
3776 						{
3777 							const deUint32	n = width * startPos.y() + startPos.x();
3778 							const deUint32	m = (n + 11) % (width * height);
3779 							const float		x0 = float(startPos.x() + 0) / float(width);
3780 							const float		y0 = float(startPos.y() + 0) / float(height);
3781 							const float		x1 = float(startPos.x() + 1) / float(width);
3782 							const float		y1 = float(startPos.y() + 1) / float(height);
3783 
3784 							if (triangles)
3785 							{
3786 								const float	xm = (x0 + x1) / 2.0f;
3787 								const float	ym = (y0 + y1) / 2.0f;
3788 
3789 								geometryData.push_back(tcu::Vec3(x0, y0, z));
3790 								geometryData.push_back(tcu::Vec3(xm, y1, z));
3791 								geometryData.push_back(tcu::Vec3(x1, ym, z));
3792 							}
3793 							else
3794 							{
3795 								geometryData.push_back(tcu::Vec3(x0, y0, z));
3796 								geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
3797 							}
3798 
3799 							startPos.y() = m / width;
3800 							startPos.x() = m % width;
3801 						}
3802 
3803 						rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, triangles);
3804 					}
3805 
3806 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3807 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
3808 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), transform);
3809 				}
3810 
3811 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
3812 
3813 				{
3814 					const deUint32							imageDepth = 4 * 4;
3815 					const int								translateColumnNumber = 3;
3816 					const deUint32							colCount = 4;
3817 					const deUint32							rowCount = 3;
3818 					const deUint32							zStride = height * width;
3819 					const deUint32							expectedFloats = imageDepth * zStride;
3820 					const float								translateX = (-1.0f / 8.0f) / float(width);
3821 					const float								translateY = (-1.0f / 16.0f) / float(height);
3822 					tcu::Matrix<float, rowCount, colCount>	m;
3823 
3824 					m[translateColumnNumber][0] = translateX;
3825 					m[translateColumnNumber][1] = translateY;
3826 
3827 					m_expected.resize(expectedFloats);
3828 
3829 					for (deUint32 y = 0; y < height; ++y)
3830 					{
3831 						for (deUint32 x = 0; x < width; ++x)
3832 						{
3833 							const deUint32	elem0Pos = x + width * y;
3834 
3835 							for (deUint32 rowNdx = 0; rowNdx < rowCount; ++rowNdx)
3836 								for (deUint32 colNdx = 0; colNdx < colCount; ++colNdx)
3837 								{
3838 									const deUint32	zNdx = rowNdx * colCount + colNdx;
3839 									const deUint32	posNdx = elem0Pos + zStride * zNdx;
3840 
3841 									m_expected[posNdx] = static_cast<deInt32>(FIXED_POINT_DIVISOR * m[colNdx][rowNdx]);
3842 								}
3843 						}
3844 					}
3845 				}
3846 
3847 				return m_topAccelerationStructure.get()->getPtr();
3848 			}
3849 
getShaderBodyText(const TestParams & testParams)3850 			const std::string TestConfigurationWorldToObject::getShaderBodyText(const TestParams& testParams)
3851 			{
3852 				if (testParams.geomType == GEOM_TYPE_AABBS)
3853 				{
3854 					const std::string result =
3855 						"  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) + ";\n"
3856 						"  uint        rayFlags = 0;\n"
3857 						"  uint        cullMask = 0xFF;\n"
3858 						"  float       tmin     = 0.0;\n"
3859 						"  float       tmax     = 9.0;\n"
3860 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
3861 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3862 						"  mat4x3      value    = mat4x3(-k);\n"
3863 						"  const float t        = abs(float(pos.x * pos.y) / float (size.x * size.y));\n"
3864 						"  rayQueryEXT rayQuery;\n"
3865 						"\n"
3866 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
3867 						"\n"
3868 						"  if (rayQueryProceedEXT(rayQuery))\n"
3869 						"  {\n"
3870 						"    value -= mat4x3(k);\n"
3871 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
3872 						"    {\n"
3873 						"      value -= mat4x3(k);\n"
3874 						"      rayQueryGenerateIntersectionEXT(rayQuery, t);\n"
3875 						"\n"
3876 						"      rayQueryProceedEXT(rayQuery);\n"
3877 						"\n"
3878 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionGeneratedEXT)\n"
3879 						"        value = mat4x3(k * rayQueryGetIntersectionWorldToObjectEXT(rayQuery, true));\n"
3880 						"    }\n"
3881 						"  }\n"
3882 						"\n"
3883 						"  int ndx = -1;\n"
3884 						"  for (int row = 0; row < 3; row++)\n"
3885 						"  for (int col = 0; col < 4; col++)\n"
3886 						"  {\n"
3887 						"    ndx++;\n"
3888 						"    ivec3 p = ivec3(pos.xy, ndx);\n"
3889 						"    float r = value[col][row];\n"
3890 						"    ivec4 c = ivec4(int(r),0,0,1);\n"
3891 						"    imageStore(result, p, c);\n"
3892 						"  }\n";
3893 
3894 					return result;
3895 				}
3896 				else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
3897 				{
3898 					const std::string result =
3899 						"  const int   k        = " + de::toString(FIXED_POINT_DIVISOR) + ";\n"
3900 						"  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
3901 						"  uint        cullMask = 0xFF;\n"
3902 						"  float       tmin     = 0.0;\n"
3903 						"  float       tmax     = 9.0;\n"
3904 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
3905 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
3906 						"  mat4x3      value    = mat4x3(-k);\n"
3907 						"  rayQueryEXT rayQuery;\n"
3908 						"\n"
3909 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
3910 						"\n"
3911 						"  if (rayQueryProceedEXT(rayQuery))\n"
3912 						"  {\n"
3913 						"    value -= mat4x3(k);\n"
3914 						"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
3915 						"    {\n"
3916 						"      value -= mat4x3(k);\n"
3917 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
3918 						"\n"
3919 						"      rayQueryProceedEXT(rayQuery);\n"
3920 						"\n"
3921 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, true) == gl_RayQueryCommittedIntersectionTriangleEXT)\n"
3922 						"        value = mat4x3(k * rayQueryGetIntersectionWorldToObjectEXT(rayQuery, true));\n"
3923 						"    }\n"
3924 						"  }\n"
3925 						"\n"
3926 						"  int ndx = -1;\n"
3927 						"  for (int row = 0; row < 3; row++)\n"
3928 						"  for (int col = 0; col < 4; col++)\n"
3929 						"  {\n"
3930 						"    ndx++;\n"
3931 						"    ivec3 p = ivec3(pos.xy, ndx);\n"
3932 						"    float r = value[col][row];\n"
3933 						"    ivec4 c = ivec4(int(r),0,0,1);\n"
3934 						"    imageStore(result, p, c);\n"
3935 						"  }\n";
3936 
3937 					return result;
3938 				}
3939 				else
3940 				{
3941 					TCU_THROW(InternalError, "Unknown geometry type");
3942 				}
3943 			}
3944 
3945 			class TestConfigurationNullASStruct : public TestConfiguration
3946 			{
3947 			public:
3948 				TestConfigurationNullASStruct(Context& context);
3949 				~TestConfigurationNullASStruct();
3950 
3951 				static const std::string					getShaderBodyText			(const TestParams& testParams);
3952 				static void									checkSupport				(Context& context, const TestParams& testParams);
3953 
3954 				virtual const VkAccelerationStructureKHR*	initAccelerationStructures	(TestParams& testParams, VkCommandBuffer cmdBuffer) override;
3955 			protected:
3956 				void										prepareTestEnvironment		(Context& context);
3957 				Move<VkAccelerationStructureKHR>			m_emptyAccelerationStructure;
3958 
3959 				Move<VkDevice>								m_device;
3960 				de::MovePtr<DeviceDriver>					m_vkd;
3961 				de::MovePtr<SimpleAllocator>				m_allocator;
3962 			};
3963 
TestConfigurationNullASStruct(Context & context)3964 			TestConfigurationNullASStruct::TestConfigurationNullASStruct(Context& context)
3965 				: TestConfiguration(context)
3966 				, m_emptyAccelerationStructure()
3967 				, m_device()
3968 				, m_vkd()
3969 				, m_allocator()
3970 			{
3971 				prepareTestEnvironment(context);
3972 			}
3973 
~TestConfigurationNullASStruct()3974 			TestConfigurationNullASStruct::~TestConfigurationNullASStruct()
3975 			{
3976 			}
3977 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)3978 			const VkAccelerationStructureKHR* TestConfigurationNullASStruct::initAccelerationStructures(TestParams& testParams,
3979 				VkCommandBuffer	cmdBuffer)
3980 			{
3981 				DE_UNREF(cmdBuffer);
3982 
3983 				m_expected = std::vector<deInt32>(testParams.width * testParams.height, 1);
3984 
3985 				return &m_emptyAccelerationStructure.get();
3986 			}
3987 
checkSupport(Context & context,const TestParams & testParams)3988 			void TestConfigurationNullASStruct::checkSupport(Context& context,
3989 				const TestParams& testParams)
3990 			{
3991 				DE_UNREF(testParams);
3992 
3993 				// Check if the physical device supports VK_EXT_robustness2 and the nullDescriptor feature.
3994 				const auto&	vki					= context.getInstanceInterface();
3995 				const auto	physicalDevice		= context.getPhysicalDevice();
3996 				const auto	supportedExtensions	= enumerateDeviceExtensionProperties(vki, physicalDevice, nullptr);
3997 
3998 				if (!isExtensionStructSupported(supportedExtensions, RequiredExtension("VK_EXT_robustness2")))
3999 					TCU_THROW(NotSupportedError, "VK_EXT_robustness2 not supported");
4000 
4001 				VkPhysicalDeviceRobustness2FeaturesEXT	robustness2Features	= initVulkanStructure();
4002 				VkPhysicalDeviceFeatures2				features2			= initVulkanStructure(&robustness2Features);
4003 
4004 				vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
4005 				if (!robustness2Features.nullDescriptor)
4006 					TCU_THROW(NotSupportedError, "VkPhysicalDeviceRobustness2FeaturesEXT::nullDescriptor not supported");
4007 			}
4008 
prepareTestEnvironment(Context & context)4009 			void TestConfigurationNullASStruct::prepareTestEnvironment (Context& context)
4010 			{
4011 				// Check if the physical device supports VK_EXT_robustness2 and the nullDescriptor feature.
4012 				const auto&	vkp					= context.getPlatformInterface();
4013 				const auto&	vki					= context.getInstanceInterface();
4014 				const auto	instance			= context.getInstance();
4015 				const auto	physicalDevice		= context.getPhysicalDevice();
4016 				const auto	queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
4017 				const auto	queuePriority		= 1.0f;
4018 				bool		accelStructSupport	= false;
4019 
4020 				// Add anything that's supported and may be needed, including nullDescriptor.
4021 				VkPhysicalDeviceFeatures2							features2						= initVulkanStructure();
4022 				VkPhysicalDeviceBufferDeviceAddressFeaturesKHR		deviceAddressFeatures			= initVulkanStructure();
4023 				VkPhysicalDeviceAccelerationStructureFeaturesKHR	accelerationStructureFeatures	= initVulkanStructure();
4024 				VkPhysicalDeviceRayQueryFeaturesKHR					rayQueryFeatures				= initVulkanStructure();
4025 				VkPhysicalDeviceRayTracingPipelineFeaturesKHR		raytracingPipelineFeatures		= initVulkanStructure();
4026 				VkPhysicalDeviceRobustness2FeaturesEXT				robustness2Features				= initVulkanStructure();
4027 				std::vector<const char*>							deviceExtensions;
4028 
4029 				if (context.isDeviceFunctionalitySupported("VK_KHR_deferred_host_operations"))
4030 				{
4031 					deviceExtensions.push_back("VK_KHR_deferred_host_operations");
4032 				}
4033 				if (context.isDeviceFunctionalitySupported("VK_KHR_buffer_device_address"))
4034 				{
4035 					deviceAddressFeatures.pNext = features2.pNext;
4036 					features2.pNext = &deviceAddressFeatures;
4037 					deviceExtensions.push_back("VK_KHR_buffer_device_address");
4038 				}
4039 				if (context.isDeviceFunctionalitySupported("VK_KHR_acceleration_structure"))
4040 				{
4041 					accelerationStructureFeatures.pNext = features2.pNext;
4042 					features2.pNext = &accelerationStructureFeatures;
4043 					deviceExtensions.push_back("VK_KHR_acceleration_structure");
4044 					accelStructSupport = true;
4045 				}
4046 
4047 				if (context.isDeviceFunctionalitySupported("VK_KHR_ray_query"))
4048 				{
4049 					rayQueryFeatures.pNext = features2.pNext;
4050 					features2.pNext = &rayQueryFeatures;
4051 					deviceExtensions.push_back("VK_KHR_ray_query");
4052 				}
4053 
4054 				if (context.isDeviceFunctionalitySupported("VK_KHR_ray_tracing_pipeline"))
4055 				{
4056 					raytracingPipelineFeatures.pNext = features2.pNext;
4057 					features2.pNext = &raytracingPipelineFeatures;
4058 					deviceExtensions.push_back("VK_KHR_ray_tracing_pipeline");
4059 				}
4060 
4061 				vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
4062 
4063 				// Add robustness2 features to the chain and make sure robustBufferAccess is consistent with robustBufferAccess2.
4064 				features2.features.robustBufferAccess = VK_FALSE;
4065 				robustness2Features.nullDescriptor = VK_TRUE;
4066 				robustness2Features.pNext = features2.pNext;
4067 				features2.pNext = &robustness2Features;
4068 
4069 				// Add more needed extensions.
4070 				deviceExtensions.push_back("VK_EXT_robustness2");
4071 				if (accelStructSupport)
4072 				{
4073 					// Not promoted yet in Vulkan 1.1.
4074 					deviceExtensions.push_back("VK_EXT_descriptor_indexing");
4075 					deviceExtensions.push_back("VK_KHR_spirv_1_4");
4076 					deviceExtensions.push_back("VK_KHR_shader_float_controls");
4077 				}
4078 
4079 				const VkDeviceQueueCreateInfo queueInfo =
4080 				{
4081 					VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	//	VkStructureType				sType;
4082 					nullptr,									//	const void*					pNext;
4083 					0u,											//	VkDeviceQueueCreateFlags	flags;
4084 					queueFamilyIndex,							//	deUint32					queueFamilyIndex;
4085 					1u,											//	deUint32					queueCount;
4086 					&queuePriority,								//	const float*				pQueuePriorities;
4087 				};
4088 
4089 				const VkDeviceCreateInfo createInfo =
4090 				{
4091 					VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,				//	VkStructureType					sType;
4092 					features2.pNext,									//	const void*						pNext;
4093 					0u,													//	VkDeviceCreateFlags				flags;
4094 					1u,													//	deUint32						queueCreateInfoCount;
4095 					&queueInfo,											//	const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
4096 					0u,													//	deUint32						enabledLayerCount;
4097 					nullptr,											//	const char* const*				ppEnabledLayerNames;
4098 					static_cast<deUint32>(deviceExtensions.size()),		//	deUint32						enabledExtensionCount;
4099 					deviceExtensions.data(),							//	const char* const*				ppEnabledExtensionNames;
4100 					&features2.features,								//	const VkPhysicalDeviceFeatures*	pEnabledFeatures;
4101 				};
4102 
4103 				m_device			= createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki, physicalDevice, &createInfo);
4104 				m_vkd				= de::MovePtr<DeviceDriver>(new DeviceDriver(vkp, instance, m_device.get()));
4105 				const auto queue	= getDeviceQueue(*m_vkd, *m_device, queueFamilyIndex, 0u);
4106 				m_allocator			= de::MovePtr<SimpleAllocator>(new SimpleAllocator(*m_vkd, m_device.get(), getPhysicalDeviceMemoryProperties(vki, physicalDevice)));
4107 
4108 				m_testEnvironment	= de::MovePtr<TestEnvironment>(new TestEnvironment
4109 				{
4110 					&vki,									//	const InstanceInterface*	vki;
4111 					physicalDevice,							//	VkPhysicalDevice			physicalDevice;
4112 					m_vkd.get(),							//	const DeviceInterface*		vkd;
4113 					m_device.get(),							//	VkDevice					device;
4114 					m_allocator.get(),						//	Allocator*					allocator;
4115 					queue,									//	VkQueue						queue;
4116 					queueFamilyIndex,						//	deUint32					queueFamilyIndex;
4117 					&context.getBinaryCollection(),			//	BinaryCollection*			binaryCollection;
4118 					&context.getTestContext().getLog(),		//	tcu::TestLog*				log;
4119 				});
4120 			}
4121 
getShaderBodyText(const TestParams & testParams)4122 			const std::string TestConfigurationNullASStruct::getShaderBodyText(const TestParams& testParams)
4123 			{
4124 				DE_UNREF(testParams);
4125 
4126 				const std::string result =
4127 					"  uint        rayFlags = 0;\n"
4128 					"  uint        cullMask = 0xFF;\n"
4129 					"  float       tmin     = 0.0;\n"
4130 					"  float       tmax     = 9.0;\n"
4131 					"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
4132 					"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
4133 					"  uint        value    = 1;\n"
4134 					"  rayQueryEXT rayQuery;\n"
4135 					"\n"
4136 					"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
4137 					"\n"
4138 					"  if (rayQueryProceedEXT(rayQuery))\n"
4139 					"  {\n"
4140 					"    value++;\n"
4141 					"\n"
4142 					"    rayQueryTerminateEXT(rayQuery);\n"
4143 					"  }\n"
4144 					"\n"
4145 					"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
4146 
4147 				return result;
4148 			}
4149 
4150 			class TestConfigurationGetIntersectionCandidateAABBOpaque : public TestConfiguration
4151 			{
4152 			public:
TestConfigurationGetIntersectionCandidateAABBOpaque(Context & context)4153 				TestConfigurationGetIntersectionCandidateAABBOpaque (Context& context) : TestConfiguration(context) {}
4154 				static const std::string					getShaderBodyText(const TestParams& testParams);
4155 
4156 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
4157 					VkCommandBuffer					cmdBuffer) override;
4158 			};
4159 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)4160 			const VkAccelerationStructureKHR* TestConfigurationGetIntersectionCandidateAABBOpaque::initAccelerationStructures(TestParams& testParams, VkCommandBuffer cmdBuffer)
4161 			{
4162 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
4163 				const VkDevice								device = m_testEnvironment->device;
4164 				Allocator&									allocator = *m_testEnvironment->allocator;
4165 				const deUint32								width = testParams.width;
4166 				const deUint32								height = testParams.height;
4167 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
4168 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
4169 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
4170 				const bool									usesTriangles = (testParams.geomType == GEOM_TYPE_TRIANGLES);
4171 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
4172 
4173 				DE_ASSERT(instancesGroupCount == 1);
4174 				DE_ASSERT(geometriesGroupCount == 1);
4175 				DE_ASSERT(squaresGroupCount == width * height);
4176 
4177 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
4178 
4179 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
4180 
4181 				m_expected.resize(width * height);
4182 
4183 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
4184 				{
4185 					de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
4186 
4187 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
4188 					{
4189 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
4190 						{
4191 							std::vector<tcu::Vec3> geometryData;
4192 
4193 							const auto					squareX = (squareNdx % width);
4194 							const auto					squareY = (squareNdx / width);
4195 							const bool					isOpaque = (squareNdx % 2) == 0;
4196 							const VkGeometryFlagsKHR	flags = (isOpaque) ? VK_GEOMETRY_OPAQUE_BIT_KHR
4197 								: 0;
4198 
4199 							const float x0 = float(squareX + 0) / float(width);
4200 							const float y0 = float(squareY + 0) / float(height);
4201 							const float x1 = float(squareX + 1) / float(width);
4202 							const float y1 = float(squareY + 1) / float(height);
4203 
4204 							if (usesTriangles)
4205 							{
4206 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4207 								geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
4208 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4209 
4210 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4211 								geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
4212 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4213 							}
4214 							else
4215 							{
4216 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4217 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4218 							}
4219 
4220 							rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, usesTriangles, flags);
4221 						}
4222 					}
4223 
4224 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4225 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
4226 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4, instanceNdx + 1);
4227 				}
4228 
4229 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4230 
4231 				for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
4232 				{
4233 					m_expected.at(squareNdx) = (squareNdx % 2) == 0;
4234 				}
4235 
4236 				return m_topAccelerationStructure.get()->getPtr();
4237 			}
4238 
getShaderBodyText(const TestParams & testParams)4239 			const std::string TestConfigurationGetIntersectionCandidateAABBOpaque::getShaderBodyText(const TestParams& testParams)
4240 			{
4241 				if (testParams.geomType == GEOM_TYPE_AABBS ||
4242 					testParams.geomType == GEOM_TYPE_TRIANGLES)
4243 				{
4244 					const std::string result =
4245 						"  uint        rayFlags = 0;\n"
4246 						"  uint        cullMask = 0xFF;\n"
4247 						"  float       tmin     = 0.0001;\n"
4248 						"  float       tmax     = 9.0;\n"
4249 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.2);\n"
4250 						"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
4251 						"  rayQueryEXT rayQuery;\n"
4252 						"\n"
4253 						"  int result_i32 = 0;\n"
4254 						"\n"
4255 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
4256 						"\n"
4257 						"  while (rayQueryProceedEXT(rayQuery))\n"
4258 						"  {\n"
4259 						"      if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
4260 						"      {\n"
4261 						"          result_i32 |= rayQueryGetIntersectionCandidateAABBOpaqueEXT(rayQuery) ? 1 : 0;\n"
4262 						"\n"
4263 						"          rayQueryConfirmIntersectionEXT(rayQuery);\n"
4264 						"      }\n"
4265 						"  }\n"
4266 						"\n"
4267 						"  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
4268 
4269 					return result;
4270 				}
4271 				else
4272 				{
4273 					TCU_THROW(InternalError, "Unknown geometry type");
4274 				}
4275 			}
4276 
4277 			class TestConfigurationGetIntersectionFrontFace : public TestConfiguration
4278 			{
4279 			public:
TestConfigurationGetIntersectionFrontFace(Context & context)4280 				TestConfigurationGetIntersectionFrontFace (Context& context) : TestConfiguration(context) {}
4281 				static const std::string					getShaderBodyTextCandidate(const TestParams& testParams);
4282 				static const std::string					getShaderBodyTextCommitted(const TestParams& testParams);
4283 
4284 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
4285 					VkCommandBuffer					cmdBuffer) override;
4286 			};
4287 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)4288 			const VkAccelerationStructureKHR* TestConfigurationGetIntersectionFrontFace::initAccelerationStructures(TestParams& testParams, VkCommandBuffer cmdBuffer)
4289 			{
4290 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
4291 				const VkDevice								device = m_testEnvironment->device;
4292 				Allocator&									allocator = *m_testEnvironment->allocator;
4293 				const deUint32								width = testParams.width;
4294 				const deUint32								height = testParams.height;
4295 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
4296 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
4297 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
4298 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
4299 
4300 				DE_ASSERT(instancesGroupCount == 1);
4301 				DE_ASSERT(geometriesGroupCount == 1);
4302 				DE_ASSERT(squaresGroupCount == width * height);
4303 
4304 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
4305 
4306 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
4307 
4308 				m_expected.resize(width * height);
4309 
4310 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
4311 				{
4312 					de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
4313 
4314 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
4315 					{
4316 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
4317 						{
4318 							std::vector<tcu::Vec3> geometryData;
4319 
4320 							const auto	squareX = (squareNdx % width);
4321 							const auto	squareY = (squareNdx / width);
4322 
4323 							const float x0 = float(squareX + 0) / float(width);
4324 							const float y0 = float(squareY + 0) / float(height);
4325 							const float x1 = float(squareX + 1) / float(width);
4326 							const float y1 = float(squareY + 1) / float(height);
4327 
4328 							if ((squareNdx % 2) == 0)
4329 							{
4330 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4331 								geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
4332 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4333 
4334 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4335 								geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
4336 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4337 							}
4338 							else
4339 							{
4340 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4341 								geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
4342 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4343 
4344 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4345 								geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
4346 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4347 							}
4348 
4349 							rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, true /* triangles */);
4350 						}
4351 					}
4352 
4353 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4354 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
4355 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4, instanceNdx + 1);
4356 				}
4357 
4358 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4359 
4360 				for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
4361 				{
4362 					m_expected.at(squareNdx) = (squareNdx % 2) != 0;
4363 				}
4364 
4365 				return m_topAccelerationStructure.get()->getPtr();
4366 			}
4367 
getShaderBodyTextCandidate(const TestParams & testParams)4368 			const std::string TestConfigurationGetIntersectionFrontFace::getShaderBodyTextCandidate(const TestParams& testParams)
4369 			{
4370 				if (testParams.geomType == GEOM_TYPE_AABBS ||
4371 					testParams.geomType == GEOM_TYPE_TRIANGLES)
4372 				{
4373 					const std::string result =
4374 						"  uint        rayFlags = 0;\n"
4375 						"  uint        cullMask = 0xFF;\n"
4376 						"  float       tmin     = 0.0001;\n"
4377 						"  float       tmax     = 9.0;\n"
4378 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y),  0.2);\n"
4379 						"  vec3        direct   = vec3(0,									  0,								     -1.0);\n"
4380 						"  rayQueryEXT rayQuery;\n"
4381 						"\n"
4382 						"  int result_i32 = 2;\n"
4383 						"\n"
4384 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
4385 						"\n"
4386 						"  while (rayQueryProceedEXT(rayQuery))\n"
4387 						"  {\n"
4388 						"      result_i32 = rayQueryGetIntersectionFrontFaceEXT(rayQuery, false) ? 1 : 0;\n"
4389 						"\n"
4390 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
4391 						"  }\n"
4392 						"\n"
4393 						"  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
4394 
4395 					return result;
4396 				}
4397 				else
4398 				{
4399 					TCU_THROW(InternalError, "Unknown geometry type");
4400 				}
4401 			}
4402 
getShaderBodyTextCommitted(const TestParams & testParams)4403 			const std::string TestConfigurationGetIntersectionFrontFace::getShaderBodyTextCommitted(const TestParams& testParams)
4404 			{
4405 				if (testParams.geomType == GEOM_TYPE_AABBS ||
4406 					testParams.geomType == GEOM_TYPE_TRIANGLES)
4407 				{
4408 					const std::string result =
4409 						"  uint        rayFlags = 0;\n"
4410 						"  uint        cullMask = 0xFF;\n"
4411 						"  float       tmin     = 0.0001;\n"
4412 						"  float       tmax     = 9.0;\n"
4413 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y),  0.2);\n"
4414 						"  vec3        direct   = vec3(0,									  0,								     -1.0);\n"
4415 						"  rayQueryEXT rayQuery;\n"
4416 						"\n"
4417 						"  bool intersection_found = false;\n"
4418 						"  int  result_i32         = 0;\n"
4419 						"\n"
4420 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
4421 						"\n"
4422 						"  while (rayQueryProceedEXT(rayQuery))\n"
4423 						"  {\n"
4424 						"      intersection_found = true;\n"
4425 						"\n"
4426 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
4427 						"  }\n"
4428 						"\n"
4429 						"  result_i32 = (intersection_found) ? (rayQueryGetIntersectionFrontFaceEXT(rayQuery, true) ? 1 : 0)\n"
4430 						"									 : 2;\n"
4431 						"\n"
4432 						"  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
4433 
4434 					return result;
4435 				}
4436 				else
4437 				{
4438 					TCU_THROW(InternalError, "Unknown geometry type");
4439 				}
4440 			}
4441 
4442 			class TestConfigurationGetIntersectionGeometryIndex : public TestConfiguration
4443 			{
4444 			public:
TestConfigurationGetIntersectionGeometryIndex(Context & context)4445 				TestConfigurationGetIntersectionGeometryIndex (Context& context) : TestConfiguration(context) {}
4446 				static const std::string					getShaderBodyTextCandidate(const TestParams& testParams);
4447 				static const std::string					getShaderBodyTextCommitted(const TestParams& testParams);
4448 
4449 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
4450 					VkCommandBuffer					cmdBuffer) override;
4451 			};
4452 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)4453 			const VkAccelerationStructureKHR* TestConfigurationGetIntersectionGeometryIndex::initAccelerationStructures(TestParams& testParams, VkCommandBuffer cmdBuffer)
4454 			{
4455 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
4456 				const VkDevice								device = m_testEnvironment->device;
4457 				Allocator&									allocator = *m_testEnvironment->allocator;
4458 				const deUint32								width = testParams.width;
4459 				const deUint32								height = testParams.height;
4460 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
4461 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
4462 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
4463 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
4464 
4465 				DE_ASSERT(instancesGroupCount == 1);
4466 				DE_ASSERT(geometriesGroupCount == 1);
4467 				DE_ASSERT(squaresGroupCount == width * height);
4468 
4469 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
4470 
4471 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
4472 
4473 				m_expected.resize(width * height);
4474 
4475 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
4476 				{
4477 					de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
4478 
4479 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
4480 					{
4481 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
4482 						{
4483 							std::vector<tcu::Vec3> geometryData;
4484 
4485 							const auto	squareX = (squareNdx % width);
4486 							const auto	squareY = (squareNdx / width);
4487 
4488 							const float x0 = float(squareX + 0) / float(width);
4489 							const float y0 = float(squareY + 0) / float(height);
4490 							const float x1 = float(squareX + 1) / float(width);
4491 							const float y1 = float(squareY + 1) / float(height);
4492 
4493 							if ((squareNdx % 2) == 0)
4494 							{
4495 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4496 								geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
4497 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4498 
4499 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4500 								geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
4501 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4502 							}
4503 							else
4504 							{
4505 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4506 								geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
4507 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4508 
4509 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4510 								geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
4511 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4512 							}
4513 
4514 							rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, true /* triangles */);
4515 						}
4516 					}
4517 
4518 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4519 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
4520 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4, instanceNdx + 1);
4521 				}
4522 
4523 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4524 
4525 				for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
4526 				{
4527 					m_expected.at(squareNdx) = squareNdx;
4528 				}
4529 
4530 				return m_topAccelerationStructure.get()->getPtr();
4531 			}
4532 
getShaderBodyTextCandidate(const TestParams & testParams)4533 			const std::string TestConfigurationGetIntersectionGeometryIndex::getShaderBodyTextCandidate(const TestParams& testParams)
4534 			{
4535 				if (testParams.geomType == GEOM_TYPE_AABBS ||
4536 					testParams.geomType == GEOM_TYPE_TRIANGLES)
4537 				{
4538 					const std::string result =
4539 						"  uint        rayFlags = 0;\n"
4540 						"  uint        cullMask = 0xFF;\n"
4541 						"  float       tmin     = 0.0001;\n"
4542 						"  float       tmax     = 9.0;\n"
4543 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y),  0.2);\n"
4544 						"  vec3        direct   = vec3(0,									  0,								     -1.0);\n"
4545 						"  rayQueryEXT rayQuery;\n"
4546 						"\n"
4547 						"  int result_i32 = 123456;\n"
4548 						"\n"
4549 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
4550 						"\n"
4551 						"  while (rayQueryProceedEXT(rayQuery))\n"
4552 						"  {\n"
4553 						"      result_i32 = rayQueryGetIntersectionGeometryIndexEXT(rayQuery, false);\n"
4554 						"\n"
4555 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
4556 						"  }\n"
4557 						"\n"
4558 						"  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
4559 
4560 					return result;
4561 				}
4562 				else
4563 				{
4564 					TCU_THROW(InternalError, "Unknown geometry type");
4565 				}
4566 			}
4567 
getShaderBodyTextCommitted(const TestParams & testParams)4568 			const std::string TestConfigurationGetIntersectionGeometryIndex::getShaderBodyTextCommitted(const TestParams& testParams)
4569 			{
4570 				if (testParams.geomType == GEOM_TYPE_AABBS ||
4571 					testParams.geomType == GEOM_TYPE_TRIANGLES)
4572 				{
4573 					const std::string result =
4574 						"  uint        rayFlags = 0;\n"
4575 						"  uint        cullMask = 0xFF;\n"
4576 						"  float       tmin     = 0.0001;\n"
4577 						"  float       tmax     = 9.0;\n"
4578 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y),  0.2);\n"
4579 						"  vec3        direct   = vec3(0,									  0,								     -1.0);\n"
4580 						"  rayQueryEXT rayQuery;\n"
4581 						"\n"
4582 						"  bool intersection_found = false;\n"
4583 						"  int  result_i32         = 0;\n"
4584 						"\n"
4585 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
4586 						"\n"
4587 						"  while (rayQueryProceedEXT(rayQuery))\n"
4588 						"  {\n"
4589 						"      intersection_found = true;\n"
4590 						"\n"
4591 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
4592 						"  }\n"
4593 						"\n"
4594 						"  result_i32 = (intersection_found) ? (rayQueryGetIntersectionGeometryIndexEXT(rayQuery, true) )\n"
4595 						"									 : 2;\n"
4596 						"\n"
4597 						"  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
4598 
4599 					return result;
4600 				}
4601 				else
4602 				{
4603 					TCU_THROW(InternalError, "Unknown geometry type");
4604 				}
4605 			}
4606 
4607 			class TestConfigurationGetIntersectionBarycentrics : public TestConfigurationVector
4608 			{
4609 			public:
TestConfigurationGetIntersectionBarycentrics(Context & context)4610 				TestConfigurationGetIntersectionBarycentrics(Context& context)
4611 					: TestConfigurationVector(context, false)
4612 				{
4613 					/* Stub */
4614 				}
4615 
4616 				static const std::string	getShaderBodyTextCandidate(const TestParams& testParams);
4617 				static const std::string	getShaderBodyTextCommitted(const TestParams& testParams);
4618 
4619 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
4620 					VkCommandBuffer					cmdBuffer) override;
4621 			};
4622 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)4623 			const VkAccelerationStructureKHR* TestConfigurationGetIntersectionBarycentrics::initAccelerationStructures(TestParams& testParams, VkCommandBuffer cmdBuffer)
4624 			{
4625 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
4626 				const VkDevice								device = m_testEnvironment->device;
4627 				Allocator&									allocator = *m_testEnvironment->allocator;
4628 				const deUint32								width = testParams.width;
4629 				const deUint32								height = testParams.height;
4630 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
4631 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
4632 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
4633 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
4634 
4635 				DE_ASSERT(instancesGroupCount == 1);
4636 				DE_ASSERT(geometriesGroupCount == 1);
4637 				DE_ASSERT(squaresGroupCount == width * height);
4638 
4639 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
4640 
4641 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
4642 
4643 				m_expected.resize(width * height * 3);
4644 
4645 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
4646 				{
4647 					de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
4648 
4649 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
4650 					{
4651 						for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
4652 						{
4653 							std::vector<tcu::Vec3> geometryData;
4654 
4655 							const auto	squareX = (squareNdx % width);
4656 							const auto	squareY = (squareNdx / width);
4657 
4658 							const float x0 = float(squareX + 0) / float(width);
4659 							const float y0 = float(squareY + 0) / float(height);
4660 							const float x1 = float(squareX + 1) / float(width);
4661 							const float y1 = float(squareY + 1) / float(height);
4662 
4663 							const float x05 = x0 + (x1 - x0) * 0.5f;
4664 							const float y05 = y0 + (y1 - y0) * 0.5f;
4665 
4666 							geometryData.push_back(tcu::Vec3(x05, y0, 0.0));
4667 							geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
4668 							geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4669 
4670 							/* With each cell, ray target moves from (x1, y1) to (x0.5, y0.5). This guarantees a hit and different barycentric coords
4671 							 * per each traced ray.
4672 							 */
4673 							const float t = float(squareNdx) / float(squaresGroupCount - 1);
4674 
4675 							const float hitX = x0 + 0.125f / float(width) + (x1 - x05) * t;
4676 							const float hitY = y1 - 0.125f / float(height) - (y1 - y05) * t;
4677 
4678 							const float barycentricX = ((0 + (x1 - x0) * (hitY - y1)) / (0 + (x1 - x0) * (y0 - y1)));
4679 							const float barycentricY = (((y1 - y0) * (hitX - x1) + (x05 - x1) * (hitY - y1)) / (0 + (x1 - x0) * (y0 - y1)));
4680 
4681 							m_expected.at(squaresGroupCount * 0 + squareNdx) = static_cast<deInt32>(FIXED_POINT_DIVISOR * barycentricY);
4682 							m_expected.at(squaresGroupCount * 1 + squareNdx) = static_cast<deInt32>(FIXED_POINT_DIVISOR * barycentricX);
4683 							m_expected.at(squaresGroupCount * 2 + squareNdx) = static_cast<deInt32>(FIXED_POINT_DIVISOR * (1.0f - barycentricX - barycentricY));
4684 
4685 							rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, true /* triangles */);
4686 						}
4687 					}
4688 
4689 					rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4690 					m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
4691 					m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4, instanceNdx + 1);
4692 				}
4693 
4694 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4695 
4696 				return m_topAccelerationStructure.get()->getPtr();
4697 			}
4698 
getShaderBodyTextCandidate(const TestParams & testParams)4699 			const std::string TestConfigurationGetIntersectionBarycentrics::getShaderBodyTextCandidate(const TestParams& testParams)
4700 			{
4701 				if (testParams.geomType == GEOM_TYPE_AABBS ||
4702 					testParams.geomType == GEOM_TYPE_TRIANGLES)
4703 				{
4704 					const std::string result =
4705 						"  uint        rayFlags = 0;\n"
4706 						"  uint        cullMask = 0xFF;\n"
4707 						"  float       tmin     = 0.0001;\n"
4708 						"  float       tmax     = 9.0;\n"
4709 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y),  0.2);\n"
4710 						"\n"
4711 						"  int         nSquare = pos.y * size.x + pos.x;\n"
4712 						"  float       t        = float(pos.y * size.x + pos.x) / float(size.x * size.y - 1);\n"
4713 						"  float       x0       = float(pos.x)     / float(size.x);\n"
4714 						"  float       x1       = float(pos.x + 1) / float(size.x);\n"
4715 						"  float       x05      = mix(x0, x1, 0.5);\n"
4716 						"  float       y0       = float(pos.y)     / float(size.y);\n"
4717 						"  float       y1       = float(pos.y + 1) / float(size.y);\n"
4718 						"  float       y05      = mix(y0, y1, 0.5);\n"
4719 						"  vec3        target   = vec3(x0 + 0.125 / float(size.x) + (x1 - x05) * t,\n"
4720 						"                              y1 - 0.125 / float(size.y) - (y1 - y05) * t,\n"
4721 						"                              0.0);\n"
4722 						"  vec3        direct   = normalize(target - origin);\n"
4723 						"\n"
4724 						"  rayQueryEXT rayQuery;\n"
4725 						"\n"
4726 						"  vec2 result_fp32 = vec2(1234, 5678);\n"
4727 						"\n"
4728 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
4729 						"\n"
4730 						"  while (rayQueryProceedEXT(rayQuery))\n"
4731 						"  {\n"
4732 						"      result_fp32 = rayQueryGetIntersectionBarycentricsEXT(rayQuery, false);\n"
4733 						"\n"
4734 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
4735 						"  }\n"
4736 						"\n"
4737 						"  imageStore(result, ivec3(pos.xy, 0), ivec4(result_fp32.x * " + de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0));\n"
4738 						"  imageStore(result, ivec3(pos.xy, 1), ivec4(result_fp32.y * " + de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0));\n"
4739 						"  imageStore(result, ivec3(pos.xy, 2), ivec4((1.0 - result_fp32.x - result_fp32.y) * " + de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0));\n";
4740 
4741 					return result;
4742 				}
4743 				else
4744 				{
4745 					TCU_THROW(InternalError, "Unknown geometry type");
4746 				}
4747 			}
4748 
getShaderBodyTextCommitted(const TestParams & testParams)4749 			const std::string TestConfigurationGetIntersectionBarycentrics::getShaderBodyTextCommitted(const TestParams& testParams)
4750 			{
4751 				if (testParams.geomType == GEOM_TYPE_AABBS ||
4752 					testParams.geomType == GEOM_TYPE_TRIANGLES)
4753 				{
4754 					const std::string result =
4755 						"  uint        rayFlags = 0;\n"
4756 						"  uint        cullMask = 0xFF;\n"
4757 						"  float       tmin     = 0.0001;\n"
4758 						"  float       tmax     = 9.0;\n"
4759 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y),  0.2);\n"
4760 						"\n"
4761 						"  int         nSquare = pos.y * size.x + pos.x;\n"
4762 						"  float       t        = float(pos.y * size.x + pos.x) / float(size.x * size.y - 1);\n"
4763 						"  float       x0       = float(pos.x)     / float(size.x);\n"
4764 						"  float       x1       = float(pos.x + 1) / float(size.x);\n"
4765 						"  float       x05      = mix(x0, x1, 0.5);\n"
4766 						"  float       y0       = float(pos.y)     / float(size.y);\n"
4767 						"  float       y1       = float(pos.y + 1) / float(size.y);\n"
4768 						"  float       y05      = mix(y0, y1, 0.5);\n"
4769 						"  vec3        target   = vec3(x0 + 0.125 / float(size.x) + (x1 - x05) * t,\n"
4770 						"                              y1 - 0.125 / float(size.y) - (y1 - y05) * t,\n"
4771 						"                              0.0);\n"
4772 						"  vec3        direct   = normalize(target - origin);\n"
4773 						"\n"
4774 						"  rayQueryEXT rayQuery;\n"
4775 						"\n"
4776 						"  bool intersection_found = false;\n"
4777 						"  vec2 result_fp32        = vec2(1234, 5678);\n"
4778 						"\n"
4779 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
4780 						"\n"
4781 						"  while (rayQueryProceedEXT(rayQuery))\n"
4782 						"  {\n"
4783 						"      intersection_found = true;\n"
4784 						"\n"
4785 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
4786 						"  }\n"
4787 						"\n"
4788 						"  if (intersection_found)\n"
4789 						"  {\n"
4790 						"    result_fp32 = rayQueryGetIntersectionBarycentricsEXT(rayQuery, true);\n"
4791 						"  }\n"
4792 						"\n"
4793 						"  imageStore(result, ivec3(pos.xy, 0), ivec4(result_fp32.x * " + de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0));\n"
4794 						"  imageStore(result, ivec3(pos.xy, 1), ivec4(result_fp32.y * " + de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0));\n"
4795 						"  imageStore(result, ivec3(pos.xy, 2), ivec4((1.0 - result_fp32.x - result_fp32.y) * " + de::toString(FIXED_POINT_DIVISOR) + ", 0, 0, 0));\n";
4796 
4797 					return result;
4798 				}
4799 				else
4800 				{
4801 					TCU_THROW(InternalError, "Unknown geometry type");
4802 				}
4803 			}
4804 
4805 			/// <summary>
4806 			class TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset : public TestConfiguration
4807 			{
4808 			public:
TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset(Context & context)4809 				TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset (Context& context) : TestConfiguration(context) {}
4810 				static const std::string					getShaderBodyTextCandidate(const TestParams& testParams);
4811 				static const std::string					getShaderBodyTextCommitted(const TestParams& testParams);
4812 
4813 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
4814 					VkCommandBuffer					cmdBuffer) override;
4815 			};
4816 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)4817 			const VkAccelerationStructureKHR* TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset::initAccelerationStructures(TestParams& testParams, VkCommandBuffer cmdBuffer)
4818 			{
4819 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
4820 				const VkDevice								device = m_testEnvironment->device;
4821 				Allocator&									allocator = *m_testEnvironment->allocator;
4822 				const deUint32								width = testParams.width;
4823 				const deUint32								height = testParams.height;
4824 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
4825 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
4826 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
4827 				deUint32									squareNdx = 0;
4828 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
4829 
4830 				DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
4831 
4832 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
4833 
4834 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
4835 
4836 				m_expected.resize(width * height);
4837 
4838 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
4839 				{
4840 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
4841 					{
4842 						for (deUint32 groupNdx = 0; groupNdx < squaresGroupCount; ++groupNdx, ++squareNdx)
4843 						{
4844 							de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
4845 							std::vector<tcu::Vec3>							geometryData;
4846 
4847 							const auto	squareX = (squareNdx % width);
4848 							const auto	squareY = (squareNdx / width);
4849 
4850 							const float x0 = float(squareX + 0) / float(width);
4851 							const float y0 = float(squareY + 0) / float(height);
4852 							const float x1 = float(squareX + 1) / float(width);
4853 							const float y1 = float(squareY + 1) / float(height);
4854 
4855 							if ((squareNdx % 2) == 0)
4856 							{
4857 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4858 								geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
4859 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4860 
4861 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4862 								geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
4863 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4864 							}
4865 							else
4866 							{
4867 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4868 								geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
4869 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4870 
4871 								geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
4872 								geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
4873 								geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
4874 							}
4875 
4876 							m_expected.at(squareNdx) = ((1 << 24) - 1) / static_cast<deUint32>(m_expected.size()) * squareNdx;
4877 
4878 							rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, true /* triangles */);
4879 
4880 							rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4881 							m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
4882 
4883 							m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4, instanceNdx + 1, 255U, m_expected.at(squareNdx));
4884 						}
4885 					}
4886 				}
4887 
4888 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
4889 
4890 				return m_topAccelerationStructure.get()->getPtr();
4891 			}
4892 
getShaderBodyTextCandidate(const TestParams & testParams)4893 			const std::string TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset::getShaderBodyTextCandidate(const TestParams& testParams)
4894 			{
4895 				if (testParams.geomType == GEOM_TYPE_AABBS ||
4896 					testParams.geomType == GEOM_TYPE_TRIANGLES)
4897 				{
4898 					const std::string result =
4899 						"  uint        rayFlags = 0;\n"
4900 						"  uint        cullMask = 0xFF;\n"
4901 						"  float       tmin     = 0.0001;\n"
4902 						"  float       tmax     = 9.0;\n"
4903 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y),  0.2);\n"
4904 						"  vec3        direct   = vec3(0,									  0,								     -1.0);\n"
4905 						"  rayQueryEXT rayQuery;\n"
4906 						"\n"
4907 						"  int result_i32 = 2;\n"
4908 						"\n"
4909 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
4910 						"\n"
4911 						"  while (rayQueryProceedEXT(rayQuery))\n"
4912 						"  {\n"
4913 						"      result_i32 = int(rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT(rayQuery, false) );\n"
4914 						"\n"
4915 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
4916 						"  }\n"
4917 						"\n"
4918 						"  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
4919 
4920 					return result;
4921 				}
4922 				else
4923 				{
4924 					TCU_THROW(InternalError, "Unknown geometry type");
4925 				}
4926 			}
4927 
getShaderBodyTextCommitted(const TestParams & testParams)4928 			const std::string TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset::getShaderBodyTextCommitted(const TestParams& testParams)
4929 			{
4930 				if (testParams.geomType == GEOM_TYPE_AABBS ||
4931 					testParams.geomType == GEOM_TYPE_TRIANGLES)
4932 				{
4933 					const std::string result =
4934 						"  uint        rayFlags = 0;\n"
4935 						"  uint        cullMask = 0xFF;\n"
4936 						"  float       tmin     = 0.0001;\n"
4937 						"  float       tmax     = 9.0;\n"
4938 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y),  0.2);\n"
4939 						"  vec3        direct   = vec3(0,									  0,								     -1.0);\n"
4940 						"  rayQueryEXT rayQuery;\n"
4941 						"\n"
4942 						"  bool intersection_found = false;\n"
4943 						"  int  result_i32         = 0;\n"
4944 						"\n"
4945 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
4946 						"\n"
4947 						"  while (rayQueryProceedEXT(rayQuery))\n"
4948 						"  {\n"
4949 						"      intersection_found = true;\n"
4950 						"\n"
4951 						"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
4952 						"  }\n"
4953 						"\n"
4954 						"  result_i32 = (intersection_found) ? int(rayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetEXT(rayQuery, true) )\n"
4955 						"									 : 2;\n"
4956 						"\n"
4957 						"  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
4958 
4959 					return result;
4960 				}
4961 				else
4962 				{
4963 					TCU_THROW(InternalError, "Unknown geometry type");
4964 				}
4965 			}
4966 			/// </summary>
4967 
4968 			class TestConfigurationRayQueryTerminate: public TestConfiguration
4969 			{
4970 			public:
TestConfigurationRayQueryTerminate(Context & context)4971 				TestConfigurationRayQueryTerminate (Context& context) : TestConfiguration(context) {}
4972 				static const std::string getShaderBodyText(const TestParams& testParams);
4973 
4974 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
4975 					VkCommandBuffer					cmdBuffer) override;
4976 
4977 				private:
4978 					static const deUint32 N_RAY_QUERIES_TO_USE;
4979 			};
4980 
4981 			const deUint32 TestConfigurationRayQueryTerminate::N_RAY_QUERIES_TO_USE = 8;
4982 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)4983 			const VkAccelerationStructureKHR* TestConfigurationRayQueryTerminate::initAccelerationStructures(TestParams& testParams, VkCommandBuffer cmdBuffer)
4984 			{
4985 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
4986 				const VkDevice								device = m_testEnvironment->device;
4987 				Allocator&									allocator = *m_testEnvironment->allocator;
4988 				const deUint32								width = testParams.width;
4989 				const deUint32								height = testParams.height;
4990 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
4991 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
4992 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
4993 				deUint32									squareNdx = 0;
4994 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
4995 
4996 				DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
4997 
4998 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
4999 
5000 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
5001 
5002 				m_expected.resize(width * height);
5003 
5004 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
5005 				{
5006 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
5007 					{
5008 						for (deUint32 groupNdx = 0; groupNdx < squaresGroupCount; ++groupNdx, ++squareNdx)
5009 						{
5010 							std::vector<tcu::Vec3>							geometryData;
5011 							de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
5012 
5013 							for (deInt32 z = -2; z <= 0; ++z)
5014 							{
5015 								const auto	squareX = (squareNdx % width);
5016 								const auto	squareY = (squareNdx / width);
5017 
5018 								const float x0 = float(squareX + 0) / float(width);
5019 								const float y0 = float(squareY + 0) / float(height);
5020 								const float x1 = float(squareX + 1) / float(width);
5021 								const float y1 = float(squareY + 1) / float(height);
5022 
5023 								if (testParams.geomType == GeomType::GEOM_TYPE_TRIANGLES)
5024 								{
5025 									if ((squareNdx % 2) == 0)
5026 									{
5027 										geometryData.push_back(tcu::Vec3(x0, y0, static_cast<float>(z) ));
5028 										geometryData.push_back(tcu::Vec3(x0, y1, static_cast<float>(z) ));
5029 										geometryData.push_back(tcu::Vec3(x1, y1, static_cast<float>(z) ));
5030 
5031 										geometryData.push_back(tcu::Vec3(x1, y1, static_cast<float>(z) ));
5032 										geometryData.push_back(tcu::Vec3(x1, y0, static_cast<float>(z) ));
5033 										geometryData.push_back(tcu::Vec3(x0, y0, static_cast<float>(z) ));
5034 									}
5035 									else
5036 									{
5037 										geometryData.push_back(tcu::Vec3(x1, y1, static_cast<float>(z) ));
5038 										geometryData.push_back(tcu::Vec3(x0, y1, static_cast<float>(z) ));
5039 										geometryData.push_back(tcu::Vec3(x0, y0, static_cast<float>(z) ));
5040 
5041 										geometryData.push_back(tcu::Vec3(x0, y0, static_cast<float>(z) ));
5042 										geometryData.push_back(tcu::Vec3(x1, y0, static_cast<float>(z) ));
5043 										geometryData.push_back(tcu::Vec3(x1, y1, static_cast<float>(z) ));
5044 									}
5045 								}
5046 								else
5047 								{
5048 									geometryData.push_back(tcu::Vec3(x0, y0, static_cast<float>(z) ));
5049 									geometryData.push_back(tcu::Vec3(x1, y1, static_cast<float>(z) ));
5050 								}
5051 							}
5052 
5053 							m_expected.at(squareNdx) = (1 << N_RAY_QUERIES_TO_USE) - 1;
5054 
5055 							rayQueryBottomLevelAccelerationStructure->addGeometry(	geometryData,
5056 																					(testParams.geomType == GeomType::GEOM_TYPE_TRIANGLES),
5057 																					VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR);
5058 
5059 							rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
5060 							m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
5061 
5062 							m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4, instanceNdx + 1, 255U, m_expected.at(squareNdx));
5063 						}
5064 					}
5065 				}
5066 
5067 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
5068 
5069 				return m_topAccelerationStructure.get()->getPtr();
5070 			}
5071 
getShaderBodyText(const TestParams & testParams)5072 			const std::string TestConfigurationRayQueryTerminate::getShaderBodyText(const TestParams& testParams)
5073 			{
5074 				if (testParams.geomType == GEOM_TYPE_AABBS ||
5075 					testParams.geomType == GEOM_TYPE_TRIANGLES)
5076 				{
5077 					std::string result =
5078 						"  const int nQueries      = " + de::toString(N_RAY_QUERIES_TO_USE) + ";\n"
5079 						"  const int nPassingQuery = nQueries / 2;\n"
5080 						"\n"
5081 						"  const uint  rayFlags = 0;\n"
5082 						"  const uint  cullMask = 0xFF;\n"
5083 						"  const float tmin     = 0.0001;\n"
5084 						"  const float tmax     = 9.0;\n"
5085 						"\n"
5086 						"  rayQueryEXT rayQueries                     [nQueries];\n"
5087 						"  int         nSuccessfulRayQueryProceedCalls[nQueries];\n"
5088 						"\n"
5089 						"  int result_i32 = 0;\n"
5090 						"\n"
5091 						"  for (int nQuery = nQueries - 1; nQuery >= 0; --nQuery)\n"
5092 						"  {\n"
5093 						"      vec3 origin = vec3((float(pos.x) + 0.4f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y),  0.2);\n"
5094 						"      vec3 direct = vec3(0,                                     0,                                     -1.0);\n"
5095 						"\n"
5096 						"      rayQueryInitializeEXT(rayQueries[nQuery], rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
5097 						"\n"
5098 						"      nSuccessfulRayQueryProceedCalls[nQuery] = 0;\n"
5099 						"  }\n"
5100 						"\n"
5101 						"  while (true)\n"
5102 						"  {\n"
5103 						"    int nQueriesSuccessful = 0;\n"
5104 						"\n"
5105 						"    for (int nQuery = 0; nQuery < nQueries; ++nQuery)\n"
5106 						"    {\n"
5107 						"      if (rayQueryProceedEXT(rayQueries[nQuery]) )\n"
5108 						"      {\n"
5109 						"        nSuccessfulRayQueryProceedCalls[nQuery] ++;\n"
5110 						"        nQueriesSuccessful                      ++;\n"
5111 						"\n"
5112 						"        if (nQuery != nPassingQuery)\n"
5113 						"        {\n"
5114 						"            rayQueryTerminateEXT(rayQueries[nQuery]);\n"
5115 						"        }\n"
5116 						"      }\n"
5117 						"    }\n"
5118 						"\n"
5119 						"    if (nQueriesSuccessful == 0)\n"
5120 						"    {\n"
5121 						"      break;\n"
5122 						"    }\n"
5123 						"  }\n"
5124 						"\n"
5125 						"  for (int nQuery = 0; nQuery < nQueries; ++nQuery)\n"
5126 						"  {\n"
5127 						"    if (nPassingQuery != nQuery)\n"
5128 						"    {\n"
5129 						"       result_i32 |= (nSuccessfulRayQueryProceedCalls[nQuery] == 1) ? (1 << nQuery) : 0;\n"
5130 						"    }\n"
5131 						"    else\n"
5132 						"    {\n"
5133 						"       result_i32 |= (nSuccessfulRayQueryProceedCalls[nQuery] == 3) ? (1 << nQuery) : 0;\n"
5134 						"    }\n"
5135 						"  }\n"
5136 						"\n"
5137 						"  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
5138 
5139 					return result;
5140 				}
5141 				else
5142 				{
5143 					TCU_THROW(InternalError, "Unknown geometry type");
5144 				}
5145 			}
5146 
5147 			class TestConfigurationGetIntersectionType : public TestConfiguration
5148 			{
5149 			public:
TestConfigurationGetIntersectionType(Context & context)5150 				TestConfigurationGetIntersectionType (Context& context) : TestConfiguration(context) {}
5151 				static const std::string	getShaderBodyTextCandidate(const TestParams& testParams);
5152 				static const std::string	getShaderBodyTextCommitted(const TestParams& testParams);
5153 
5154 				virtual const VkAccelerationStructureKHR* initAccelerationStructures(TestParams& testParams,
5155 					VkCommandBuffer					cmdBuffer) override;
5156 			};
5157 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)5158 			const VkAccelerationStructureKHR* TestConfigurationGetIntersectionType::initAccelerationStructures(TestParams& testParams, VkCommandBuffer cmdBuffer)
5159 			{
5160 				const DeviceInterface&						vkd = *m_testEnvironment->vkd;
5161 				const VkDevice								device = m_testEnvironment->device;
5162 				Allocator&									allocator = *m_testEnvironment->allocator;
5163 				const deUint32								width = testParams.width;
5164 				const deUint32								height = testParams.height;
5165 				const deUint32								instancesGroupCount = testParams.instancesGroupCount;
5166 				const deUint32								geometriesGroupCount = testParams.geometriesGroupCount;
5167 				const deUint32								squaresGroupCount = testParams.squaresGroupCount;
5168 				deUint32									squareNdx = 0;
5169 				de::MovePtr<TopLevelAccelerationStructure>	rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
5170 
5171 				DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == width * height);
5172 
5173 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
5174 
5175 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
5176 
5177 				m_expected.resize(width * height);
5178 
5179 				for (deUint32 instanceNdx = 0; instanceNdx < instancesGroupCount; ++instanceNdx)
5180 				{
5181 					for (deUint32 geometryNdx = 0; geometryNdx < geometriesGroupCount; ++geometryNdx)
5182 					{
5183 						for (deUint32 groupNdx = 0; groupNdx < squaresGroupCount; ++groupNdx, ++squareNdx)
5184 						{
5185 							de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
5186 							std::vector<tcu::Vec3>							geometryData;
5187 
5188 							const auto	squareX = (squareNdx % width);
5189 							const auto	squareY = (squareNdx / width);
5190 
5191 							const float x0 = float(squareX + 0) / float(width);
5192 							const float y0 = float(squareY + 0) / float(height);
5193 							const float x1 = float(squareX + 1) / float(width);
5194 							const float y1 = float(squareY + 1) / float(height);
5195 
5196 							if ((squareNdx % 2) == 0)
5197 							{
5198 								if (testParams.geomType == GEOM_TYPE_TRIANGLES)
5199 								{
5200 									geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
5201 									geometryData.push_back(tcu::Vec3(x0, y1, 0.0));
5202 									geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
5203 
5204 									geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
5205 									geometryData.push_back(tcu::Vec3(x1, y0, 0.0));
5206 									geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
5207 								}
5208 								else
5209 								{
5210 									geometryData.push_back(tcu::Vec3(x0, y0, 0.0));
5211 									geometryData.push_back(tcu::Vec3(x1, y1, 0.0));
5212 								}
5213 
5214 								m_expected.at(squareNdx) = (testParams.testType == TEST_TYPE_GET_INTERSECTION_TYPE_CANDIDATE)	? (testParams.geomType == GEOM_TYPE_TRIANGLES)	? 0		/* gl_RayQueryCandidateIntersectionTriangleEXT  */
5215 																																												: 1		/* gl_RayQueryCandidateIntersectionAABBEXT      */
5216 																																: (testParams.geomType == GEOM_TYPE_TRIANGLES)	? 1		/* gl_RayQueryCommittedIntersectionTriangleEXT  */
5217 																																												: 2;	/* gl_RayQueryCommittedIntersectionGeneratedEXT */
5218 
5219 								rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, (testParams.geomType == GEOM_TYPE_TRIANGLES) );
5220 
5221 								rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
5222 								m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
5223 
5224 								m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4);
5225 							}
5226 							else
5227 							{
5228 								m_expected.at(squareNdx) = (testParams.testType == TEST_TYPE_GET_INTERSECTION_TYPE_CANDIDATE)	? 123
5229 																																: 0; /* gl_RayQueryCommittedIntersectionNoneEXT */
5230 							}
5231 						}
5232 					}
5233 				}
5234 
5235 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
5236 
5237 				return m_topAccelerationStructure.get()->getPtr();
5238 			}
5239 
getShaderBodyTextCandidate(const TestParams & testParams)5240 			const std::string TestConfigurationGetIntersectionType::getShaderBodyTextCandidate(const TestParams& testParams)
5241 			{
5242 				if (testParams.geomType == GEOM_TYPE_AABBS ||
5243 					testParams.geomType == GEOM_TYPE_TRIANGLES)
5244 				{
5245 					std::string result =
5246 						"  uint        rayFlags = 0;\n"
5247 						"  uint        cullMask = 0xFF;\n"
5248 						"  float       tmin     = 0.0001;\n"
5249 						"  float       tmax     = 9.0;\n"
5250 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y),  0.2);\n"
5251 						"  vec3        direct   = vec3(0,									  0,								     -1.0);\n"
5252 						"  rayQueryEXT rayQuery;\n"
5253 						"\n"
5254 						"  int result_i32 = 123;\n"
5255 						"\n"
5256 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
5257 						"\n"
5258 						"  while (rayQueryProceedEXT(rayQuery))\n"
5259 						"  {\n"
5260 						"      result_i32 = int(rayQueryGetIntersectionTypeEXT(rayQuery, false) );\n"
5261 						"\n";
5262 
5263 					if (testParams.geomType == GEOM_TYPE_AABBS)
5264 					{
5265 						result += "      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n";
5266 					}
5267 					else
5268 					if (testParams.geomType == GEOM_TYPE_TRIANGLES)
5269 					{
5270 						result += "      rayQueryConfirmIntersectionEXT(rayQuery);\n";
5271 					}
5272 
5273 					result +=
5274 						"  }\n"
5275 						"\n"
5276 						"  imageStore(result, pos, ivec4(result_i32, 0, 0, 0));\n";
5277 
5278 					return result;
5279 				}
5280 				else
5281 				{
5282 					TCU_THROW(InternalError, "Unknown geometry type");
5283 				}
5284 			}
5285 
getShaderBodyTextCommitted(const TestParams & testParams)5286 			const std::string TestConfigurationGetIntersectionType::getShaderBodyTextCommitted(const TestParams& testParams)
5287 			{
5288 				if (testParams.geomType == GEOM_TYPE_AABBS ||
5289 					testParams.geomType == GEOM_TYPE_TRIANGLES)
5290 				{
5291 					std::string result =
5292 						"  uint        rayFlags = 0;\n"
5293 						"  uint        cullMask = 0xFF;\n"
5294 						"  float       tmin     = 0.0001;\n"
5295 						"  float       tmax     = 9.0;\n"
5296 						"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y),  0.2);\n"
5297 						"  vec3        direct   = vec3(0,									  0,								     -1.0);\n"
5298 						"  rayQueryEXT rayQuery;\n"
5299 						"\n"
5300 						"  uint result_i32 = 123u;\n"
5301 						"\n"
5302 						"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
5303 						"\n"
5304 						"  while (rayQueryProceedEXT(rayQuery))\n"
5305 						"  {\n";
5306 
5307 					if (testParams.geomType == GEOM_TYPE_AABBS)
5308 					{
5309 						result += "      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n";
5310 					}
5311 					else
5312 					if (testParams.geomType == GEOM_TYPE_TRIANGLES)
5313 					{
5314 						result +=
5315 							"      rayQueryConfirmIntersectionEXT(rayQuery);\n";
5316 					}
5317 
5318 					result +=
5319 						"  }\n"
5320 						"\n"
5321 						"  result_i32 = rayQueryGetIntersectionTypeEXT(rayQuery, true);\n"
5322 						"\n"
5323 						"  imageStore(result, pos, ivec4(int(result_i32), 0, 0, 0));\n";
5324 
5325 					return result;
5326 				}
5327 				else
5328 				{
5329 					TCU_THROW(InternalError, "Unknown geometry type");
5330 				}
5331 			}
5332 
5333 			class TestConfigurationUsingWrapperFunction : public TestConfiguration
5334 			{
5335 			public:
TestConfigurationUsingWrapperFunction(Context & context)5336 				TestConfigurationUsingWrapperFunction (Context& context) : TestConfiguration(context) {}
5337 				virtual const VkAccelerationStructureKHR*	initAccelerationStructures(TestParams&			testParams,
5338 																					   VkCommandBuffer		cmdBuffer) override;
5339 
5340 				static const std::string getShaderBodyText(const TestParams& testParams);
5341 			};
5342 
initAccelerationStructures(TestParams & testParams,VkCommandBuffer cmdBuffer)5343 			const VkAccelerationStructureKHR* TestConfigurationUsingWrapperFunction::initAccelerationStructures(TestParams& testParams, VkCommandBuffer cmdBuffer)
5344 			{
5345 				const DeviceInterface&	vkd = *m_testEnvironment->vkd;
5346 				const VkDevice			device = m_testEnvironment->device;
5347 				Allocator&				allocator = *m_testEnvironment->allocator;
5348 				const deUint32			width = testParams.width;
5349 				const deUint32			height = testParams.height;
5350 				const deUint32			instancesGroupCount = testParams.instancesGroupCount;
5351 				const deUint32			squaresGroupCount = testParams.squaresGroupCount;
5352 				const bool				usesTriangles = (testParams.geomType == GEOM_TYPE_TRIANGLES);
5353 
5354 				DE_ASSERT(instancesGroupCount == 1);
5355 				DE_ASSERT(squaresGroupCount == width * height);
5356 
5357 				m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(makeTopLevelAccelerationStructure().release());
5358 				m_topAccelerationStructure->setInstanceCount(instancesGroupCount);
5359 
5360 				m_expected = std::vector<deInt32>(width * height, 1);
5361 
5362 				de::MovePtr<BottomLevelAccelerationStructure> rayQueryBottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
5363 
5364 				for (deUint32 squareNdx = 0; squareNdx < squaresGroupCount; ++squareNdx)
5365 				{
5366 					std::vector<tcu::Vec3> geometryData;
5367 
5368 					const auto	squareX = (squareNdx % width);
5369 					const auto	squareY = (squareNdx / width);
5370 
5371 					const float x0 = float(squareX + 0) / float(width);
5372 					const float y0 = float(squareY + 0) / float(height);
5373 					const float x1 = float(squareX + 1) / float(width);
5374 					const float y1 = float(squareY + 1) / float(height);
5375 
5376 					if (usesTriangles)
5377 					{
5378 						geometryData.emplace_back(x0, y0, 0.0f);
5379 						geometryData.emplace_back(x0, y1, 0.0f);
5380 						geometryData.emplace_back(x1, y1, 0.0f);
5381 
5382 						geometryData.emplace_back(x1, y1, 0.0f);
5383 						geometryData.emplace_back(x1, y0, 0.0f);
5384 						geometryData.emplace_back(x0, y0, 0.0f);
5385 					}
5386 					else
5387 					{
5388 						geometryData.emplace_back(x0, y0, 0.0f);
5389 						geometryData.emplace_back(x1, y1, 0.0f);
5390 					}
5391 
5392 					rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, usesTriangles);
5393 				}
5394 
5395 				rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
5396 				m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
5397 				m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back(), identityMatrix3x4, 1);
5398 				m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
5399 
5400 				return m_topAccelerationStructure.get()->getPtr();
5401 			}
5402 
getShaderBodyText(const TestParams & testParams)5403 			const std::string TestConfigurationUsingWrapperFunction::getShaderBodyText(const TestParams& testParams)
5404 			{
5405 				DE_UNREF(testParams);
5406 				DE_ASSERT(testParams.isSPIRV);
5407 
5408 				// glslang is compiling rayQueryEXT function parameters to OpTypePointer Function to OpTypeRayQueryKHR
5409 				// To test bare rayQueryEXT object passed as function parameter we need to use SPIR-V assembly.
5410 				// In it, rayQueryWrapper has been modified to take a bare rayQueryEXT as the third argument, instead of a pointer.
5411 				// The SPIR-V assembly shader below is based on the following GLSL code:
5412 
5413 				// int rayQueryWrapper(rayQueryEXT rq1, int value, rayQueryEXT rq2)
5414 				// {
5415 				//    int result = value;
5416 				//    while (rayQueryProceedEXT(rq1))
5417 				//    {
5418 				//       result = 1;
5419 				//       rayQueryConfirmIntersectionEXT(rq2);
5420 				//    }
5421 				//    return result;
5422 				// }
5423 				// void main()
5424 				// {
5425 				//    ivec3       pos = ivec3(gl_WorkGroupID);
5426 				//    ivec3       size = ivec3(gl_NumWorkGroups);
5427 				//    uint        rayFlags = 0;
5428 				//    uint        cullMask = 0xFF;
5429 				//    float       tmin = 0.0001;
5430 				//    float       tmax = 9.0;
5431 				//    vec3        origin = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.2);
5432 				//    vec3        direct = vec3(0.0, 0.0, -1.0);
5433 				//    rayQueryEXT rayQuery;
5434 				//    rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);
5435 				//    imageStore(result, pos, ivec4(rayQueryWrapper(rayQuery, 0, rayQuery), 0, 0, 0));
5436 				// }
5437 
5438 				return
5439 					"OpCapability Shader\n"
5440 					"OpCapability RayQueryKHR\n"
5441 					"OpExtension \"SPV_KHR_ray_query\"\n"
5442 				"%1 = OpExtInstImport \"GLSL.std.450\"\n"
5443 				"OpMemoryModel Logical GLSL450\n"
5444 					"OpEntryPoint GLCompute %4 \"main\" %35 %39 %83 %93\n"
5445 					"OpExecutionMode %4 LocalSize 1 1 1\n"
5446 					"OpDecorate %35 BuiltIn WorkgroupId\n"
5447 					"OpDecorate %39 BuiltIn NumWorkgroups\n"
5448 					"OpDecorate %83 DescriptorSet 0\n"
5449 					"OpDecorate %83 Binding 1\n"
5450 					"OpDecorate %93 DescriptorSet 0\n"
5451 					"OpDecorate %93 Binding 0\n"
5452 
5453 					// types and constants
5454 					"%2 = OpTypeVoid\n"
5455 					"%3 = OpTypeFunction %2\n"
5456 					"%bare_query_type = OpTypeRayQueryKHR\n"
5457 					"%pointer_to_query_type = OpTypePointer Function %bare_query_type\n"
5458 					"%8 = OpTypeInt 32 1\n"
5459 					"%9 = OpTypePointer Function %8\n"
5460 
5461 					// this function was modified to take also bare rayQueryEXT type
5462 					"%ray_query_wrapper_fun = OpTypeFunction %8 %pointer_to_query_type %9 %bare_query_type\n"
5463 
5464 					"%23 = OpTypeBool\n"
5465 					"%25 = OpConstant %8 1\n"
5466 					"%29 = OpTypeVector %8 3\n"
5467 					"%30 = OpTypePointer Function %29\n"
5468 					"%32 = OpTypeInt 32 0\n"
5469 					"%33 = OpTypeVector %32 3\n"
5470 					"%34 = OpTypePointer Input %33\n"
5471 					"%35 = OpVariable %34 Input\n"
5472 					"%39 = OpVariable %34 Input\n"
5473 					"%42 = OpTypePointer Function %32\n"
5474 					"%44 = OpConstant %32 0\n"
5475 					"%46 = OpConstant %32 255\n"
5476 					"%47 = OpTypeFloat 32\n"
5477 					"%48 = OpTypePointer Function %47\n"
5478 					"%50 = OpConstant %47 9.99999975e-05\n"
5479 					"%52 = OpConstant %47 9\n"
5480 					"%53 = OpTypeVector %47 3\n"
5481 					"%54 = OpTypePointer Function %53\n"
5482 					"%59 = OpConstant %47 0.5\n"
5483 					"%65 = OpConstant %32 1\n"
5484 					"%74 = OpConstant %47 0.200000003\n"
5485 					"%77 = OpConstant %47 0\n"
5486 					"%78 = OpConstant %47 -1\n"
5487 					"%79 = OpConstantComposite %53 %77 %77 %78\n"
5488 					"%81 = OpTypeAccelerationStructureKHR\n"
5489 					"%82 = OpTypePointer UniformConstant %81\n"
5490 					"%83 = OpVariable %82 UniformConstant\n"
5491 					"%91 = OpTypeImage %8 3D 0 0 0 2 R32i\n"
5492 					"%92 = OpTypePointer UniformConstant %91\n"
5493 					"%93 = OpVariable %92 UniformConstant\n"
5494 					"%96 = OpConstant %8 0\n"
5495 					"%99 = OpTypeVector %8 4\n"
5496 
5497 					// void main()
5498 					"%4 = OpFunction %2 None %3\n"
5499 					"%5 = OpLabel\n"
5500 					"%31 = OpVariable %30 Function\n"
5501 					"%38 = OpVariable %30 Function\n"
5502 					"%43 = OpVariable %42 Function\n"
5503 					"%45 = OpVariable %42 Function\n"
5504 					"%49 = OpVariable %48 Function\n"
5505 					"%51 = OpVariable %48 Function\n"
5506 					"%55 = OpVariable %54 Function\n"
5507 					"%76 = OpVariable %54 Function\n"
5508 					"%var_ray_query_ptr = OpVariable %pointer_to_query_type Function\n"
5509 					"%97 = OpVariable %9 Function\n"
5510 					"%36 = OpLoad %33 %35\n"
5511 					"%37 = OpBitcast %29 %36\n"
5512 					"OpStore %31 %37\n"
5513 					"%40 = OpLoad %33 %39\n"
5514 					"%41 = OpBitcast %29 %40\n"
5515 					"OpStore %38 %41\n"
5516 					"OpStore %43 %44\n"
5517 					"OpStore %45 %46\n"
5518 					"OpStore %49 %50\n"
5519 					"OpStore %51 %52\n"
5520 					"%56 = OpAccessChain %9 %31 %44\n"
5521 					"%57 = OpLoad %8 %56\n"
5522 					"%58 = OpConvertSToF %47 %57\n"
5523 					"%60 = OpFAdd %47 %58 %59\n"
5524 					"%61 = OpAccessChain %9 %38 %44\n"
5525 					"%62 = OpLoad %8 %61\n"
5526 					"%63 = OpConvertSToF %47 %62\n"
5527 					"%64 = OpFDiv %47 %60 %63\n"
5528 					"%66 = OpAccessChain %9 %31 %65\n"
5529 					"%67 = OpLoad %8 %66\n"
5530 					"%68 = OpConvertSToF %47 %67\n"
5531 					"%69 = OpFAdd %47 %68 %59\n"
5532 					"%70 = OpAccessChain %9 %38 %65\n"
5533 					"%71 = OpLoad %8 %70\n"
5534 					"%72 = OpConvertSToF %47 %71\n"
5535 					"%73 = OpFDiv %47 %69 %72\n"
5536 					"%75 = OpCompositeConstruct %53 %64 %73 %74\n"
5537 					"OpStore %55 %75\n"
5538 					"OpStore %76 %79\n"
5539 					"%84 = OpLoad %81 %83\n"
5540 					"%85 = OpLoad %32 %43\n"
5541 					"%86 = OpLoad %32 %45\n"
5542 					"%87 = OpLoad %53 %55\n"
5543 					"%88 = OpLoad %47 %49\n"
5544 					"%89 = OpLoad %53 %76\n"
5545 					"%90 = OpLoad %47 %51\n"
5546 					"OpRayQueryInitializeKHR %var_ray_query_ptr %84 %85 %86 %87 %88 %89 %90\n"
5547 					"%94 = OpLoad %91 %93\n"
5548 					"%95 = OpLoad %29 %31\n"
5549 					"OpStore %97 %96\n"
5550 					"%var_ray_query_bare = OpLoad %bare_query_type %var_ray_query_ptr\n"
5551 					"%98 = OpFunctionCall %8 %14 %var_ray_query_ptr %97 %var_ray_query_bare\n"
5552 					"%100 = OpCompositeConstruct %99 %98 %96 %96 %96\n"
5553 					"OpImageWrite %94 %95 %100 SignExtend\n"
5554 					"OpReturn\n"
5555 					"OpFunctionEnd\n"
5556 
5557 					// int rayQueryWrapper(rayQueryEXT rq1, int value, rayQueryEXT rq2)
5558 					// where in SPIRV rq1 is pointer and rq2 is bare type
5559 					"%14 = OpFunction %8 None %ray_query_wrapper_fun\n"
5560 					"%11 = OpFunctionParameter %pointer_to_query_type\n"
5561 					"%12 = OpFunctionParameter %9\n"
5562 					"%13 = OpFunctionParameter %bare_query_type\n"
5563 					"%15 = OpLabel\n"
5564 					"%16 = OpVariable %9 Function\n"
5565 					"%local_var_ray_query_ptr = OpVariable %pointer_to_query_type Function\n"
5566 					"%17 = OpLoad %8 %12\n"
5567 					"OpStore %16 %17\n"
5568 					"OpBranch %18\n"
5569 					"%18 = OpLabel\n"
5570 					"OpLoopMerge %20 %21 None\n"
5571 					"OpBranch %22\n"
5572 					"%22 = OpLabel\n"
5573 					"%24 = OpRayQueryProceedKHR %23 %11\n"
5574 					"OpBranchConditional %24 %19 %20\n"
5575 					"%19 = OpLabel\n"
5576 					"OpStore %16 %25\n"
5577 					"OpStore %local_var_ray_query_ptr %13\n"
5578 					"OpRayQueryConfirmIntersectionKHR %local_var_ray_query_ptr\n"
5579 					"OpBranch %21\n"
5580 					"%21 = OpLabel\n"
5581 					"OpBranch %18\n"
5582 					"%20 = OpLabel\n"
5583 					"%26 = OpLoad %8 %16\n"
5584 					"OpReturnValue %26\n"
5585 					"OpFunctionEnd\n";
5586 			}
5587 
5588 			class RayQueryBuiltinTestInstance : public TestInstance
5589 			{
5590 			public:
5591 				RayQueryBuiltinTestInstance(Context& context, const TestParams& data);
5592 				virtual								~RayQueryBuiltinTestInstance(void);
5593 				tcu::TestStatus						iterate(void);
5594 
5595 			private:
5596 				TestParams							m_data;
5597 				de::MovePtr<TestConfiguration>		m_testConfig;
5598 				de::MovePtr<PipelineConfiguration>	m_pipelineConfig;
5599 			};
5600 
RayQueryBuiltinTestInstance(Context & context,const TestParams & data)5601 			RayQueryBuiltinTestInstance::RayQueryBuiltinTestInstance(Context& context, const TestParams& data)
5602 				: vkt::TestInstance(context)
5603 				, m_data(data)
5604 			{
5605 				switch (m_data.testType)
5606 				{
5607 				case TEST_TYPE_FLOW:																	m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationFlow(context));													break;
5608 				case TEST_TYPE_PRIMITIVE_ID:															m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationPrimitiveId(context));											break;
5609 				case TEST_TYPE_INSTANCE_ID:																m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationInstanceId(context));											break;
5610 				case TEST_TYPE_INSTANCE_CUSTOM_INDEX:													m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationInstanceCustomIndex(context));									break;
5611 				case TEST_TYPE_INTERSECTION_T_KHR:														m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationIntersectionT(context));											break;
5612 				case TEST_TYPE_OBJECT_RAY_ORIGIN_KHR:													m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationObjectRayOrigin(context));										break;
5613 				case TEST_TYPE_OBJECT_RAY_DIRECTION_KHR:												m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationObjectRayDirection(context));									break;
5614 				case TEST_TYPE_OBJECT_TO_WORLD_KHR:														m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationObjectToWorld(context));											break;
5615 				case TEST_TYPE_WORLD_TO_OBJECT_KHR:														m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationWorldToObject(context));											break;
5616 				case TEST_TYPE_NULL_ACCELERATION_STRUCTURE:												m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationNullASStruct(context));											break;
5617 				case TEST_TYPE_USING_WRAPPER_FUNCTION:													m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationUsingWrapperFunction(context));									break;
5618 				case TEST_TYPE_GET_RAY_TMIN:															m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetRayTMin(context));											break;
5619 				case TEST_TYPE_GET_WORLD_RAY_ORIGIN:													m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetWorldRayOrigin(context));										break;
5620 				case TEST_TYPE_GET_WORLD_RAY_DIRECTION:													m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetWorldRayDirection(context));									break;
5621 				case TEST_TYPE_GET_INTERSECTION_CANDIDATE_AABB_OPAQUE:									m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionCandidateAABBOpaque(context));					break;
5622 				case TEST_TYPE_GET_INTERSECTION_FRONT_FACE_CANDIDATE:									m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionFrontFace(context));								break;
5623 				case TEST_TYPE_GET_INTERSECTION_FRONT_FACE_COMMITTED:									m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionFrontFace(context));								break;
5624 				case TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_CANDIDATE:								m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionGeometryIndex(context));							break;
5625 				case TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_COMMITTED:								m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionGeometryIndex(context));							break;
5626 				case TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_CANDIDATE:									m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionBarycentrics(context));							break;
5627 				case TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_COMMITTED:									m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionBarycentrics(context));							break;
5628 				case TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_CANDIDATE:	m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset(context));	break;
5629 				case TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_COMMITTED:	m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset(context));	break;
5630 				case TEST_TYPE_RAY_QUERY_TERMINATE:														m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationRayQueryTerminate(context));										break;
5631 				case TEST_TYPE_GET_INTERSECTION_TYPE_CANDIDATE:											m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionType(context));									break;
5632 				case TEST_TYPE_GET_INTERSECTION_TYPE_COMMITTED:											m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationGetIntersectionType(context));									break;
5633 
5634 				default: TCU_THROW(InternalError, "Unknown test type");
5635 				}
5636 
5637 				switch (m_data.stage)
5638 				{
5639 				case VK_SHADER_STAGE_VERTEX_BIT:
5640 				case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
5641 				case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
5642 				case VK_SHADER_STAGE_GEOMETRY_BIT:
5643 				case VK_SHADER_STAGE_FRAGMENT_BIT:
5644 				{
5645 					m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new GraphicsConfiguration());
5646 					break;
5647 				}
5648 
5649 				case VK_SHADER_STAGE_COMPUTE_BIT:
5650 				{
5651 					m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new ComputeConfiguration());
5652 					break;
5653 				}
5654 
5655 				case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
5656 				case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
5657 				case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
5658 				case VK_SHADER_STAGE_MISS_BIT_KHR:
5659 				case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
5660 				case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
5661 				{
5662 					m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new RayTracingConfiguration());
5663 					break;
5664 				}
5665 
5666 				default:
5667 					TCU_THROW(InternalError, "Unknown shader stage");
5668 				}
5669 			}
5670 
~RayQueryBuiltinTestInstance(void)5671 			RayQueryBuiltinTestInstance::~RayQueryBuiltinTestInstance(void)
5672 			{
5673 			}
5674 
iterate(void)5675 			tcu::TestStatus RayQueryBuiltinTestInstance::iterate (void)
5676 			{
5677 				const TestEnvironment&				testEnv								= m_testConfig->getTestEnvironment();
5678 				const DeviceInterface&				vkd									= *testEnv.vkd;
5679 				const VkDevice						device								= testEnv.device;
5680 				const VkQueue						queue								= testEnv.queue;
5681 				Allocator&							allocator							= *testEnv.allocator;
5682 				const deUint32						queueFamilyIndex					= testEnv.queueFamilyIndex;
5683 
5684 				const deUint32						width								= m_data.width;
5685 				const deUint32						height								= m_data.height;
5686 				const deUint32						depth								= m_data.depth;
5687 				const VkImageCreateInfo				imageCreateInfo						= makeImageCreateInfo(m_data.format, width, height, depth);
5688 				const VkImageSubresourceRange		imageSubresourceRange				= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
5689 				const de::MovePtr<ImageWithMemory>	image								= de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
5690 				const Move<VkImageView>				imageView							= makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, m_data.format, imageSubresourceRange);
5691 
5692 				const deUint32						pixelSize							= mapVkFormat(m_data.format).getPixelSize();
5693 				const VkBufferCreateInfo			resultBufferCreateInfo				= makeBufferCreateInfo(width * height * depth * pixelSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
5694 				const VkImageSubresourceLayers		resultBufferImageSubresourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
5695 				const VkBufferImageCopy				resultBufferImageRegion				= makeBufferImageCopy(makeExtent3D(width, height, depth), resultBufferImageSubresourceLayers);
5696 				de::MovePtr<BufferWithMemory>		resultBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
5697 
5698 				const VkDescriptorImageInfo			resultImageInfo						= makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
5699 
5700 				const Move<VkCommandPool>			cmdPool								= createCommandPool(vkd, device, 0, queueFamilyIndex);
5701 				const Move<VkCommandBuffer>			cmdBuffer							= allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5702 				const VkAccelerationStructureKHR*	topAccelerationStructurePtr			= DE_NULL;
5703 
5704 				m_pipelineConfig->initConfiguration(testEnv, m_data);
5705 
5706 				beginCommandBuffer(vkd, *cmdBuffer, 0u);
5707 				{
5708 					const VkImageMemoryBarrier	preImageBarrier			= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, **image, imageSubresourceRange);
5709 					const VkClearValue			clearValue				= makeClearValueColorU32(0u, 0u, 0u, 0u);
5710 					const VkImageMemoryBarrier	postImageBarrier		= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, **image, imageSubresourceRange);
5711 					const VkMemoryBarrier		postTestMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
5712 					const VkMemoryBarrier		postCopyMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
5713 
5714 					cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
5715 					vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
5716 					cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
5717 
5718 					topAccelerationStructurePtr = m_testConfig->initAccelerationStructures(m_data, *cmdBuffer);
5719 
5720 					m_pipelineConfig->fillCommandBuffer(testEnv, m_data, *cmdBuffer, topAccelerationStructurePtr, resultImageInfo);
5721 
5722 					cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTestMemoryBarrier);
5723 
5724 					vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
5725 
5726 					cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
5727 				}
5728 				endCommandBuffer(vkd, *cmdBuffer);
5729 
5730 				submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
5731 
5732 				invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
5733 
5734 				if (m_testConfig->verify(resultBuffer.get(), m_data))
5735 					return tcu::TestStatus::pass("Pass");
5736 				else
5737 					return tcu::TestStatus::fail("Fail");
5738 			}
5739 
5740 			class RayQueryBuiltinTestCase : public TestCase
5741 			{
5742 			public:
5743 				RayQueryBuiltinTestCase(tcu::TestContext& context, const char* name, const char* desc, const TestParams data);
5744 				~RayQueryBuiltinTestCase(void);
5745 
5746 				virtual void			checkSupport(Context& context) const;
5747 				virtual	void			initPrograms(SourceCollections& programCollection) const;
5748 				virtual TestInstance*	createInstance(Context& context) const;
5749 
5750 			private:
5751 				TestParams				m_data;
5752 			};
5753 
RayQueryBuiltinTestCase(tcu::TestContext & context,const char * name,const char * desc,const TestParams data)5754 			RayQueryBuiltinTestCase::RayQueryBuiltinTestCase(tcu::TestContext& context, const char* name, const char* desc, const TestParams data)
5755 				: vkt::TestCase(context, name, desc)
5756 				, m_data(data)
5757 			{
5758 			}
5759 
~RayQueryBuiltinTestCase(void)5760 			RayQueryBuiltinTestCase::~RayQueryBuiltinTestCase(void)
5761 			{
5762 			}
5763 
checkSupport(Context & context) const5764 			void RayQueryBuiltinTestCase::checkSupport(Context& context) const
5765 			{
5766 				context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
5767 				context.requireDeviceFunctionality("VK_KHR_ray_query");
5768 
5769 				const VkPhysicalDeviceRayQueryFeaturesKHR& rayQueryFeaturesKHR = context.getRayQueryFeatures();
5770 				if (rayQueryFeaturesKHR.rayQuery == DE_FALSE)
5771 					TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");
5772 
5773 				const VkPhysicalDeviceAccelerationStructureFeaturesKHR& accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
5774 				if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
5775 					TCU_THROW(TestError, "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
5776 
5777 				m_data.pipelineCheckSupport(context, m_data);
5778 
5779 				if (m_data.testConfigCheckSupport != DE_NULL)
5780 					m_data.testConfigCheckSupport(context, m_data);
5781 			}
5782 
createInstance(Context & context) const5783 			TestInstance* RayQueryBuiltinTestCase::createInstance(Context& context) const
5784 			{
5785 				return new RayQueryBuiltinTestInstance(context, m_data);
5786 			}
5787 
initPrograms(SourceCollections & programCollection) const5788 			void RayQueryBuiltinTestCase::initPrograms(SourceCollections& programCollection) const
5789 			{
5790 				m_data.pipelineInitPrograms(programCollection, m_data);
5791 			}
5792 
getPipelineCheckSupport(const VkShaderStageFlagBits stage)5793 			static inline CheckSupportFunc getPipelineCheckSupport(const VkShaderStageFlagBits stage)
5794 			{
5795 				switch (stage)
5796 				{
5797 				case VK_SHADER_STAGE_VERTEX_BIT:
5798 				case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
5799 				case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
5800 				case VK_SHADER_STAGE_GEOMETRY_BIT:
5801 				case VK_SHADER_STAGE_FRAGMENT_BIT:
5802 					return GraphicsConfiguration::checkSupport;
5803 
5804 				case VK_SHADER_STAGE_COMPUTE_BIT:
5805 					return ComputeConfiguration::checkSupport;
5806 
5807 				case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
5808 				case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
5809 				case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
5810 				case VK_SHADER_STAGE_MISS_BIT_KHR:
5811 				case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
5812 				case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
5813 					return RayTracingConfiguration::checkSupport;
5814 
5815 				default:
5816 					TCU_THROW(InternalError, "Unknown shader stage");
5817 				}
5818 			}
5819 
getPipelineInitPrograms(const VkShaderStageFlagBits stage)5820 			static inline InitProgramsFunc getPipelineInitPrograms(const VkShaderStageFlagBits stage)
5821 			{
5822 				switch (stage)
5823 				{
5824 				case VK_SHADER_STAGE_VERTEX_BIT:
5825 				case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
5826 				case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
5827 				case VK_SHADER_STAGE_GEOMETRY_BIT:
5828 				case VK_SHADER_STAGE_FRAGMENT_BIT:
5829 					return GraphicsConfiguration::initPrograms;
5830 
5831 				case VK_SHADER_STAGE_COMPUTE_BIT:
5832 					return ComputeConfiguration::initPrograms;
5833 
5834 				case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
5835 				case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
5836 				case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
5837 				case VK_SHADER_STAGE_MISS_BIT_KHR:
5838 				case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
5839 				case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
5840 					return RayTracingConfiguration::initPrograms;
5841 
5842 				default:
5843 					TCU_THROW(InternalError, "Unknown shader stage");
5844 				}
5845 			}
5846 
getShaderBodyTextFunc(const TestType testType)5847 			static inline ShaderBodyTextFunc getShaderBodyTextFunc(const TestType testType)
5848 			{
5849 				switch (testType)
5850 				{
5851 				case TEST_TYPE_FLOW:																	return TestConfigurationFlow::getShaderBodyText;
5852 				case TEST_TYPE_PRIMITIVE_ID:															return TestConfigurationPrimitiveId::getShaderBodyText;
5853 				case TEST_TYPE_INSTANCE_ID:																return TestConfigurationInstanceId::getShaderBodyText;
5854 				case TEST_TYPE_INSTANCE_CUSTOM_INDEX:													return TestConfigurationInstanceCustomIndex::getShaderBodyText;
5855 				case TEST_TYPE_INTERSECTION_T_KHR:														return TestConfigurationIntersectionT::getShaderBodyText;
5856 				case TEST_TYPE_OBJECT_RAY_ORIGIN_KHR:													return TestConfigurationObjectRayOrigin::getShaderBodyText;
5857 				case TEST_TYPE_OBJECT_RAY_DIRECTION_KHR:												return TestConfigurationObjectRayDirection::getShaderBodyText;
5858 				case TEST_TYPE_OBJECT_TO_WORLD_KHR:														return TestConfigurationObjectToWorld::getShaderBodyText;
5859 				case TEST_TYPE_WORLD_TO_OBJECT_KHR:														return TestConfigurationWorldToObject::getShaderBodyText;
5860 				case TEST_TYPE_NULL_ACCELERATION_STRUCTURE:												return TestConfigurationNullASStruct::getShaderBodyText;
5861 				case TEST_TYPE_USING_WRAPPER_FUNCTION:													return TestConfigurationUsingWrapperFunction::getShaderBodyText;
5862 				case TEST_TYPE_GET_RAY_TMIN:															return TestConfigurationGetRayTMin::getShaderBodyText;
5863 				case TEST_TYPE_GET_WORLD_RAY_ORIGIN:													return TestConfigurationGetWorldRayOrigin::getShaderBodyText;
5864 				case TEST_TYPE_GET_WORLD_RAY_DIRECTION:													return TestConfigurationGetWorldRayDirection::getShaderBodyText;;
5865 				case TEST_TYPE_GET_INTERSECTION_CANDIDATE_AABB_OPAQUE:									return TestConfigurationGetIntersectionCandidateAABBOpaque::getShaderBodyText;
5866 				case TEST_TYPE_GET_INTERSECTION_FRONT_FACE_CANDIDATE:									return TestConfigurationGetIntersectionFrontFace::getShaderBodyTextCandidate;
5867 				case TEST_TYPE_GET_INTERSECTION_FRONT_FACE_COMMITTED:									return TestConfigurationGetIntersectionFrontFace::getShaderBodyTextCommitted;
5868 				case TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_CANDIDATE:								return TestConfigurationGetIntersectionGeometryIndex::getShaderBodyTextCandidate;
5869 				case TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_COMMITTED:								return TestConfigurationGetIntersectionGeometryIndex::getShaderBodyTextCommitted;
5870 				case TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_CANDIDATE:									return TestConfigurationGetIntersectionBarycentrics::getShaderBodyTextCandidate;
5871 				case TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_COMMITTED:									return TestConfigurationGetIntersectionBarycentrics::getShaderBodyTextCommitted;
5872 				case TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_CANDIDATE:	return TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset::getShaderBodyTextCandidate;
5873 				case TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_COMMITTED:	return TestConfigurationGetIntersectionInstanceShaderBindingTableRecordOffset::getShaderBodyTextCommitted;
5874 				case TEST_TYPE_RAY_QUERY_TERMINATE:														return TestConfigurationRayQueryTerminate::getShaderBodyText;
5875 				case TEST_TYPE_GET_INTERSECTION_TYPE_CANDIDATE:											return TestConfigurationGetIntersectionType::getShaderBodyTextCandidate;
5876 				case TEST_TYPE_GET_INTERSECTION_TYPE_COMMITTED:											return TestConfigurationGetIntersectionType::getShaderBodyTextCommitted;
5877 
5878 				default:									TCU_THROW(InternalError, "Unknown test type");
5879 				}
5880 			}
5881 
getTestConfigCheckSupport(const TestType testType)5882 			static inline CheckSupportFunc getTestConfigCheckSupport(const TestType testType)
5883 			{
5884 				if (testType >= TEST_TYPE_LAST)
5885 					TCU_THROW(InternalError, "Unknown test type");
5886 
5887 				switch (testType)
5888 				{
5889 				case TEST_TYPE_NULL_ACCELERATION_STRUCTURE:	return TestConfigurationNullASStruct::checkSupport;
5890 				default:									return DE_NULL;
5891 				}
5892 			}
5893 
5894 		}	// anonymous
5895 
5896 		const struct PipelineStages
5897 		{
5898 			VkShaderStageFlagBits	stage;
5899 			const char* name;
5900 		}
5901 		pipelineStages[] =
5902 		{
5903 			{ VK_SHADER_STAGE_VERTEX_BIT,					"vert"	},
5904 			{ VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,		"tesc"	},
5905 			{ VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,	"tese"	},
5906 			{ VK_SHADER_STAGE_GEOMETRY_BIT,					"geom"	},
5907 			{ VK_SHADER_STAGE_FRAGMENT_BIT,					"frag"	},
5908 			{ VK_SHADER_STAGE_COMPUTE_BIT,					"comp"	},
5909 			{ VK_SHADER_STAGE_RAYGEN_BIT_KHR,				"rgen"	},
5910 			{ VK_SHADER_STAGE_ANY_HIT_BIT_KHR,				"ahit"	},
5911 			{ VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,			"chit"	},
5912 			{ VK_SHADER_STAGE_MISS_BIT_KHR,					"miss"	},
5913 			{ VK_SHADER_STAGE_INTERSECTION_BIT_KHR,			"sect"	},
5914 			{ VK_SHADER_STAGE_CALLABLE_BIT_KHR,				"call"	},
5915 		};
5916 
5917 		const struct GeomTypes
5918 		{
5919 			GeomType	geomType;
5920 			const char* name;
5921 		}
5922 		geomTypes[] =
5923 		{
5924 			{ GEOM_TYPE_TRIANGLES,							"triangles" },
5925 			{ GEOM_TYPE_AABBS,								"aabbs" },
5926 		};
5927 
createBuiltinTests(tcu::TestContext & testCtx)5928 		tcu::TestCaseGroup* createBuiltinTests(tcu::TestContext& testCtx)
5929 		{
5930 			de::MovePtr<tcu::TestCaseGroup>		group(new tcu::TestCaseGroup(testCtx, "builtin", "Tests verifying builtins provided by ray query"));
5931 
5932 			const struct TestTypes
5933 			{
5934 				TestType	testType;
5935 				const char* name;
5936 			}
5937 			testTypes[] =
5938 			{
5939 				{ TEST_TYPE_FLOW,																	"flow"															},
5940 				{ TEST_TYPE_PRIMITIVE_ID,															"primitiveid"													},
5941 				{ TEST_TYPE_INSTANCE_ID,															"instanceid"													},
5942 				{ TEST_TYPE_INSTANCE_CUSTOM_INDEX,													"instancecustomindex"											},
5943 				{ TEST_TYPE_INTERSECTION_T_KHR,														"intersectiont"													},
5944 				{ TEST_TYPE_OBJECT_RAY_ORIGIN_KHR,													"objectrayorigin"												},
5945 				{ TEST_TYPE_OBJECT_RAY_DIRECTION_KHR,												"objectraydirection"											},
5946 				{ TEST_TYPE_OBJECT_TO_WORLD_KHR,													"objecttoworld"													},
5947 				{ TEST_TYPE_WORLD_TO_OBJECT_KHR,													"worldtoobject"													},
5948 				{ TEST_TYPE_GET_RAY_TMIN,															"getraytmin"													},
5949 				{ TEST_TYPE_GET_WORLD_RAY_ORIGIN,													"getworldrayorigin"												},
5950 				{ TEST_TYPE_GET_WORLD_RAY_DIRECTION,												"getworldraydirection"											},
5951 				{ TEST_TYPE_GET_INTERSECTION_CANDIDATE_AABB_OPAQUE,									"getintersectioncandidateaabbopaque"							},
5952 				{ TEST_TYPE_GET_INTERSECTION_FRONT_FACE_CANDIDATE,									"getintersectionfrontfaceCandidate"								},
5953 				{ TEST_TYPE_GET_INTERSECTION_FRONT_FACE_COMMITTED,									"getintersectionfrontfaceCommitted"								},
5954 				{ TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_CANDIDATE,								"getintersectiongeometryindexCandidate"							},
5955 				{ TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_COMMITTED,								"getintersectiongeometryindexCommitted"							},
5956 				{ TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_CANDIDATE,								"getintersectionbarycentricsCandidate"							},
5957 				{ TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_COMMITTED,								"getintersectionbarycentricsCommitted"							},
5958 				{ TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_CANDIDATE,	"getintersectioninstanceshaderbindingtablerecordoffsetCandidate"},
5959 				{ TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_COMMITTED,	"getintersectioninstanceshaderbindingtablerecordoffsetCommitted"},
5960 				{ TEST_TYPE_RAY_QUERY_TERMINATE,													"rayqueryterminate"},
5961 				{ TEST_TYPE_GET_INTERSECTION_TYPE_CANDIDATE,										"getintersectiontypeCandidate"},
5962 				{ TEST_TYPE_GET_INTERSECTION_TYPE_COMMITTED,										"getintersectiontypeCommitted"},
5963 
5964 			};
5965 
5966 			for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
5967 			{
5968 				de::MovePtr<tcu::TestCaseGroup>	testTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), testTypes[testTypeNdx].name, ""));
5969 				const TestType					testType = testTypes[testTypeNdx].testType;
5970 				const ShaderBodyTextFunc		testConfigShaderBodyTextFunc = getShaderBodyTextFunc(testType);
5971 				const bool						fixedPointVectorOutput = testType == TEST_TYPE_OBJECT_RAY_ORIGIN_KHR
5972 					|| testType == TEST_TYPE_OBJECT_RAY_DIRECTION_KHR
5973 					|| testType == TEST_TYPE_GET_WORLD_RAY_ORIGIN
5974 					|| testType == TEST_TYPE_GET_WORLD_RAY_DIRECTION
5975 					|| testType == TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_CANDIDATE
5976 					|| testType == TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_COMMITTED
5977 					|| testType == TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_CANDIDATE
5978 					|| testType == TEST_TYPE_GET_INTERSECTION_INSTANCE_SHADER_BINDING_TABLE_RECORD_OFFSET_COMMITTED;
5979 				const bool						fixedPointMatrixOutput = testType == TEST_TYPE_OBJECT_TO_WORLD_KHR
5980 					|| testType == TEST_TYPE_WORLD_TO_OBJECT_KHR;
5981 				const bool						single = testTypeNdx == TEST_TYPE_FLOW
5982 					|| testType == TEST_TYPE_OBJECT_RAY_ORIGIN_KHR
5983 					|| testType == TEST_TYPE_OBJECT_RAY_DIRECTION_KHR
5984 					|| testType == TEST_TYPE_OBJECT_TO_WORLD_KHR
5985 					|| testType == TEST_TYPE_WORLD_TO_OBJECT_KHR
5986 					|| testType == TEST_TYPE_GET_RAY_TMIN
5987 					|| testType == TEST_TYPE_GET_WORLD_RAY_ORIGIN
5988 					|| testType == TEST_TYPE_GET_WORLD_RAY_DIRECTION
5989 					|| testType == TEST_TYPE_GET_INTERSECTION_CANDIDATE_AABB_OPAQUE
5990 					|| testType == TEST_TYPE_GET_INTERSECTION_FRONT_FACE_CANDIDATE
5991 					|| testType == TEST_TYPE_GET_INTERSECTION_FRONT_FACE_COMMITTED
5992 					|| testType == TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_CANDIDATE
5993 					|| testType == TEST_TYPE_GET_INTERSECTION_GEOMETRY_INDEX_COMMITTED
5994 					|| testType == TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_CANDIDATE
5995 					|| testType == TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_COMMITTED
5996 					|| testType == TEST_TYPE_RAY_QUERY_TERMINATE;
5997 				const deUint32					imageDepth = fixedPointMatrixOutput ? 4 * 4
5998 					: fixedPointVectorOutput ? 4
5999 					: 1;
6000 
6001 				for (size_t pipelineStageNdx = 0; pipelineStageNdx < DE_LENGTH_OF_ARRAY(pipelineStages); ++pipelineStageNdx)
6002 				{
6003 					de::MovePtr<tcu::TestCaseGroup>	sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), pipelineStages[pipelineStageNdx].name, ""));
6004 					const VkShaderStageFlagBits		stage = pipelineStages[pipelineStageNdx].stage;
6005 					const CheckSupportFunc			pipelineCheckSupport = getPipelineCheckSupport(stage);
6006 					const InitProgramsFunc			pipelineInitPrograms = getPipelineInitPrograms(stage);
6007 					const deUint32					instancesGroupCount = single ? 1 : 2;
6008 					const deUint32					geometriesGroupCount = single ? 1 : 8;
6009 					const deUint32					squaresGroupCount = (TEST_WIDTH * TEST_HEIGHT) / geometriesGroupCount / instancesGroupCount;
6010 
6011 					DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == TEST_WIDTH * TEST_HEIGHT);
6012 
6013 					for (size_t geomTypeNdx = 0; geomTypeNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypeNdx)
6014 					{
6015 						const GeomType		geomType = geomTypes[geomTypeNdx].geomType;
6016 						const TestParams	testParams =
6017 						{
6018 							TEST_WIDTH,						//  deUint32				width;
6019 							TEST_HEIGHT,					//  deUint32				height;
6020 							imageDepth,						//  deUint32				depth;
6021 							testType,						//  TestType				testType;
6022 							stage,							//  VkShaderStageFlagBits	stage;
6023 							geomType,						//  GeomType				geomType;
6024 							squaresGroupCount,				//  deUint32				squaresGroupCount;
6025 							geometriesGroupCount,			//  deUint32				geometriesGroupCount;
6026 							instancesGroupCount,			//  deUint32				instancesGroupCount;
6027 							VK_FORMAT_R32_SINT,				//  VkFormat				format;
6028 							pipelineCheckSupport,			//  CheckSupportFunc		pipelineCheckSupport;
6029 							pipelineInitPrograms,			//  InitProgramsFunc		pipelineInitPrograms;
6030 							testConfigShaderBodyTextFunc,	//  ShaderTestTextFunc		testConfigShaderBodyText;
6031 							false,							//  bool					isSPIRV;
6032 							DE_NULL,						//  CheckSupportFunc		testConfigCheckSupport;
6033 						};
6034 
6035 						if (geomType != GEOM_TYPE_AABBS &&
6036 							testType == TEST_TYPE_GET_INTERSECTION_CANDIDATE_AABB_OPAQUE)
6037 						{
6038 							continue;
6039 						}
6040 
6041 						if (geomType != GEOM_TYPE_TRIANGLES &&
6042 							(testType == TEST_TYPE_GET_INTERSECTION_FRONT_FACE_CANDIDATE ||
6043 								testType == TEST_TYPE_GET_INTERSECTION_FRONT_FACE_COMMITTED ||
6044 								testType == TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_CANDIDATE ||
6045 								testType == TEST_TYPE_GET_INTERSECTION_BARYCENTRICS_COMMITTED))
6046 						{
6047 							continue;
6048 						}
6049 
6050 						sourceTypeGroup->addChild(new RayQueryBuiltinTestCase(group->getTestContext(), geomTypes[geomTypeNdx].name, "", testParams));
6051 					}
6052 
6053 					testTypeGroup->addChild(sourceTypeGroup.release());
6054 				}
6055 
6056 				group->addChild(testTypeGroup.release());
6057 			}
6058 
6059 			return group.release();
6060 		}
6061 
createAdvancedTests(tcu::TestContext & testCtx)6062 		tcu::TestCaseGroup* createAdvancedTests(tcu::TestContext& testCtx)
6063 		{
6064 			de::MovePtr<tcu::TestCaseGroup>		group(new tcu::TestCaseGroup(testCtx, "advanced", "Advanced ray query tests"));
6065 
6066 			const struct TestTypes
6067 			{
6068 				TestType	testType;
6069 				const char* name;
6070 			}
6071 			testTypes[] =
6072 			{
6073 				{ TEST_TYPE_NULL_ACCELERATION_STRUCTURE,	"null_as"					},
6074 				{ TEST_TYPE_USING_WRAPPER_FUNCTION,			"using_wrapper_function"	}
6075 			};
6076 
6077 			for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
6078 			{
6079 				de::MovePtr<tcu::TestCaseGroup>	testTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), testTypes[testTypeNdx].name, ""));
6080 				const TestType					testType = testTypes[testTypeNdx].testType;
6081 				const ShaderBodyTextFunc		testConfigShaderBodyTextFunc = getShaderBodyTextFunc(testType);
6082 				const CheckSupportFunc			testConfigCheckSupport = getTestConfigCheckSupport(testType);
6083 				const deUint32					imageDepth = 1;
6084 				bool							useSPIRV = false;
6085 
6086 				for (size_t pipelineStageNdx = 0; pipelineStageNdx < DE_LENGTH_OF_ARRAY(pipelineStages); ++pipelineStageNdx)
6087 				{
6088 					const VkShaderStageFlagBits stage = pipelineStages[pipelineStageNdx].stage;
6089 
6090 					// tests that are implemented using spirv are limit to compute stage
6091 					if (testType == TEST_TYPE_USING_WRAPPER_FUNCTION)
6092 					{
6093 						if (stage != VK_SHADER_STAGE_COMPUTE_BIT)
6094 							continue;
6095 						useSPIRV = true;
6096 					}
6097 
6098 					de::MovePtr<tcu::TestCaseGroup>	sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), pipelineStages[pipelineStageNdx].name, ""));
6099 					const CheckSupportFunc			pipelineCheckSupport = getPipelineCheckSupport(stage);
6100 					const InitProgramsFunc			pipelineInitPrograms = getPipelineInitPrograms(stage);
6101 					const deUint32					instancesGroupCount = 1;
6102 					const deUint32					geometriesGroupCount = 1;
6103 					const deUint32					squaresGroupCount = (TEST_WIDTH * TEST_HEIGHT) / geometriesGroupCount / instancesGroupCount;
6104 
6105 					DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == TEST_WIDTH * TEST_HEIGHT);
6106 
6107 					for (size_t geomTypeNdx = 0; geomTypeNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypeNdx)
6108 					{
6109 						const GeomType		geomType = geomTypes[geomTypeNdx].geomType;
6110 						const TestParams	testParams =
6111 						{
6112 							TEST_WIDTH,						//  deUint32				width;
6113 							TEST_HEIGHT,					//  deUint32				height;
6114 							imageDepth,						//  deUint32				depth;
6115 							testType,						//  TestType				testType;
6116 							stage,							//  VkShaderStageFlagBits	stage;
6117 							geomType,						//  GeomType				geomType;
6118 							squaresGroupCount,				//  deUint32				squaresGroupCount;
6119 							geometriesGroupCount,			//  deUint32				geometriesGroupCount;
6120 							instancesGroupCount,			//  deUint32				instancesGroupCount;
6121 							VK_FORMAT_R32_SINT,				//  VkFormat				format;
6122 							pipelineCheckSupport,			//  CheckSupportFunc		pipelineCheckSupport;
6123 							pipelineInitPrograms,			//  InitProgramsFunc		pipelineInitPrograms;
6124 							testConfigShaderBodyTextFunc,	//  ShaderTestTextFunc		testConfigShaderBodyText;
6125 							useSPIRV,						//  bool					isSPIRV;
6126 							testConfigCheckSupport,			//  CheckSupportFunc		testConfigCheckSupport;
6127 						};
6128 
6129 						sourceTypeGroup->addChild(new RayQueryBuiltinTestCase(group->getTestContext(), geomTypes[geomTypeNdx].name, "", testParams));
6130 					}
6131 
6132 					testTypeGroup->addChild(sourceTypeGroup.release());
6133 				}
6134 
6135 				group->addChild(testTypeGroup.release());
6136 			}
6137 
6138 			return group.release();
6139 		}
6140 
6141 	}	// RayQuery
6142 }	// vkt
6143