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