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