• 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 "vktRayQueryWatertightnessTests.hpp"
25 
26 #include "vkDefs.hpp"
27 
28 #include "vktTestCase.hpp"
29 #include "vktTestGroupUtil.hpp"
30 #include "vkCmdUtil.hpp"
31 #include "vkObjUtil.hpp"
32 #include "vkBuilderUtil.hpp"
33 #include "vkBarrierUtil.hpp"
34 #include "vkBufferWithMemory.hpp"
35 #include "vkImageWithMemory.hpp"
36 #include "vkTypeUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "deRandom.hpp"
39 #include "tcuTexture.hpp"
40 #include "tcuTextureUtil.hpp"
41 #include "tcuTestLog.hpp"
42 #include "tcuImageCompare.hpp"
43 #include "tcuCommandLine.hpp"
44 
45 #include "vkRayTracingUtil.hpp"
46 
47 namespace vkt
48 {
49 namespace RayQuery
50 {
51 namespace
52 {
53 using namespace vk;
54 using namespace vkt;
55 
56 static const VkFlags	ALL_RAY_TRACING_STAGES	= VK_SHADER_STAGE_RAYGEN_BIT_KHR
57 												| VK_SHADER_STAGE_ANY_HIT_BIT_KHR
58 												| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
59 												| VK_SHADER_STAGE_MISS_BIT_KHR
60 												| VK_SHADER_STAGE_INTERSECTION_BIT_KHR
61 												| VK_SHADER_STAGE_CALLABLE_BIT_KHR;
62 
63 enum TestType
64 {
65 	TEST_TYPE_NO_MISS		= 0,
66 	TEST_TYPE_SINGLE_HIT,
67 };
68 
69 enum GeomType
70 {
71 	GEOM_TYPE_TRIANGLES,
72 	GEOM_TYPE_AABBS,
73 	GEOM_TYPE_LAST,
74 };
75 
76 const deUint32	TEST_WIDTH					= 256u;
77 const deUint32	TEST_HEIGHT					= 256u;
78 const float		MIN_AABB_SIDE_LENGTH		= 1e-6f;
79 const float		MIN_TRIANGLE_EDGE_LENGTH	= 1.0f / float(10 * TEST_WIDTH * TEST_HEIGHT);
80 const float		MIN_TRIANGLE_AREA_SIZE		= 1.0f / float(10 * TEST_WIDTH * TEST_HEIGHT);
81 
82 struct TestParams;
83 
84 typedef void (*CheckSupportFunc)(Context& context, const TestParams& testParams);
85 typedef void (*InitProgramsFunc)(SourceCollections& programCollection, const TestParams& testParams);
86 typedef const std::string (*ShaderBodyTextFunc)(const TestParams& testParams);
87 
88 class PipelineConfiguration
89 {
90 public:
PipelineConfiguration()91 					PipelineConfiguration	()	{}
~PipelineConfiguration()92 	virtual			~PipelineConfiguration	()	{}
93 
94 	virtual void	initConfiguration	(Context&							context,
95 										 TestParams&						testParams) = 0;
96 	virtual void	fillCommandBuffer	(Context&							context,
97 										 TestParams&						testParams,
98 										 VkCommandBuffer					commandBuffer,
99 										 const VkAccelerationStructureKHR*	rayQueryTopAccelerationStructurePtr,
100 										 const VkDescriptorImageInfo&		resultImageInfo) = 0;
101 };
102 
103 class TestConfiguration
104 {
105 public:
TestConfiguration()106 																	TestConfiguration				()
107 																		: m_bottomAccelerationStructures	()
108 																		, m_topAccelerationStructure		()
109 																		, m_expected						()
110 																	{
111 																	}
~TestConfiguration()112 	virtual															~TestConfiguration				()
113 																	{
114 																	}
115 
116 	virtual const VkAccelerationStructureKHR*						initAccelerationStructures		(Context&							context,
117 																									 TestParams&						testParams,
118 																									 VkCommandBuffer					cmdBuffer) = 0;
119 	virtual bool													verify							(BufferWithMemory*					resultBuffer,
120 																									 Context&							context,
121 																									 TestParams&						testParams) = 0;
122 
123 protected:
124 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	m_bottomAccelerationStructures;
125 	de::SharedPtr<TopLevelAccelerationStructure>					m_topAccelerationStructure;
126 	std::vector<deInt32>											m_expected;
127 };
128 
129 struct TestParams
130 {
131 	deUint32				width;
132 	deUint32				height;
133 	deUint32				depth;
134 	deUint32				randomSeed;
135 	TestType				testType;
136 	VkShaderStageFlagBits	stage;
137 	GeomType				geomType;
138 	deUint32				squaresGroupCount;
139 	deUint32				geometriesGroupCount;
140 	deUint32				instancesGroupCount;
141 	VkFormat				format;
142 	CheckSupportFunc		pipelineCheckSupport;
143 	InitProgramsFunc		pipelineInitPrograms;
144 	ShaderBodyTextFunc		testConfigShaderBodyText;
145 };
146 
getShaderGroupHandleSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)147 deUint32 getShaderGroupHandleSize (const InstanceInterface&	vki,
148 								   const VkPhysicalDevice	physicalDevice)
149 {
150 	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
151 
152 	rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physicalDevice);
153 
154 	return rayTracingPropertiesKHR->getShaderGroupHandleSize();
155 }
156 
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)157 deUint32 getShaderGroupBaseAlignment (const InstanceInterface&	vki,
158 									  const VkPhysicalDevice	physicalDevice)
159 {
160 	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
161 
162 	rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
163 
164 	return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
165 }
166 
getVkBuffer(const de::MovePtr<BufferWithMemory> & buffer)167 VkBuffer getVkBuffer (const de::MovePtr<BufferWithMemory>& buffer)
168 {
169 	VkBuffer result = (buffer.get() == DE_NULL) ? DE_NULL : buffer->get();
170 
171 	return result;
172 }
173 
makeStridedDeviceAddressRegion(const DeviceInterface & vkd,const VkDevice device,VkBuffer buffer,VkDeviceSize size)174 VkStridedDeviceAddressRegionKHR makeStridedDeviceAddressRegion (const DeviceInterface& vkd, const VkDevice device, VkBuffer buffer, VkDeviceSize size)
175 {
176 	const VkDeviceSize sizeFixed = ((buffer == DE_NULL) ? 0ull : size);
177 
178 	return makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, buffer, 0), sizeFixed, sizeFixed);
179 }
180 
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)181 VkImageCreateInfo makeImageCreateInfo (VkFormat				format,
182 									   deUint32				width,
183 									   deUint32				height,
184 									   deUint32				depth,
185 									   VkImageType			imageType	= VK_IMAGE_TYPE_3D,
186 									   VkImageUsageFlags	usageFlags	= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
187 {
188 	const VkImageCreateInfo	imageCreateInfo	=
189 	{
190 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType;
191 		DE_NULL,								// const void*				pNext;
192 		(VkImageCreateFlags)0u,					// VkImageCreateFlags		flags;
193 		imageType,								// VkImageType				imageType;
194 		format,									// VkFormat					format;
195 		makeExtent3D(width, height, depth),		// VkExtent3D				extent;
196 		1u,										// deUint32					mipLevels;
197 		1u,										// deUint32					arrayLayers;
198 		VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples;
199 		VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling;
200 		usageFlags,								// VkImageUsageFlags		usage;
201 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode;
202 		0u,										// deUint32					queueFamilyIndexCount;
203 		DE_NULL,								// const deUint32*			pQueueFamilyIndices;
204 		VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout;
205 	};
206 
207 	return imageCreateInfo;
208 }
209 
getMissPassthrough(void)210 static const std::string getMissPassthrough (void)
211 {
212 	const std::string missPassthrough =
213 		"#version 460 core\n"
214 		"#extension GL_EXT_ray_tracing : require\n"
215 		"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
216 		"\n"
217 		"void main()\n"
218 		"{\n"
219 		"}\n";
220 
221 	return missPassthrough;
222 }
223 
getHitPassthrough(void)224 static const std::string getHitPassthrough (void)
225 {
226 	const std::string hitPassthrough =
227 		"#version 460 core\n"
228 		"#extension GL_EXT_ray_tracing : require\n"
229 		"hitAttributeEXT vec3 attribs;\n"
230 		"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
231 		"\n"
232 		"void main()\n"
233 		"{\n"
234 		"}\n";
235 
236 	return hitPassthrough;
237 }
238 
getGraphicsPassthrough(void)239 static const std::string getGraphicsPassthrough (void)
240 {
241 	std::ostringstream src;
242 
243 	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
244 		<< "\n"
245 		<< "void main(void)\n"
246 		<< "{\n"
247 		<< "}\n";
248 
249 	return src.str();
250 }
251 
getVertexPassthrough(void)252 static const std::string getVertexPassthrough (void)
253 {
254 	std::ostringstream src;
255 
256 	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
257 		<< "\n"
258 		<< "layout(location = 0) in vec4 in_position;\n"
259 		<< "\n"
260 		<< "void main(void)\n"
261 		<< "{\n"
262 		<< "  gl_Position = in_position;\n"
263 		<< "}\n";
264 
265 	return src.str();
266 }
267 
mixVec2(const tcu::Vec2 & a,const tcu::Vec2 & b,const float alpha)268 static inline tcu::Vec2 mixVec2 (const tcu::Vec2& a, const tcu::Vec2& b, const float alpha)
269 {
270 	const tcu::Vec2 result = a * alpha + b * (1.0f - alpha);
271 
272 	return result;
273 }
274 
mixCoordsVec2(const tcu::Vec2 & a,const tcu::Vec2 & b,const float alpha,const float beta)275 static inline tcu::Vec2 mixCoordsVec2 (const tcu::Vec2& a, const tcu::Vec2& b, const float alpha, const float beta)
276 {
277 	const tcu::Vec2	result	= tcu::Vec2(deFloatMix(a.x(), b.x(), alpha), deFloatMix(a.y(), b.y(), beta));
278 
279 	return result;
280 }
281 
triangleEdgeLength(const tcu::Vec2 & vertexA,const tcu::Vec2 & vertexB)282 inline float triangleEdgeLength (const tcu::Vec2& vertexA, const tcu::Vec2& vertexB)
283 {
284 	const float	abx	= vertexA.x() - vertexB.x();
285 	const float	aby	= vertexA.y() - vertexB.y();
286 	const float abq	= abx * abx + aby * aby;
287 	const float	ab	= deFloatSqrt(abq);
288 
289 	return ab;
290 }
291 
triangleArea(const float edgeALen,const float edgeBLen,const float edgeCLen)292 inline float triangleArea (const float edgeALen, const float edgeBLen, const float edgeCLen)
293 {
294 	const float	s	= (edgeALen + edgeBLen + edgeCLen) / 2.0f;
295 	const float	q	= s * (s - edgeALen) * (s - edgeBLen) * (s - edgeCLen);
296 
297 	if (q <= 0.0f)
298 		return 0.0f;
299 
300 	return deFloatSqrt(q);
301 }
302 
303 class GraphicsConfiguration : public PipelineConfiguration
304 {
305 public:
306 	static void						checkSupport			(Context&							context,
307 															 const TestParams&					testParams);
308 	static void						initPrograms			(SourceCollections&					programCollection,
309 															 const TestParams&					testParams);
310 
311 									GraphicsConfiguration	();
~GraphicsConfiguration()312 	virtual							~GraphicsConfiguration	() {}
313 
314 	void							initVertexBuffer		(Context&							context,
315 															 TestParams&						testParams);
316 	Move<VkPipeline>				makeGraphicsPipeline	(Context&							context,
317 															 TestParams&						testParams);
318 	virtual void					initConfiguration		(Context&							context,
319 															 TestParams&						testParams) override;
320 	virtual void					fillCommandBuffer		(Context&							context,
321 															 TestParams&						testParams,
322 															 VkCommandBuffer					commandBuffer,
323 															 const VkAccelerationStructureKHR*	rayQueryTopAccelerationStructurePtr,
324 															 const VkDescriptorImageInfo&		resultImageInfo) override;
325 
326 private:
327 	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
328 	Move<VkDescriptorPool>			m_descriptorPool;
329 	Move<VkDescriptorSet>			m_descriptorSet;
330 
331 	VkFormat						m_framebufferFormat;
332 	Move<VkImage>					m_framebufferImage;
333 	de::MovePtr<Allocation>			m_framebufferImageAlloc;
334 	Move<VkImageView>				m_framebufferAttachment;
335 
336 	Move<VkShaderModule>			m_vertShaderModule;
337 	Move<VkShaderModule>			m_geomShaderModule;
338 	Move<VkShaderModule>			m_tescShaderModule;
339 	Move<VkShaderModule>			m_teseShaderModule;
340 	Move<VkShaderModule>			m_fragShaderModule;
341 
342 	Move<VkRenderPass>				m_renderPass;
343 	Move<VkFramebuffer>				m_framebuffer;
344 	Move<VkPipelineLayout>			m_pipelineLayout;
345 	Move<VkPipeline>				m_pipeline;
346 
347 	deUint32						m_vertexCount;
348 	Move<VkBuffer>					m_vertexBuffer;
349 	de::MovePtr<Allocation>			m_vertexBufferAlloc;
350 };
351 
GraphicsConfiguration()352 GraphicsConfiguration::GraphicsConfiguration()
353 	: PipelineConfiguration		()
354 	, m_descriptorSetLayout		()
355 	, m_descriptorPool			()
356 	, m_descriptorSet			()
357 	, m_framebufferFormat		(VK_FORMAT_R8G8B8A8_UNORM)
358 	, m_framebufferImage		()
359 	, m_framebufferImageAlloc	()
360 	, m_framebufferAttachment	()
361 	, m_vertShaderModule		()
362 	, m_geomShaderModule		()
363 	, m_tescShaderModule		()
364 	, m_teseShaderModule		()
365 	, m_fragShaderModule		()
366 	, m_renderPass				()
367 	, m_framebuffer				()
368 	, m_pipelineLayout			()
369 	, m_pipeline				()
370 	, m_vertexCount				(0)
371 	, m_vertexBuffer			()
372 	, m_vertexBufferAlloc		()
373 {
374 }
375 
checkSupport(Context & context,const TestParams & testParams)376 void GraphicsConfiguration::checkSupport (Context&			context,
377 										  const TestParams&	testParams)
378 {
379 	switch (testParams.stage)
380 	{
381 	case VK_SHADER_STAGE_VERTEX_BIT:
382 	case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
383 	case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
384 	case VK_SHADER_STAGE_GEOMETRY_BIT:
385 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
386 		break;
387 	default:
388 		break;
389 	}
390 
391 	switch (testParams.stage)
392 	{
393 	case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
394 	case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
395 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
396 		break;
397 	case VK_SHADER_STAGE_GEOMETRY_BIT:
398 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
399 		break;
400 	default:
401 		break;
402 	}
403 }
404 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)405 void GraphicsConfiguration::initPrograms (SourceCollections&	programCollection,
406 										  const TestParams&		testParams)
407 {
408 	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
409 	const std::string				testShaderBody	= testParams.testConfigShaderBodyText(testParams);
410 
411 	switch (testParams.stage)
412 	{
413 		case VK_SHADER_STAGE_VERTEX_BIT:
414 		{
415 			{
416 				std::ostringstream src;
417 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
418 					<< "#extension GL_EXT_ray_query : require\n"
419 					<< "#extension GL_EXT_ray_tracing : require\n"
420 					<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
421 					<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
422 					<< "\n"
423 					<< "void testFunc(ivec3 pos, ivec3 size)\n"
424 					<< "{\n"
425 					<< testShaderBody
426 					<< "}\n"
427 					<< "\n"
428 					<< "void main(void)\n"
429 					<< "{\n"
430 					<< "  const int   posId    = int(gl_VertexIndex / 3);\n"
431 					<< "  const int   vertId   = int(gl_VertexIndex % 3);\n"
432 					<< "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
433 					<< "  const ivec3 pos      = ivec3(posId % size.x, posId / size.x, 0);\n"
434 					<< "\n"
435 					<< "  if (vertId == 0)\n"
436 					<< "  {\n"
437 					<< "    testFunc(pos, size);\n"
438 					<< "  }\n"
439 					<< "}\n";
440 
441 				programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
442 			}
443 
444 			programCollection.glslSources.add("frag") << glu::FragmentSource(getGraphicsPassthrough()) << buildOptions;
445 
446 			break;
447 		}
448 
449 		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
450 		{
451 			{
452 				std::ostringstream src;
453 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
454 					<< "\n"
455 					<< "layout(location = 0) in vec4 in_position;\n"
456 					<< "out gl_PerVertex\n"
457 					<< "{\n"
458 					<< "  vec4 gl_Position;\n"
459 					<< "};\n"
460 					<< "\n"
461 					<< "void main(void)\n"
462 					<< "{\n"
463 					<< "  gl_Position = in_position;\n"
464 					<< "}\n";
465 
466 				programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
467 			}
468 
469 			{
470 				std::ostringstream src;
471 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
472 					<< "#extension GL_EXT_tessellation_shader : require\n"
473 					<< "#extension GL_EXT_ray_query : require\n"
474 					<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
475 					<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
476 					<< "in gl_PerVertex\n"
477 					<< "{\n"
478 					<< "  vec4 gl_Position;\n"
479 					<< "} gl_in[];\n"
480 					<< "layout(vertices = 3) out;\n"
481 					<< "out gl_PerVertex\n"
482 					<< "{\n"
483 					<< "  vec4 gl_Position;\n"
484 					<< "} gl_out[];\n"
485 					<< "\n"
486 					<< "void testFunc(ivec3 pos, ivec3 size)\n"
487 					<< "{\n"
488 					<< testShaderBody
489 					<< "}\n"
490 					<< "\n"
491 					<< "void main(void)\n"
492 					<< "{\n"
493 					<< "\n"
494 					<< "  if (gl_InvocationID == 0)\n"
495 					<< "  {\n"
496 					<< "    const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
497 					<< "    int index = int(gl_in[gl_InvocationID].gl_Position.z);\n"
498 					<< "    int x = index % size.x;\n"
499 					<< "    int y = index / size.y;\n"
500 					<< "    const ivec3 pos = ivec3(x, y, 0);\n"
501 					<< "    testFunc(pos, size);\n"
502 					<< "  }\n"
503 					<< "\n"
504 					<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
505 					<< "  gl_TessLevelInner[0] = 1;\n"
506 					<< "  gl_TessLevelInner[1] = 1;\n"
507 					<< "  gl_TessLevelOuter[gl_InvocationID] = 1;\n"
508 					<< "}\n";
509 
510 				programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions;
511 			}
512 
513 			{
514 				std::ostringstream src;
515 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
516 					<< "#extension GL_EXT_tessellation_shader : require\n"
517 					<< "layout(triangles, equal_spacing, ccw) in;\n"
518 					<< "in gl_PerVertex\n"
519 					<< "{\n"
520 					<< "  vec4 gl_Position;\n"
521 					<< "} gl_in[];\n"
522 					<< "\n"
523 					<< "void main(void)\n"
524 					<< "{\n"
525 					<< "  gl_Position = gl_in[0].gl_Position;\n"
526 					<< "}\n";
527 
528 				programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions;
529 			}
530 
531 			break;
532 		}
533 
534 		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
535 		{
536 			{
537 				std::ostringstream src;
538 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
539 					<< "\n"
540 					<< "layout(location = 0) in vec4 in_position;\n"
541 					<< "out gl_PerVertex"
542 					<< "{\n"
543 					<< "  vec4 gl_Position;\n"
544 					<< "};\n"
545 					<< "\n"
546 					<< "void main(void)\n"
547 					<< "{\n"
548 					<< "  gl_Position = in_position;\n"
549 					<< "}\n";
550 
551 				programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
552 			}
553 
554 			{
555 				std::ostringstream src;
556 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
557 					<< "#extension GL_EXT_tessellation_shader : require\n"
558 					<< "in gl_PerVertex\n"
559 					<< "{\n"
560 					<< "  vec4 gl_Position;\n"
561 					<< "} gl_in[];\n"
562 					<< "layout(vertices = 3) out;\n"
563 					<< "out gl_PerVertex\n"
564 					<< "{\n"
565 					<< "  vec4 gl_Position;\n"
566 					<< "} gl_out[];\n"
567 					<< "\n"
568 					<< "void main(void)\n"
569 					<< "{\n"
570 					<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
571 					<< "  gl_TessLevelInner[0] = 1;\n"
572 					<< "  gl_TessLevelInner[1] = 1;\n"
573 					<< "  gl_TessLevelOuter[gl_InvocationID] = 1;\n"
574 					<< "}\n";
575 
576 				programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions;
577 			}
578 
579 			{
580 				std::ostringstream src;
581 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
582 					<< "#extension GL_EXT_tessellation_shader : require\n"
583 					<< "#extension GL_EXT_ray_query : require\n"
584 					<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
585 					<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
586 					<< "layout(triangles, equal_spacing, ccw) in;\n"
587 					<< "in gl_PerVertex\n"
588 					<< "{\n"
589 					<< "  vec4 gl_Position;\n"
590 					<< "} gl_in[];\n"
591 					<< "\n"
592 					<< "void testFunc(ivec3 pos, ivec3 size)\n"
593 					<< "{\n"
594 					<< testShaderBody
595 					<< "}\n"
596 					<< "\n"
597 					<< "void main(void)\n"
598 					<< "{\n"
599 					<< "	const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
600 					<< "	int index = int(gl_in[0].gl_Position.z);\n"
601 					<< "	int x = index % size.x;\n"
602 					<< "	int y = index / size.y;\n"
603 					<< "	const ivec3 pos = ivec3(x, y, 0);\n"
604 					<< "	testFunc(pos, size);\n"
605 					<< "	gl_Position = gl_in[0].gl_Position;\n"
606 					<< "}\n";
607 
608 				programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions;
609 			}
610 
611 			break;
612 		}
613 
614 		case VK_SHADER_STAGE_GEOMETRY_BIT:
615 		{
616 			programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions;
617 
618 			{
619 				std::ostringstream src;
620 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
621 					<< "#extension GL_EXT_ray_query : require\n"
622 					<< "layout(triangles) in;\n"
623 					<< "layout(points, max_vertices = 1) out;\n"
624 					<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
625 					<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
626 					<< "\n"
627 					<< "void testFunc(ivec3 pos, ivec3 size)\n"
628 					<< "{\n"
629 					<< testShaderBody
630 					<< "}\n"
631 					<< "\n"
632 					<< "void main(void)\n"
633 					<< "{\n"
634 					<< "  const int   posId    = int(gl_PrimitiveIDIn);\n"
635 					<< "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
636 					<< "  const ivec3 pos      = ivec3(posId % size.x, posId / size.x, 0);\n"
637 					<< "\n"
638 					<< "  testFunc(pos, size);\n"
639 					<< "}\n";
640 
641 				programCollection.glslSources.add("geom") << glu::GeometrySource(src.str()) << buildOptions;
642 			}
643 
644 			break;
645 		}
646 
647 		case VK_SHADER_STAGE_FRAGMENT_BIT:
648 		{
649 			programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions;
650 
651 			{
652 				std::ostringstream src;
653 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
654 					<< "#extension GL_EXT_ray_query : require\n"
655 					<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
656 					<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
657 					<< "\n"
658 					<< "void testFunc(ivec3 pos, ivec3 size)\n"
659 					<< "{\n"
660 					<< testShaderBody
661 					<< "}\n"
662 					<< "\n"
663 					<< "void main(void)\n"
664 					<< "{\n"
665 					<< "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
666 					<< "  const ivec3 pos      = ivec3(int(gl_FragCoord.x - 0.5f), int(gl_FragCoord.y - 0.5f), 0);\n"
667 					<< "\n"
668 					<< "  testFunc(pos, size);\n"
669 					<< "}\n";
670 
671 				programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()) << buildOptions;
672 			}
673 
674 			break;
675 		}
676 
677 		default:
678 			TCU_THROW(InternalError, "Unknown stage");
679 	}
680 }
681 
initVertexBuffer(Context & context,TestParams & testParams)682 void GraphicsConfiguration::initVertexBuffer (Context&		context,
683 											  TestParams&	testParams)
684 {
685 	const DeviceInterface&	vkd			= context.getDeviceInterface();
686 	const VkDevice			device		= context.getDevice();
687 	const deUint32			width		= testParams.width;
688 	const deUint32			height		= testParams.height;
689 	Allocator&				allocator	= context.getDefaultAllocator();
690 	std::vector<tcu::Vec4>	vertices;
691 
692 	switch (testParams.stage)
693 	{
694 		case VK_SHADER_STAGE_VERTEX_BIT:
695 		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
696 		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
697 		{
698 			float z = 0.0f;
699 			const float w = 1.0f;
700 
701 			vertices.reserve(3 * height * width);
702 
703 			for (deUint32 y = 0; y < height; ++y)
704 			for (deUint32 x = 0; x < width; ++x)
705 			{
706 				const float	x0	= float(x + 0) / float(width);
707 				const float	y0	= float(y + 0) / float(height);
708 				const float	x1	= float(x + 1) / float(width);
709 				const float	y1	= float(y + 1) / float(height);
710 				const float	xm	= (x0 + x1) / 2.0f;
711 				const float	ym	= (y0 + y1) / 2.0f;
712 
713 				vertices.push_back(tcu::Vec4(x0, y0, z, w));
714 				vertices.push_back(tcu::Vec4(xm, y1, z, w));
715 				vertices.push_back(tcu::Vec4(x1, ym, z, w));
716 
717 				z += 1.f;
718 			}
719 
720 			break;
721 		}
722 
723 		case VK_SHADER_STAGE_GEOMETRY_BIT:
724 		{
725 			const float z = 0.0f;
726 			const float w = 1.0f;
727 
728 			vertices.reserve(3 * height * width);
729 
730 			for (deUint32 y = 0; y < height; ++y)
731 			for (deUint32 x = 0; x < width; ++x)
732 			{
733 				const float	x0	= float(x + 0) / float(width);
734 				const float	y0	= float(y + 0) / float(height);
735 				const float	x1	= float(x + 1) / float(width);
736 				const float	y1	= float(y + 1) / float(height);
737 				const float	xm	= (x0 + x1) / 2.0f;
738 				const float	ym	= (y0 + y1) / 2.0f;
739 
740 				vertices.push_back(tcu::Vec4(x0, y0, z, w));
741 				vertices.push_back(tcu::Vec4(xm, y1, z, w));
742 				vertices.push_back(tcu::Vec4(x1, ym, z, w));
743 			}
744 
745 			break;
746 		}
747 
748 		case VK_SHADER_STAGE_FRAGMENT_BIT:
749 		{
750 			const float		z = 1.0f;
751 			const float		w = 1.0f;
752 			const tcu::Vec4	a = tcu::Vec4(-1.0f, -1.0f, z, w);
753 			const tcu::Vec4	b = tcu::Vec4(+1.0f, -1.0f, z, w);
754 			const tcu::Vec4	c = tcu::Vec4(-1.0f, +1.0f, z, w);
755 			const tcu::Vec4	d = tcu::Vec4(+1.0f, +1.0f, z, w);
756 
757 			vertices.push_back(a);
758 			vertices.push_back(b);
759 			vertices.push_back(c);
760 
761 			vertices.push_back(b);
762 			vertices.push_back(c);
763 			vertices.push_back(d);
764 
765 			break;
766 		}
767 
768 		default:
769 			TCU_THROW(InternalError, "Unknown stage");
770 
771 	}
772 
773 	// Initialize vertex buffer
774 	{
775 		const VkDeviceSize			vertexBufferSize		= sizeof(vertices[0][0]) * vertices[0].SIZE * vertices.size();
776 		const VkBufferCreateInfo	vertexBufferCreateInfo	= makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
777 
778 		m_vertexCount		= static_cast<deUint32>(vertices.size());
779 		m_vertexBuffer		= createBuffer(vkd, device, &vertexBufferCreateInfo);
780 		m_vertexBufferAlloc	= bindBuffer(vkd, device, allocator, *m_vertexBuffer, vk::MemoryRequirement::HostVisible);
781 
782 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexBufferSize);
783 		flushAlloc(vkd, device, *m_vertexBufferAlloc);
784 	}
785 }
786 
makeGraphicsPipeline(Context & context,TestParams & testParams)787 Move<VkPipeline> GraphicsConfiguration::makeGraphicsPipeline (Context&		context,
788 															  TestParams&	testParams)
789 {
790 	const DeviceInterface&			vkd					= context.getDeviceInterface();
791 	const VkDevice					device				= context.getDevice();
792 	const bool						tessStageTest		= (testParams.stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || testParams.stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
793 	const VkPrimitiveTopology		topology			= tessStageTest ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
794 	const deUint32					patchControlPoints	= tessStageTest ? 3 : 0;
795 	const std::vector<VkViewport>	viewports			(1, makeViewport(testParams.width, testParams.height));
796 	const std::vector<VkRect2D>		scissors			(1, makeRect2D(testParams.width, testParams.height));
797 
798 	return vk::makeGraphicsPipeline	(vkd,
799 									 device,
800 									 *m_pipelineLayout,
801 									 *m_vertShaderModule,
802 									 *m_tescShaderModule,
803 									 *m_teseShaderModule,
804 									 *m_geomShaderModule,
805 									 *m_fragShaderModule,
806 									 *m_renderPass,
807 									 viewports,
808 									 scissors,
809 									 topology,
810 									 0,
811 									 patchControlPoints);
812 }
813 
initConfiguration(Context & context,TestParams & testParams)814 void GraphicsConfiguration::initConfiguration (Context&		context,
815 											   TestParams&	testParams)
816 {
817 	const DeviceInterface&	vkd			= context.getDeviceInterface();
818 	const VkDevice			device		= context.getDevice();
819 	Allocator&				allocator	= context.getDefaultAllocator();
820 	vk::BinaryCollection&	collection	= context.getBinaryCollection();
821 	VkShaderStageFlags		shaders		= static_cast<VkShaderStageFlags>(0);
822 	deUint32				shaderCount	= 0;
823 
824 	if (collection.contains("vert")) shaders |= VK_SHADER_STAGE_VERTEX_BIT;
825 	if (collection.contains("geom")) shaders |= VK_SHADER_STAGE_GEOMETRY_BIT;
826 	if (collection.contains("tesc")) shaders |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
827 	if (collection.contains("tese")) shaders |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
828 	if (collection.contains("frag")) shaders |= VK_SHADER_STAGE_FRAGMENT_BIT;
829 
830 	for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
831 		shaderCount++;
832 
833 	if (shaderCount != (deUint32)dePop32(shaders))
834 		TCU_THROW(InternalError, "Unused shaders detected in the collection");
835 
836 	if (0 != (shaders & VK_SHADER_STAGE_VERTEX_BIT))					m_vertShaderModule = createShaderModule(vkd, device, collection.get("vert"), 0);
837 	if (0 != (shaders & VK_SHADER_STAGE_GEOMETRY_BIT))					m_geomShaderModule = createShaderModule(vkd, device, collection.get("geom"), 0);
838 	if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT))		m_tescShaderModule = createShaderModule(vkd, device, collection.get("tesc"), 0);
839 	if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))	m_teseShaderModule = createShaderModule(vkd, device, collection.get("tese"), 0);
840 	if (0 != (shaders & VK_SHADER_STAGE_FRAGMENT_BIT))					m_fragShaderModule = createShaderModule(vkd, device, collection.get("frag"), 0);
841 
842 	m_descriptorSetLayout	= DescriptorSetLayoutBuilder()
843 								.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL_GRAPHICS)
844 								.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL_GRAPHICS)
845 								.build(vkd, device);
846 	m_descriptorPool		= DescriptorPoolBuilder()
847 								.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
848 								.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
849 								.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
850 	m_descriptorSet			= makeDescriptorSet		(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
851 	m_framebufferImage		= makeImage				(vkd, device, makeImageCreateInfo(m_framebufferFormat, testParams.width, testParams.height, 1u, VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
852 	m_framebufferImageAlloc	= bindImage				(vkd, device, allocator, *m_framebufferImage, MemoryRequirement::Any);
853 	m_framebufferAttachment	= makeImageView			(vkd, device, *m_framebufferImage, VK_IMAGE_VIEW_TYPE_2D, m_framebufferFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
854 	m_renderPass			= makeRenderPass		(vkd, device, m_framebufferFormat);
855 	m_framebuffer			= makeFramebuffer		(vkd, device, *m_renderPass, *m_framebufferAttachment, testParams.width, testParams.height);
856 	m_pipelineLayout		= makePipelineLayout	(vkd, device, m_descriptorSetLayout.get());
857 	m_pipeline				= makeGraphicsPipeline	(context, testParams);
858 
859 	initVertexBuffer(context, testParams);
860 }
861 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer cmdBuffer,const VkAccelerationStructureKHR * rayQueryTopAccelerationStructurePtr,const VkDescriptorImageInfo & resultImageInfo)862 void GraphicsConfiguration::fillCommandBuffer (Context&								context,
863 											   TestParams&							testParams,
864 											   VkCommandBuffer						cmdBuffer,
865 											   const VkAccelerationStructureKHR*	rayQueryTopAccelerationStructurePtr,
866 											   const VkDescriptorImageInfo&			resultImageInfo)
867 {
868 	const DeviceInterface&								vkd												= context.getDeviceInterface();
869 	const VkDevice										device											= context.getDevice();
870 	const VkDeviceSize									vertexBufferOffset								= 0;
871 	const VkWriteDescriptorSetAccelerationStructureKHR	rayQueryAccelerationStructureWriteDescriptorSet	=
872 	{
873 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
874 		DE_NULL,															//  const void*							pNext;
875 		1u,																	//  deUint32							accelerationStructureCount;
876 		rayQueryTopAccelerationStructurePtr,								//  const VkAccelerationStructureKHR*	pAccelerationStructures;
877 	};
878 
879 	DescriptorSetUpdateBuilder()
880 		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
881 		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
882 		.update(vkd, device);
883 
884 	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
885 	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
886 	vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
887 
888 	beginRenderPass(vkd, cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, testParams.width, testParams.height), tcu::UVec4());
889 
890 	vkd.cmdDraw(cmdBuffer, m_vertexCount, 1u, 0u, 0u);
891 
892 	endRenderPass(vkd, cmdBuffer);
893 }
894 
895 class ComputeConfiguration : public PipelineConfiguration
896 {
897 public:
898 								ComputeConfiguration	();
~ComputeConfiguration()899 	virtual						~ComputeConfiguration	() {}
900 
901 	static void					checkSupport			(Context&							context,
902 														 const TestParams&					testParams);
903 	static void					initPrograms			(SourceCollections&					programCollection,
904 														 const TestParams&					testParams);
905 
906 	virtual void				initConfiguration		(Context&							context,
907 														 TestParams&						testParams) override;
908 	virtual void				fillCommandBuffer		(Context&							context,
909 														 TestParams&						testParams,
910 														 VkCommandBuffer					commandBuffer,
911 														 const VkAccelerationStructureKHR*	rayQueryTopAccelerationStructurePtr,
912 														 const VkDescriptorImageInfo&		resultImageInfo) override;
913 
914 protected:
915 	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
916 	Move<VkDescriptorPool>		m_descriptorPool;
917 	Move<VkDescriptorSet>		m_descriptorSet;
918 	Move<VkPipelineLayout>		m_pipelineLayout;
919 
920 	Move<VkShaderModule>		m_shaderModule;
921 
922 	Move<VkPipeline>			m_pipeline;
923 };
924 
ComputeConfiguration()925 ComputeConfiguration::ComputeConfiguration ()
926 	: PipelineConfiguration	()
927 	, m_descriptorSetLayout	()
928 	, m_descriptorPool		()
929 	, m_descriptorSet		()
930 	, m_pipelineLayout		()
931 
932 	, m_shaderModule		()
933 
934 	, m_pipeline			()
935 {
936 }
937 
checkSupport(Context & context,const TestParams & testParams)938 void ComputeConfiguration::checkSupport (Context&			context,
939 										 const TestParams&	testParams)
940 {
941 	DE_UNREF(context);
942 	DE_UNREF(testParams);
943 }
944 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)945 void ComputeConfiguration::initPrograms (SourceCollections&	programCollection,
946 										 const TestParams&	testParams)
947 {
948 	const vk::ShaderBuildOptions	buildOptions		(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
949 	const std::string				testShaderBody		= testParams.testConfigShaderBodyText(testParams);
950 	const std::string				testBody			=
951 		"  ivec3       pos      = ivec3(gl_WorkGroupID);\n"
952 		"  ivec3       size     = ivec3(gl_NumWorkGroups);\n"
953 		+ testShaderBody;
954 
955 	switch (testParams.stage)
956 	{
957 		case VK_SHADER_STAGE_COMPUTE_BIT:
958 		{
959 			std::stringstream css;
960 			css <<
961 				"#version 460 core\n"
962 				"#extension GL_EXT_ray_query : require\n"
963 				"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
964 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
965 				"\n"
966 				"void main()\n"
967 				"{\n"
968 				<< testBody <<
969 				"}\n";
970 
971 			programCollection.glslSources.add("comp") << glu::ComputeSource(updateRayTracingGLSL(css.str())) << buildOptions;
972 
973 			break;
974 		}
975 
976 		default:
977 			TCU_THROW(InternalError, "Unknown stage");
978 	}
979 }
980 
initConfiguration(Context & context,TestParams & testParams)981 void ComputeConfiguration::initConfiguration (Context&		context,
982 											  TestParams&	testParams)
983 {
984 	DE_UNREF(testParams);
985 
986 	const DeviceInterface&	vkd			= context.getDeviceInterface();
987 	const VkDevice			device		= context.getDevice();
988 	vk::BinaryCollection&	collection	= context.getBinaryCollection();
989 
990 	m_descriptorSetLayout	= DescriptorSetLayoutBuilder()
991 								.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
992 								.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_COMPUTE_BIT)
993 								.build(vkd, device);
994 	m_descriptorPool		= DescriptorPoolBuilder()
995 								.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
996 								.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
997 								.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
998 	m_descriptorSet			= makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
999 	m_pipelineLayout		= makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
1000 	m_shaderModule			= createShaderModule(vkd, device, collection.get("comp"), 0);
1001 	m_pipeline				= makeComputePipeline(vkd, device, *m_pipelineLayout, *m_shaderModule);
1002 }
1003 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer cmdBuffer,const VkAccelerationStructureKHR * rayQueryTopAccelerationStructurePtr,const VkDescriptorImageInfo & resultImageInfo)1004 void ComputeConfiguration::fillCommandBuffer (Context&							context,
1005 											  TestParams&						testParams,
1006 											  VkCommandBuffer					cmdBuffer,
1007 											  const VkAccelerationStructureKHR*	rayQueryTopAccelerationStructurePtr,
1008 											  const VkDescriptorImageInfo&		resultImageInfo)
1009 {
1010 	const DeviceInterface&								vkd												= context.getDeviceInterface();
1011 	const VkDevice										device											= context.getDevice();
1012 	const VkWriteDescriptorSetAccelerationStructureKHR	rayQueryAccelerationStructureWriteDescriptorSet	=
1013 	{
1014 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
1015 		DE_NULL,															//  const void*							pNext;
1016 		1u,																	//  deUint32							accelerationStructureCount;
1017 		rayQueryTopAccelerationStructurePtr,								//  const VkAccelerationStructureKHR*	pAccelerationStructures;
1018 	};
1019 
1020 	DescriptorSetUpdateBuilder()
1021 		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
1022 		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
1023 		.update(vkd, device);
1024 
1025 	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
1026 
1027 	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline.get());
1028 
1029 	vkd.cmdDispatch(cmdBuffer, testParams.width, testParams.height, 1);
1030 }
1031 
1032 class RayTracingConfiguration : public PipelineConfiguration
1033 {
1034 public:
1035 													RayTracingConfiguration				();
~RayTracingConfiguration()1036 	virtual											~RayTracingConfiguration			() {}
1037 
1038 	static void										checkSupport						(Context&							context,
1039 																						 const TestParams&					testParams);
1040 	static void										initPrograms						(SourceCollections&					programCollection,
1041 																						 const TestParams&					testParams);
1042 
1043 	virtual void									initConfiguration					(Context&							context,
1044 																						 TestParams&						testParams) override;
1045 	virtual void									fillCommandBuffer					(Context&							context,
1046 																						 TestParams&						testParams,
1047 																						 VkCommandBuffer					commandBuffer,
1048 																						 const VkAccelerationStructureKHR*	rayQueryTopAccelerationStructurePtr,
1049 																						 const VkDescriptorImageInfo&		resultImageInfo) override;
1050 
1051 protected:
1052 	de::MovePtr<BufferWithMemory>					createShaderBindingTable			(const InstanceInterface&			vki,
1053 																						 const DeviceInterface&				vkd,
1054 																						 const VkDevice						device,
1055 																						 const VkPhysicalDevice				physicalDevice,
1056 																						 const VkPipeline					pipeline,
1057 																						 Allocator&							allocator,
1058 																						 de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
1059 																						 const deUint32						group);
1060 
1061 protected:
1062 	deUint32										m_shaders;
1063 	deUint32										m_raygenShaderGroup;
1064 	deUint32										m_missShaderGroup;
1065 	deUint32										m_hitShaderGroup;
1066 	deUint32										m_callableShaderGroup;
1067 	deUint32										m_shaderGroupCount;
1068 
1069 	Move<VkDescriptorSetLayout>						m_descriptorSetLayout;
1070 	Move<VkDescriptorPool>							m_descriptorPool;
1071 	Move<VkDescriptorSet>							m_descriptorSet;
1072 	Move<VkPipelineLayout>							m_pipelineLayout;
1073 
1074 	de::MovePtr<RayTracingPipeline>					m_rayTracingPipeline;
1075 	Move<VkPipeline>								m_pipeline;
1076 
1077 	de::MovePtr<BufferWithMemory>					m_raygenShaderBindingTable;
1078 	de::MovePtr<BufferWithMemory>					m_hitShaderBindingTable;
1079 	de::MovePtr<BufferWithMemory>					m_missShaderBindingTable;
1080 	de::MovePtr<BufferWithMemory>					m_callableShaderBindingTable;
1081 
1082 	VkStridedDeviceAddressRegionKHR					m_raygenShaderBindingTableRegion;
1083 	VkStridedDeviceAddressRegionKHR					m_missShaderBindingTableRegion;
1084 	VkStridedDeviceAddressRegionKHR					m_hitShaderBindingTableRegion;
1085 	VkStridedDeviceAddressRegionKHR					m_callableShaderBindingTableRegion;
1086 
1087 	de::SharedPtr<BottomLevelAccelerationStructure>	m_bottomLevelAccelerationStructure;
1088 	de::SharedPtr<TopLevelAccelerationStructure>	m_topLevelAccelerationStructure;
1089 };
1090 
RayTracingConfiguration()1091 RayTracingConfiguration::RayTracingConfiguration()
1092 	: m_shaders								(0)
1093 	, m_raygenShaderGroup					(~0u)
1094 	, m_missShaderGroup						(~0u)
1095 	, m_hitShaderGroup						(~0u)
1096 	, m_callableShaderGroup					(~0u)
1097 	, m_shaderGroupCount					(0)
1098 
1099 	, m_descriptorSetLayout					()
1100 	, m_descriptorPool						()
1101 	, m_descriptorSet						()
1102 	, m_pipelineLayout						()
1103 
1104 	, m_rayTracingPipeline					()
1105 	, m_pipeline							()
1106 
1107 	, m_raygenShaderBindingTable			()
1108 	, m_hitShaderBindingTable				()
1109 	, m_missShaderBindingTable				()
1110 	, m_callableShaderBindingTable			()
1111 
1112 	, m_raygenShaderBindingTableRegion		()
1113 	, m_missShaderBindingTableRegion		()
1114 	, m_hitShaderBindingTableRegion			()
1115 	, m_callableShaderBindingTableRegion	()
1116 
1117 	, m_bottomLevelAccelerationStructure	()
1118 	, m_topLevelAccelerationStructure		()
1119 {
1120 }
1121 
checkSupport(Context & context,const TestParams & testParams)1122 void RayTracingConfiguration::checkSupport (Context&			context,
1123 											const TestParams&	testParams)
1124 {
1125 	DE_UNREF(testParams);
1126 
1127 	context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1128 	const VkPhysicalDeviceRayTracingPipelineFeaturesKHR&	rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
1129 	if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE)
1130 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1131 }
1132 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)1133 void RayTracingConfiguration::initPrograms (SourceCollections&	programCollection,
1134 											const TestParams&	testParams)
1135 {
1136 	const vk::ShaderBuildOptions	buildOptions		(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1137 
1138 	const std::string				testShaderBody		= testParams.testConfigShaderBodyText(testParams);
1139 	const std::string				testBody			=
1140 		"  ivec3       pos      = ivec3(gl_LaunchIDEXT);\n"
1141 		"  ivec3       size     = ivec3(gl_LaunchSizeEXT);\n"
1142 		+ testShaderBody;
1143 
1144 	switch (testParams.stage)
1145 	{
1146 		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
1147 		{
1148 			std::stringstream css;
1149 			css <<
1150 				"#version 460 core\n"
1151 				"#extension GL_EXT_ray_tracing : require\n"
1152 				"#extension GL_EXT_ray_query : require\n"
1153 				"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1154 				"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1155 				"\n"
1156 				"void main()\n"
1157 				"{\n"
1158 				<< testBody <<
1159 				"}\n";
1160 
1161 			programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1162 
1163 			break;
1164 		}
1165 
1166 		case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
1167 		{
1168 			programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1169 
1170 			{
1171 				std::stringstream css;
1172 				css <<
1173 					"#version 460 core\n"
1174 					"#extension GL_EXT_ray_tracing : require\n"
1175 					"#extension GL_EXT_ray_query : require\n"
1176 					"hitAttributeEXT vec3 attribs;\n"
1177 					"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1178 					"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1179 					"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1180 					"\n"
1181 					"void main()\n"
1182 					"{\n"
1183 					<< testBody <<
1184 					"}\n";
1185 
1186 				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1187 			}
1188 
1189 			programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1190 			programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1191 
1192 			break;
1193 		}
1194 
1195 		case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
1196 		{
1197 			programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1198 
1199 			{
1200 				std::stringstream css;
1201 				css <<
1202 					"#version 460 core\n"
1203 					"#extension GL_EXT_ray_tracing : require\n"
1204 					"#extension GL_EXT_ray_query : require\n"
1205 					"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1206 					"hitAttributeEXT vec3 attribs;\n"
1207 					"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1208 					"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1209 					"\n"
1210 					"void main()\n"
1211 					"{\n"
1212 					<< testBody <<
1213 					"}\n";
1214 
1215 				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1216 			}
1217 
1218 			programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1219 			programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1220 
1221 			break;
1222 		}
1223 
1224 		case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
1225 		{
1226 			programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1227 
1228 			{
1229 				std::stringstream css;
1230 				css <<
1231 					"#version 460 core\n"
1232 					"#extension GL_EXT_ray_tracing : require\n"
1233 					"#extension GL_EXT_ray_query : require\n"
1234 					"hitAttributeEXT vec3 hitAttribute;\n"
1235 					"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1236 					"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1237 					"\n"
1238 					"void main()\n"
1239 					"{\n"
1240 					<< testBody <<
1241 					"  hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n"
1242 					"  reportIntersectionEXT(1.0f, 0);\n"
1243 					"}\n";
1244 
1245 				programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1246 			}
1247 
1248 			programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1249 			programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1250 			programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1251 
1252 			break;
1253 		}
1254 
1255 		case VK_SHADER_STAGE_MISS_BIT_KHR:
1256 		{
1257 			programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1258 
1259 			{
1260 				std::stringstream css;
1261 				css <<
1262 					"#version 460 core\n"
1263 					"#extension GL_EXT_ray_tracing : require\n"
1264 					"#extension GL_EXT_ray_query : require\n"
1265 					"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1266 					"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1267 					"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1268 					"\n"
1269 					"void main()\n"
1270 					"{\n"
1271 					<< testBody <<
1272 					"}\n";
1273 
1274 				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1275 			}
1276 
1277 			programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1278 			programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1279 
1280 			break;
1281 		}
1282 
1283 		case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
1284 		{
1285 			{
1286 				std::stringstream css;
1287 				css <<
1288 					"#version 460 core\n"
1289 					"#extension GL_EXT_ray_tracing : require\n"
1290 					"#extension GL_EXT_ray_query : require\n"
1291 					"layout(location = 0) callableDataEXT float dummy;"
1292 					"layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1293 					"\n"
1294 					"void main()\n"
1295 					"{\n"
1296 					"  executeCallableEXT(0, 0);\n"
1297 					"}\n";
1298 
1299 				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1300 			}
1301 
1302 			{
1303 				std::stringstream css;
1304 				css <<
1305 					"#version 460 core\n"
1306 					"#extension GL_EXT_ray_tracing : require\n"
1307 					"#extension GL_EXT_ray_query : require\n"
1308 					"layout(location = 0) callableDataInEXT float dummy;"
1309 					"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1310 					"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
1311 					"\n"
1312 					"void main()\n"
1313 					"{\n"
1314 					<< testBody <<
1315 					"}\n";
1316 
1317 				programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
1318 			}
1319 
1320 			programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1321 			programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1322 			programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1323 
1324 			break;
1325 		}
1326 
1327 		default:
1328 			TCU_THROW(InternalError, "Unknown stage");
1329 	}
1330 }
1331 
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)1332 de::MovePtr<BufferWithMemory> RayTracingConfiguration::createShaderBindingTable (const InstanceInterface&			vki,
1333 																				 const DeviceInterface&				vkd,
1334 																				 const VkDevice						device,
1335 																				 const VkPhysicalDevice				physicalDevice,
1336 																				 const VkPipeline					pipeline,
1337 																				 Allocator&							allocator,
1338 																				 de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
1339 																				 const deUint32						group)
1340 {
1341 	de::MovePtr<BufferWithMemory>	shaderBindingTable;
1342 
1343 	if (group < m_shaderGroupCount)
1344 	{
1345 		const deUint32	shaderGroupHandleSize		= getShaderGroupHandleSize(vki, physicalDevice);
1346 		const deUint32	shaderGroupBaseAlignment	= getShaderGroupBaseAlignment(vki, physicalDevice);
1347 
1348 		shaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, group, 1u);
1349 	}
1350 
1351 	return shaderBindingTable;
1352 }
1353 
initConfiguration(Context & context,TestParams & testParams)1354 void RayTracingConfiguration::initConfiguration (Context&		context,
1355 												 TestParams&	testParams)
1356 {
1357 	DE_UNREF(testParams);
1358 
1359 	const InstanceInterface&	vki						= context.getInstanceInterface();
1360 	const DeviceInterface&		vkd						= context.getDeviceInterface();
1361 	const VkDevice				device					= context.getDevice();
1362 	const VkPhysicalDevice		physicalDevice			= context.getPhysicalDevice();
1363 	vk::BinaryCollection&		collection				= context.getBinaryCollection();
1364 	Allocator&					allocator				= context.getDefaultAllocator();
1365 	const deUint32				shaderGroupHandleSize	= getShaderGroupHandleSize(vki, physicalDevice);
1366 	const VkShaderStageFlags	hitStages				= VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
1367 	deUint32					shaderCount				= 0;
1368 
1369 	m_shaderGroupCount = 0;
1370 
1371 	if (collection.contains("rgen")) m_shaders |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
1372 	if (collection.contains("ahit")) m_shaders |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
1373 	if (collection.contains("chit")) m_shaders |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
1374 	if (collection.contains("miss")) m_shaders |= VK_SHADER_STAGE_MISS_BIT_KHR;
1375 	if (collection.contains("sect")) m_shaders |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
1376 	if (collection.contains("call")) m_shaders |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
1377 
1378 	for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
1379 		shaderCount++;
1380 
1381 	if (shaderCount != (deUint32)dePop32(m_shaders))
1382 		TCU_THROW(InternalError, "Unused shaders detected in the collection");
1383 
1384 	if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))
1385 		m_raygenShaderGroup		= m_shaderGroupCount++;
1386 
1387 	if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))
1388 		m_missShaderGroup		= m_shaderGroupCount++;
1389 
1390 	if (0 != (m_shaders & hitStages))
1391 		m_hitShaderGroup		= m_shaderGroupCount++;
1392 
1393 	if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))
1394 		m_callableShaderGroup	= m_shaderGroupCount++;
1395 
1396 	m_rayTracingPipeline				= de::newMovePtr<RayTracingPipeline>();
1397 
1398 	m_descriptorSetLayout				= DescriptorSetLayoutBuilder()
1399 											.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
1400 											.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1401 											.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1402 											.build(vkd, device);
1403 	m_descriptorPool					= DescriptorPoolBuilder()
1404 											.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1405 											.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1406 											.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1407 											.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1408 	m_descriptorSet						= makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
1409 
1410 	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);
1411 	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);
1412 	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);
1413 	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);
1414 	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);
1415 	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);
1416 
1417 	m_pipelineLayout					= makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
1418 	m_pipeline							= m_rayTracingPipeline->createPipeline(vkd, device, *m_pipelineLayout);
1419 
1420 	m_raygenShaderBindingTable			= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_raygenShaderGroup);
1421 	m_missShaderBindingTable			= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_missShaderGroup);
1422 	m_hitShaderBindingTable				= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_hitShaderGroup);
1423 	m_callableShaderBindingTable		= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_callableShaderGroup);
1424 
1425 	m_raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_raygenShaderBindingTable),		shaderGroupHandleSize);
1426 	m_missShaderBindingTableRegion		= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_missShaderBindingTable),		shaderGroupHandleSize);
1427 	m_hitShaderBindingTableRegion		= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_hitShaderBindingTable),			shaderGroupHandleSize);
1428 	m_callableShaderBindingTableRegion	= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_callableShaderBindingTable),	shaderGroupHandleSize);
1429 }
1430 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkAccelerationStructureKHR * rayQueryTopAccelerationStructurePtr,const VkDescriptorImageInfo & resultImageInfo)1431 void RayTracingConfiguration::fillCommandBuffer (Context&							context,
1432 												 TestParams&						testParams,
1433 												 VkCommandBuffer					commandBuffer,
1434 												 const VkAccelerationStructureKHR*	rayQueryTopAccelerationStructurePtr,
1435 												 const VkDescriptorImageInfo&		resultImageInfo)
1436 {
1437 	const DeviceInterface&							vkd									= context.getDeviceInterface();
1438 	const VkDevice									device								= context.getDevice();
1439 	Allocator&										allocator							= context.getDefaultAllocator();
1440 	de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure	= makeBottomLevelAccelerationStructure();
1441 	de::MovePtr<TopLevelAccelerationStructure>		topLevelAccelerationStructure		= makeTopLevelAccelerationStructure();
1442 
1443 	m_bottomLevelAccelerationStructure = de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release());
1444 	m_bottomLevelAccelerationStructure->setDefaultGeometryData(testParams.stage);
1445 	m_bottomLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1446 
1447 	m_topLevelAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(topLevelAccelerationStructure.release());
1448 	m_topLevelAccelerationStructure->setInstanceCount(1);
1449 	m_topLevelAccelerationStructure->addInstance(m_bottomLevelAccelerationStructure);
1450 	m_topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1451 
1452 	const TopLevelAccelerationStructure*				topLevelAccelerationStructurePtr				= m_topLevelAccelerationStructure.get();
1453 	const VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet			=
1454 	{
1455 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
1456 		DE_NULL,															//  const void*							pNext;
1457 		1u,																	//  deUint32							accelerationStructureCount;
1458 		topLevelAccelerationStructurePtr->getPtr(),							//  const VkAccelerationStructureKHR*	pAccelerationStructures;
1459 	};
1460 	const VkWriteDescriptorSetAccelerationStructureKHR	rayQueryAccelerationStructureWriteDescriptorSet	=
1461 	{
1462 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
1463 		DE_NULL,															//  const void*							pNext;
1464 		1u,																	//  deUint32							accelerationStructureCount;
1465 		rayQueryTopAccelerationStructurePtr,								//  const VkAccelerationStructureKHR*	pAccelerationStructures;
1466 	};
1467 
1468 	DescriptorSetUpdateBuilder()
1469 		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
1470 		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1471 		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
1472 		.update(vkd, device);
1473 
1474 	vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
1475 
1476 	vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, m_pipeline.get());
1477 
1478 	cmdTraceRays(vkd,
1479 		commandBuffer,
1480 		&m_raygenShaderBindingTableRegion,
1481 		&m_missShaderBindingTableRegion,
1482 		&m_hitShaderBindingTableRegion,
1483 		&m_callableShaderBindingTableRegion,
1484 		testParams.width, testParams.height, 1);
1485 }
1486 
1487 
getShaderBodyText(const TestParams & testParams)1488 const std::string getShaderBodyText (const TestParams& testParams)
1489 {
1490 	if (testParams.geomType == GEOM_TYPE_AABBS)
1491 	{
1492 		const std::string result =
1493 			"  uint        rayFlags = 0;\n"
1494 			"  uint        cullMask = 0xFF;\n"
1495 			"  float       tmin     = 0.0;\n"
1496 			"  float       tmax     = 9.0;\n"
1497 			"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
1498 			"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
1499 			"  uint        count    = 0;\n"
1500 			"  rayQueryEXT rayQuery;\n"
1501 			"\n"
1502 			"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
1503 			"\n"
1504 			"  while(rayQueryProceedEXT(rayQuery))\n"
1505 			"  {\n"
1506 			"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
1507 			"    {\n"
1508 			"      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n"
1509 			"      count++;\n"
1510 			"    }\n"
1511 			"  }\n"
1512 			"  imageStore(result, pos, ivec4(count, 0, 0, 0));\n"
1513 			"\n";
1514 
1515 		return result;
1516 	}
1517 	else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
1518 	{
1519 		const std::string result =
1520 			"  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
1521 			"  uint        cullMask = 0xFF;\n"
1522 			"  float       tmin     = 0.0;\n"
1523 			"  float       tmax     = 9.0;\n"
1524 			"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
1525 			"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
1526 			"  uint        count    = 0;\n"
1527 			"  rayQueryEXT rayQuery;\n"
1528 			"\n"
1529 			"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
1530 			"\n"
1531 			"  while(rayQueryProceedEXT(rayQuery))\n"
1532 			"  {\n"
1533 			"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
1534 			"    {\n"
1535 			"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
1536 			"      count++;\n"
1537 			"    }\n"
1538 			"  }\n"
1539 			"  imageStore(result, pos, ivec4(count, 0, 0, 0));\n"
1540 			"\n";
1541 
1542 		return result;
1543 	}
1544 	else
1545 	{
1546 		TCU_THROW(InternalError, "Unknown geometry type");
1547 	}
1548 }
1549 
1550 
1551 class TestConfigurationNoMiss : public TestConfiguration
1552 {
1553 public:
1554 	virtual const VkAccelerationStructureKHR*	initAccelerationStructures	(Context&							context,
1555 																			 TestParams&						testParams,
1556 																			 VkCommandBuffer					cmdBuffer) override;
1557 
1558 	virtual bool								verify						(BufferWithMemory*					resultBuffer,
1559 																			 Context&							context,
1560 																			 TestParams&						testParams) override;
1561 private:
1562 	deUint32									chooseAABB					(de::Random&						rng,
1563 																			 const std::vector<tcu::Vec2>&		vertices,
1564 																			 const std::vector<tcu::UVec2>&		aabbs);
1565 	deUint32									chooseTriangle				(de::Random&						rng,
1566 																			 const std::vector<tcu::Vec2>&		vertices,
1567 																			 const std::vector<tcu::UVec3>&		triangles);
1568 };
1569 
chooseAABB(de::Random & rng,const std::vector<tcu::Vec2> & vertices,const std::vector<tcu::UVec2> & aabbs)1570 deUint32 TestConfigurationNoMiss::chooseAABB (de::Random&						rng,
1571 											  const std::vector<tcu::Vec2>&		vertices,
1572 											  const std::vector<tcu::UVec2>&	aabbs)
1573 {
1574 	while (true)
1575 	{
1576 		const deUint32		n	= (deUint32)rng.getInt(0, (deUint32)aabbs.size() - 1);
1577 		const tcu::UVec2&	t	= aabbs[n];
1578 		const tcu::Vec2&	a	= vertices[t.x()];
1579 		const tcu::Vec2&	b	= vertices[t.y()];
1580 
1581 		if (deFloatAbs(a.x() - b.x()) < MIN_AABB_SIDE_LENGTH || deFloatAbs(a.y() - b.y()) < MIN_AABB_SIDE_LENGTH)
1582 			continue;
1583 
1584 		return n;
1585 	}
1586 }
1587 
chooseTriangle(de::Random & rng,const std::vector<tcu::Vec2> & vertices,const std::vector<tcu::UVec3> & triangles)1588 deUint32 TestConfigurationNoMiss::chooseTriangle (de::Random&						rng,
1589 												  const std::vector<tcu::Vec2>&		vertices,
1590 												  const std::vector<tcu::UVec3>&	triangles)
1591 {
1592 	while (true)
1593 	{
1594 		const deUint32		n	= (deUint32)rng.getInt(0, (deUint32)triangles.size() - 1);
1595 		const tcu::UVec3&	t	= triangles[n];
1596 		const tcu::Vec2&	a	= vertices[t.x()];
1597 		const tcu::Vec2&	b	= vertices[t.y()];
1598 		const tcu::Vec2&	c	= vertices[t.z()];
1599 		const float			ab	= triangleEdgeLength(a, b);
1600 		const float			bc	= triangleEdgeLength(b, c);
1601 		const float			ca	= triangleEdgeLength(c, a);
1602 
1603 		if (ab < MIN_TRIANGLE_EDGE_LENGTH || bc < MIN_TRIANGLE_EDGE_LENGTH || ca < MIN_TRIANGLE_EDGE_LENGTH || triangleArea(ab, bc, ca) < MIN_TRIANGLE_AREA_SIZE)
1604 			continue;
1605 
1606 		return n;
1607 	}
1608 }
1609 
initAccelerationStructures(Context & context,TestParams & testParams,VkCommandBuffer cmdBuffer)1610 const VkAccelerationStructureKHR* TestConfigurationNoMiss::initAccelerationStructures (Context&			context,
1611 																					   TestParams&		testParams,
1612 																					   VkCommandBuffer	cmdBuffer)
1613 {
1614 	const DeviceInterface&							vkd											= context.getDeviceInterface();
1615 	const VkDevice									device										= context.getDevice();
1616 	Allocator&										allocator									= context.getDefaultAllocator();
1617 	const tcu::Vec2									centerPixelCenter							= tcu::Vec2(0.5f - 0.5f / float(testParams.width), 0.5f - 0.5f / float(testParams.height));
1618 	de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure	= makeBottomLevelAccelerationStructure();
1619 	de::MovePtr<TopLevelAccelerationStructure>		rayQueryTopLevelAccelerationStructure		= makeTopLevelAccelerationStructure();
1620 	de::Random										rng											(testParams.randomSeed);
1621 	std::vector<tcu::Vec3>							geometryData;
1622 
1623 	if (testParams.geomType == GEOM_TYPE_AABBS)
1624 	{
1625 		std::vector<tcu::UVec2>	aabbs;
1626 		std::vector<tcu::Vec2>	vertices;
1627 
1628 		vertices.reserve(2u * testParams.squaresGroupCount);
1629 		aabbs.reserve(testParams.squaresGroupCount);
1630 
1631 		{
1632 			// a---g---+
1633 			// |   |   |
1634 			// e---d---h
1635 			// |   |   |
1636 			// +---f---b
1637 			//
1638 			// a-d, d-b, e-f, g-h
1639 
1640 			const tcu::Vec2		d	= centerPixelCenter;
1641 			const tcu::Vec2		a	= tcu::Vec2(0.0f, 0.0f);
1642 			const tcu::Vec2		b	= tcu::Vec2(1.0f, 1.0f);
1643 			const tcu::Vec2		e	= tcu::Vec2(a.x(), d.y());
1644 			const tcu::Vec2		f	= tcu::Vec2(d.x(), b.y());
1645 			const tcu::Vec2		g	= tcu::Vec2(d.x(), a.y());
1646 			const tcu::Vec2		h	= tcu::Vec2(b.x(), d.y());
1647 			const deUint32		A	= 0;
1648 			const deUint32		B	= 1;
1649 			const deUint32		D	= 2;
1650 			const deUint32		E	= 3;
1651 			const deUint32		F	= 4;
1652 			const deUint32		G	= 5;
1653 			const deUint32		H	= 6;
1654 
1655 			vertices.push_back(a);
1656 			vertices.push_back(b);
1657 			vertices.push_back(d);
1658 			vertices.push_back(e);
1659 			vertices.push_back(f);
1660 			vertices.push_back(g);
1661 			vertices.push_back(h);
1662 
1663 			aabbs.push_back(tcu::UVec2(A, D));
1664 			aabbs.push_back(tcu::UVec2(D, B));
1665 			aabbs.push_back(tcu::UVec2(E, F));
1666 			aabbs.push_back(tcu::UVec2(G, H));
1667 		}
1668 
1669 		while (aabbs.size() < testParams.squaresGroupCount)
1670 		{
1671 			// a-------+      a---g---+
1672 			// |       |      |   |   |
1673 			// |       |  ->  e---d---h
1674 			// |       |      |   |   |
1675 			// +-------b      +---f---b
1676 			//
1677 			// a-b        ->  a-d, d-b, e-f, g-h
1678 
1679 			const deUint32		n		= chooseAABB(rng, vertices, aabbs);
1680 			tcu::UVec2&			t		= aabbs[n];
1681 			const tcu::Vec2&	a		= vertices[t.x()];
1682 			const tcu::Vec2&	b		= vertices[t.y()];
1683 			const float			alfa	= rng.getFloat(0.2f, 0.8f);
1684 			const float			beta	= rng.getFloat(0.2f, 0.8f);
1685 			const tcu::Vec2		d		= mixCoordsVec2(a, b, alfa, beta);
1686 			const tcu::Vec2		e		= tcu::Vec2(a.x(), d.y());
1687 			const tcu::Vec2		f		= tcu::Vec2(d.x(), b.y());
1688 			const tcu::Vec2		g		= tcu::Vec2(d.x(), a.y());
1689 			const tcu::Vec2		h		= tcu::Vec2(b.x(), d.y());
1690 			const deUint32		B		= t.y();
1691 			const deUint32		D		= (deUint32)vertices.size();
1692 			const deUint32		E		= D + 1;
1693 			const deUint32		F		= D + 2;
1694 			const deUint32		G		= D + 3;
1695 			const deUint32		H		= D + 4;
1696 
1697 			if (d.x() <= a.x() || d.x() >= b.x() || d.y() <= a.y() || d.y() >= b.y())
1698 				continue;
1699 
1700 			vertices.push_back(d);
1701 			vertices.push_back(e);
1702 			vertices.push_back(f);
1703 			vertices.push_back(g);
1704 			vertices.push_back(h);
1705 
1706 			t.y() = D;
1707 			aabbs.push_back(tcu::UVec2(D, B));
1708 			aabbs.push_back(tcu::UVec2(E, F));
1709 			aabbs.push_back(tcu::UVec2(G, H));
1710 		}
1711 
1712 		geometryData.reserve(2u * aabbs.size());
1713 
1714 		for (size_t i = 0; i < aabbs.size(); ++i)
1715 		{
1716 			const tcu::Vec2&	a	= vertices[aabbs[i].x()];
1717 			const tcu::Vec2&	b	= vertices[aabbs[i].y()];
1718 			const float			az	= -rng.getFloat(0.1f, 0.5f);
1719 			const float			bz	= az + 0.01f;
1720 			const tcu::Vec3		A	= tcu::Vec3(a.x(), a.y(), az);
1721 			const tcu::Vec3		B	= tcu::Vec3(b.x(), b.y(), bz);
1722 
1723 			geometryData.push_back(A);
1724 			geometryData.push_back(B);
1725 		}
1726 	}
1727 	else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
1728 	{
1729 		std::vector<tcu::UVec3>	triangles;
1730 		std::vector<tcu::Vec2>	vertices;
1731 		std::vector<float>		verticesZ;
1732 
1733 		vertices.reserve(3u * testParams.squaresGroupCount);
1734 		triangles.reserve(testParams.squaresGroupCount);
1735 
1736 		{
1737 			// Initial triangle set: aeb, bec, cef, fei, ieh, heg, ged, dea
1738 			// e - is not math middle, but centrum of one of the pixels
1739 			// a---b---c
1740 			// | \ | / |
1741 			// d---e---f
1742 			// | / | \ |
1743 			// g---h---i
1744 
1745 			const tcu::Vec2		e	= centerPixelCenter;
1746 			const tcu::Vec2		a	= tcu::Vec2( 0.0f,  0.0f);
1747 			const tcu::Vec2		i	= tcu::Vec2( 1.0f,  1.0f);
1748 			const tcu::Vec2		c	= tcu::Vec2(i.x(), a.y());
1749 			const tcu::Vec2		g	= tcu::Vec2(a.x(), i.y());
1750 			const tcu::Vec2		b	= tcu::Vec2(e.x(), a.y());
1751 			const tcu::Vec2		d	= tcu::Vec2(a.x(), e.y());
1752 			const tcu::Vec2		f	= tcu::Vec2(i.x(), e.y());
1753 			const tcu::Vec2		h	= tcu::Vec2(e.x(), i.y());
1754 			const deUint32		A	= 0;
1755 			const deUint32		B	= 1;
1756 			const deUint32		C	= 2;
1757 			const deUint32		D	= 3;
1758 			const deUint32		E	= 4;
1759 			const deUint32		F	= 5;
1760 			const deUint32		G	= 6;
1761 			const deUint32		H	= 7;
1762 			const deUint32		I	= 8;
1763 
1764 			vertices.push_back(a);
1765 			vertices.push_back(b);
1766 			vertices.push_back(c);
1767 			vertices.push_back(d);
1768 			vertices.push_back(e);
1769 			vertices.push_back(f);
1770 			vertices.push_back(g);
1771 			vertices.push_back(h);
1772 			vertices.push_back(i);
1773 
1774 			triangles.push_back(tcu::UVec3(A, E, B));
1775 			triangles.push_back(tcu::UVec3(B, E, C));
1776 			triangles.push_back(tcu::UVec3(C, E, F));
1777 			triangles.push_back(tcu::UVec3(F, E, I));
1778 			triangles.push_back(tcu::UVec3(I, E, H));
1779 			triangles.push_back(tcu::UVec3(H, E, G));
1780 			triangles.push_back(tcu::UVec3(G, E, D));
1781 			triangles.push_back(tcu::UVec3(D, E, A));
1782 		}
1783 
1784 		while (triangles.size() < testParams.squaresGroupCount)
1785 		{
1786 			const deUint32		n		= chooseTriangle(rng, vertices, triangles);
1787 			tcu::UVec3&			t		= triangles[n];
1788 			const tcu::Vec2&	a		= vertices[t.x()];
1789 			const tcu::Vec2&	b		= vertices[t.y()];
1790 			const tcu::Vec2&	c		= vertices[t.z()];
1791 			const float			alfa	= rng.getFloat(0.2f, 0.8f);
1792 			const float			beta	= rng.getFloat(0.2f, 0.8f);
1793 			const tcu::Vec2		d		= mixVec2(mixVec2(a, b, alfa), c, beta);
1794 			const deUint32&		p		= t.x();
1795 			const deUint32&		q		= t.y();
1796 			deUint32&			r		= t.z();
1797 			const deUint32		R		= (deUint32)vertices.size();
1798 
1799 			vertices.push_back(d);
1800 
1801 			triangles.push_back(tcu::UVec3(q, r, R));
1802 			triangles.push_back(tcu::UVec3(p, r, R));
1803 			r = R;
1804 		}
1805 
1806 		verticesZ.reserve(vertices.size());
1807 		for (size_t i = 0; i < vertices.size(); ++i)
1808 			verticesZ.push_back(-rng.getFloat(0.01f, 0.99f));
1809 
1810 		geometryData.reserve(3u * triangles.size());
1811 
1812 		for (size_t i = 0; i < triangles.size(); ++i)
1813 		{
1814 			const deUint32	a = triangles[i].x();
1815 			const deUint32	b = triangles[i].y();
1816 			const deUint32	c = triangles[i].z();
1817 
1818 			geometryData.push_back(tcu::Vec3(vertices[a].x(), vertices[a].y(), verticesZ[a]));
1819 			geometryData.push_back(tcu::Vec3(vertices[b].x(), vertices[b].y(), verticesZ[b]));
1820 			geometryData.push_back(tcu::Vec3(vertices[c].x(), vertices[c].y(), verticesZ[c]));
1821 		}
1822 	}
1823 	else
1824 	{
1825 		TCU_THROW(InternalError, "Unknown geometry type");
1826 	}
1827 
1828 	rayQueryBottomLevelAccelerationStructure->setGeometryCount(1u);
1829 	rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, testParams.geomType == GEOM_TYPE_TRIANGLES);
1830 	rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
1831 	m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
1832 	m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
1833 	m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back());
1834 	m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
1835 
1836 	return m_topAccelerationStructure.get()->getPtr();
1837 }
1838 
verify(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)1839 bool TestConfigurationNoMiss::verify (BufferWithMemory*					resultBuffer,
1840 									  Context&							context,
1841 									  TestParams&						testParams)
1842 {
1843 	tcu::TestLog&	log			= context.getTestContext().getLog();
1844 	const deUint32	width		= testParams.width;
1845 	const deUint32	height		= testParams.height;
1846 	const deInt32*	resultPtr	= (deInt32*)resultBuffer->getAllocation().getHostPtr();
1847 	deUint32		failures	= 0;
1848 	deUint32		pos			= 0;
1849 
1850 	for (deUint32 y = 0; y < height; ++y)
1851 	for (deUint32 x = 0; x < width; ++x)
1852 	{
1853 		if (resultPtr[pos] <= 0)
1854 			failures++;
1855 
1856 		pos++;
1857 	}
1858 
1859 	if (failures != 0)
1860 	{
1861 		std::stringstream	css;
1862 
1863 		pos = 0;
1864 
1865 		for (deUint32 y = 0; y < height; ++y)
1866 		{
1867 			for (deUint32 x = 0; x < width; ++x)
1868 			{
1869 				if (resultPtr[pos] <= 0)
1870 					css << std::setw(3) << resultPtr[pos] << ",";
1871 				else
1872 					css << "___,";
1873 
1874 				pos++;
1875 			}
1876 
1877 			css << std::endl;
1878 		}
1879 
1880 		log << tcu::TestLog::Message << "Retrieved:" << tcu::TestLog::EndMessage;
1881 		log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
1882 	}
1883 
1884 	return (failures == 0);
1885 }
1886 
1887 
1888 class TestConfigurationSingleHit : public TestConfigurationNoMiss
1889 {
1890 public:
1891 	virtual bool								verify						(BufferWithMemory*					resultBuffer,
1892 																			 Context&							context,
1893 																			 TestParams&						testParams) override;
1894 };
1895 
verify(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)1896 bool TestConfigurationSingleHit::verify (BufferWithMemory*					resultBuffer,
1897 										 Context&							context,
1898 										 TestParams&						testParams)
1899 {
1900 	tcu::TestLog&	log				= context.getTestContext().getLog();
1901 	const deUint32	width			= testParams.width;
1902 	const deUint32	height			= testParams.height;
1903 	const deInt32*	resultPtr		= (deInt32*)resultBuffer->getAllocation().getHostPtr();
1904 	const deInt32	expectedValue	= 1;
1905 	deUint32		failures		= 0;
1906 	deUint32		pos				= 0;
1907 
1908 	for (deUint32 y = 0; y < height; ++y)
1909 	for (deUint32 x = 0; x < width; ++x)
1910 	{
1911 		if (resultPtr[pos] != expectedValue)
1912 			failures++;
1913 
1914 		pos++;
1915 	}
1916 
1917 	if (failures != 0)
1918 	{
1919 		std::stringstream	css;
1920 
1921 		pos = 0;
1922 
1923 		for (deUint32 y = 0; y < height; ++y)
1924 		{
1925 			for (deUint32 x = 0; x < width; ++x)
1926 			{
1927 				if (resultPtr[pos] != expectedValue)
1928 					css << std::setw(3) << resultPtr[pos] << ",";
1929 				else
1930 					css << "___,";
1931 
1932 				pos++;
1933 			}
1934 
1935 			css << std::endl;
1936 		}
1937 
1938 		log << tcu::TestLog::Message << "Retrieved:" << tcu::TestLog::EndMessage;
1939 		log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
1940 	}
1941 
1942 	return (failures == 0);
1943 }
1944 
1945 
1946 class RayQueryBuiltinTestInstance : public TestInstance
1947 {
1948 public:
1949 										RayQueryBuiltinTestInstance		(Context& context, const TestParams& data);
1950 	virtual								~RayQueryBuiltinTestInstance	(void);
1951 	tcu::TestStatus						iterate							(void);
1952 
1953 private:
1954 	TestParams							m_data;
1955 	de::MovePtr<TestConfiguration>		m_testConfig;
1956 	de::MovePtr<PipelineConfiguration>	m_pipelineConfig;
1957 };
1958 
RayQueryBuiltinTestInstance(Context & context,const TestParams & data)1959 RayQueryBuiltinTestInstance::RayQueryBuiltinTestInstance (Context& context, const TestParams& data)
1960 	: vkt::TestInstance		(context)
1961 	, m_data				(data)
1962 {
1963 	switch (m_data.testType)
1964 	{
1965 		case TEST_TYPE_NO_MISS:		m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationNoMiss());		break;
1966 		case TEST_TYPE_SINGLE_HIT:	m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationSingleHit());	break;
1967 		default: TCU_THROW(InternalError, "Unknown test type");
1968 	}
1969 
1970 	switch (m_data.stage)
1971 	{
1972 		case VK_SHADER_STAGE_VERTEX_BIT:
1973 		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
1974 		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
1975 		case VK_SHADER_STAGE_GEOMETRY_BIT:
1976 		case VK_SHADER_STAGE_FRAGMENT_BIT:
1977 		{
1978 			m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new GraphicsConfiguration());
1979 			break;
1980 		}
1981 
1982 		case VK_SHADER_STAGE_COMPUTE_BIT:
1983 		{
1984 			m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new ComputeConfiguration());
1985 			break;
1986 		}
1987 
1988 		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
1989 		case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
1990 		case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
1991 		case VK_SHADER_STAGE_MISS_BIT_KHR:
1992 		case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
1993 		case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
1994 		{
1995 			m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new RayTracingConfiguration());
1996 			break;
1997 		}
1998 
1999 		default:
2000 			TCU_THROW(InternalError, "Unknown shader stage");
2001 	}
2002 }
2003 
~RayQueryBuiltinTestInstance(void)2004 RayQueryBuiltinTestInstance::~RayQueryBuiltinTestInstance (void)
2005 {
2006 }
2007 
iterate(void)2008 tcu::TestStatus RayQueryBuiltinTestInstance::iterate (void)
2009 {
2010 	const DeviceInterface&				vkd									= m_context.getDeviceInterface();
2011 	const VkDevice						device								= m_context.getDevice();
2012 	const VkQueue						queue								= m_context.getUniversalQueue();
2013 	Allocator&							allocator							= m_context.getDefaultAllocator();
2014 	const deUint32						queueFamilyIndex					= m_context.getUniversalQueueFamilyIndex();
2015 
2016 	const deUint32						width								= m_data.width;
2017 	const deUint32						height								= m_data.height;
2018 	const deUint32						depth								= m_data.depth;
2019 	const VkImageCreateInfo				imageCreateInfo						= makeImageCreateInfo(m_data.format, width, height, depth);
2020 	const VkImageSubresourceRange		imageSubresourceRange				= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2021 	const de::MovePtr<ImageWithMemory>	image								= de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
2022 	const Move<VkImageView>				imageView							= makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, m_data.format, imageSubresourceRange);
2023 
2024 	const deUint32						pixelSize							= mapVkFormat(m_data.format).getPixelSize();
2025 	const VkBufferCreateInfo			resultBufferCreateInfo				= makeBufferCreateInfo(width * height * depth * pixelSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
2026 	const VkImageSubresourceLayers		resultBufferImageSubresourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2027 	const VkBufferImageCopy				resultBufferImageRegion				= makeBufferImageCopy(makeExtent3D(width, height, depth), resultBufferImageSubresourceLayers);
2028 	de::MovePtr<BufferWithMemory>		resultBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
2029 
2030 	const VkDescriptorImageInfo			resultImageInfo						= makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
2031 
2032 	const Move<VkCommandPool>			cmdPool								= createCommandPool(vkd, device, 0, queueFamilyIndex);
2033 	const Move<VkCommandBuffer>			cmdBuffer							= allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2034 	const VkAccelerationStructureKHR*	topAccelerationStructurePtr			= DE_NULL;
2035 
2036 	m_pipelineConfig->initConfiguration(m_context, m_data);
2037 
2038 	beginCommandBuffer(vkd, *cmdBuffer, 0u);
2039 	{
2040 		const VkImageMemoryBarrier	preImageBarrier			= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, **image, imageSubresourceRange);
2041 		const VkClearValue			clearValue				= makeClearValueColorU32(0u, 0u, 0u, 0u);
2042 		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);
2043 		const VkMemoryBarrier		postTestMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
2044 		const VkMemoryBarrier		postCopyMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
2045 
2046 		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
2047 		vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
2048 		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
2049 
2050 		topAccelerationStructurePtr = m_testConfig->initAccelerationStructures(m_context, m_data, *cmdBuffer);
2051 
2052 		m_pipelineConfig->fillCommandBuffer(m_context, m_data, *cmdBuffer, topAccelerationStructurePtr, resultImageInfo);
2053 
2054 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTestMemoryBarrier);
2055 
2056 		vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
2057 
2058 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
2059 	}
2060 	endCommandBuffer(vkd, *cmdBuffer);
2061 
2062 	submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2063 
2064 	invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
2065 
2066 	if (m_testConfig->verify(resultBuffer.get(), m_context, m_data))
2067 		return tcu::TestStatus::pass("Pass");
2068 	else
2069 		return tcu::TestStatus::fail("Fail");
2070 }
2071 
2072 class RayQueryBuiltinTestCase : public TestCase
2073 {
2074 	public:
2075 							RayQueryBuiltinTestCase		(tcu::TestContext& context, const char* name, const char* desc, const TestParams data);
2076 							~RayQueryBuiltinTestCase	(void);
2077 
2078 	virtual void			checkSupport				(Context& context) const;
2079 	virtual	void			initPrograms				(SourceCollections& programCollection) const;
2080 	virtual TestInstance*	createInstance				(Context& context) const;
2081 
2082 private:
2083 	TestParams				m_data;
2084 };
2085 
RayQueryBuiltinTestCase(tcu::TestContext & context,const char * name,const char * desc,const TestParams data)2086 RayQueryBuiltinTestCase::RayQueryBuiltinTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams data)
2087 	: vkt::TestCase	(context, name, desc)
2088 	, m_data		(data)
2089 {
2090 }
2091 
~RayQueryBuiltinTestCase(void)2092 RayQueryBuiltinTestCase::~RayQueryBuiltinTestCase (void)
2093 {
2094 }
2095 
checkSupport(Context & context) const2096 void RayQueryBuiltinTestCase::checkSupport (Context& context) const
2097 {
2098 	context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
2099 	context.requireDeviceFunctionality("VK_KHR_ray_query");
2100 
2101 	const VkPhysicalDeviceRayQueryFeaturesKHR&				rayQueryFeaturesKHR					= context.getRayQueryFeatures();
2102 	if (rayQueryFeaturesKHR.rayQuery == DE_FALSE)
2103 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");
2104 
2105 	const VkPhysicalDeviceAccelerationStructureFeaturesKHR&	accelerationStructureFeaturesKHR	= context.getAccelerationStructureFeatures();
2106 	if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
2107 		TCU_THROW(TestError, "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
2108 
2109 	m_data.pipelineCheckSupport(context, m_data);
2110 }
2111 
createInstance(Context & context) const2112 TestInstance* RayQueryBuiltinTestCase::createInstance (Context& context) const
2113 {
2114 	return new RayQueryBuiltinTestInstance(context, m_data);
2115 }
2116 
initPrograms(SourceCollections & programCollection) const2117 void RayQueryBuiltinTestCase::initPrograms (SourceCollections& programCollection) const
2118 {
2119 	m_data.pipelineInitPrograms(programCollection, m_data);
2120 }
2121 
getPipelineCheckSupport(const VkShaderStageFlagBits stage)2122 static inline CheckSupportFunc getPipelineCheckSupport (const VkShaderStageFlagBits stage)
2123 {
2124 	switch (stage)
2125 	{
2126 		case VK_SHADER_STAGE_VERTEX_BIT:
2127 		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
2128 		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
2129 		case VK_SHADER_STAGE_GEOMETRY_BIT:
2130 		case VK_SHADER_STAGE_FRAGMENT_BIT:
2131 			return GraphicsConfiguration::checkSupport;
2132 
2133 		case VK_SHADER_STAGE_COMPUTE_BIT:
2134 			return ComputeConfiguration::checkSupport;
2135 
2136 		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2137 		case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2138 		case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2139 		case VK_SHADER_STAGE_MISS_BIT_KHR:
2140 		case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2141 		case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2142 			return RayTracingConfiguration::checkSupport;
2143 
2144 		default:
2145 			TCU_THROW(InternalError, "Unknown shader stage");
2146 	}
2147 }
2148 
getPipelineInitPrograms(const VkShaderStageFlagBits stage)2149 static inline InitProgramsFunc getPipelineInitPrograms (const VkShaderStageFlagBits stage)
2150 {
2151 	switch (stage)
2152 	{
2153 		case VK_SHADER_STAGE_VERTEX_BIT:
2154 		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
2155 		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
2156 		case VK_SHADER_STAGE_GEOMETRY_BIT:
2157 		case VK_SHADER_STAGE_FRAGMENT_BIT:
2158 			return GraphicsConfiguration::initPrograms;
2159 
2160 		case VK_SHADER_STAGE_COMPUTE_BIT:
2161 			return ComputeConfiguration::initPrograms;
2162 
2163 		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2164 		case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2165 		case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2166 		case VK_SHADER_STAGE_MISS_BIT_KHR:
2167 		case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2168 		case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2169 			return RayTracingConfiguration::initPrograms;
2170 
2171 		default:
2172 			TCU_THROW(InternalError, "Unknown shader stage");
2173 	}
2174 }
2175 
getShaderBodyTextFunc(const TestType testType)2176 static inline ShaderBodyTextFunc getShaderBodyTextFunc (const TestType testType)
2177 {
2178 	switch (testType)
2179 	{
2180 		case TEST_TYPE_NO_MISS:		return getShaderBodyText;
2181 		case TEST_TYPE_SINGLE_HIT:	return getShaderBodyText;
2182 		default:					TCU_THROW(InternalError, "Unknown test type");
2183 	}
2184 }
2185 
2186 }	// anonymous
2187 
createWatertightnessTests(tcu::TestContext & testCtx)2188 tcu::TestCaseGroup*	createWatertightnessTests	(tcu::TestContext& testCtx)
2189 {
2190 	const deUint32					seed	= (deUint32)(testCtx.getCommandLine().getBaseSeed());
2191 	de::MovePtr<tcu::TestCaseGroup> group	(new tcu::TestCaseGroup(testCtx, "watertightness", "Tests watertightness of ray query"));
2192 
2193 	const struct PipelineStages
2194 	{
2195 		VkShaderStageFlagBits	stage;
2196 		const char*				name;
2197 	}
2198 	pipelineStages[] =
2199 	{
2200 		{ VK_SHADER_STAGE_VERTEX_BIT,					"vert"			},
2201 		{ VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,		"tesc"			},
2202 		{ VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,	"tese"			},
2203 		{ VK_SHADER_STAGE_GEOMETRY_BIT,					"geom"			},
2204 		{ VK_SHADER_STAGE_FRAGMENT_BIT,					"frag"			},
2205 		{ VK_SHADER_STAGE_COMPUTE_BIT,					"comp"			},
2206 		{ VK_SHADER_STAGE_RAYGEN_BIT_KHR,				"rgen"			},
2207 		{ VK_SHADER_STAGE_ANY_HIT_BIT_KHR,				"ahit"			},
2208 		{ VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,			"chit"			},
2209 		{ VK_SHADER_STAGE_MISS_BIT_KHR,					"miss"			},
2210 		{ VK_SHADER_STAGE_INTERSECTION_BIT_KHR,			"sect"			},
2211 		{ VK_SHADER_STAGE_CALLABLE_BIT_KHR,				"call"			},
2212 	};
2213 	const struct TestTypes
2214 	{
2215 		TestType	testType;
2216 		const char*	name;
2217 	}
2218 	testTypes[] =
2219 	{
2220 		{ TEST_TYPE_NO_MISS,							"nomiss"		},
2221 		{ TEST_TYPE_SINGLE_HIT,							"singlehit"		},
2222 	};
2223 	const struct GeomTypes
2224 	{
2225 		GeomType	geomType;
2226 		const char*	name;
2227 	}
2228 	geomTypes[] =
2229 	{
2230 		{ GEOM_TYPE_TRIANGLES,							"triangles"		},
2231 		{ GEOM_TYPE_AABBS,								"aabbs"			},
2232 	};
2233 
2234 	for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
2235 	{
2236 		de::MovePtr<tcu::TestCaseGroup>	testTypeGroup		(new tcu::TestCaseGroup(group->getTestContext(), testTypes[testTypeNdx].name, ""));
2237 		const TestType					testType			= testTypes[testTypeNdx].testType;
2238 		const ShaderBodyTextFunc		shaderBodyTextFunc	= getShaderBodyTextFunc(testType);
2239 		const deUint32					imageDepth			= 1;
2240 
2241 		for (size_t pipelineStageNdx = 0; pipelineStageNdx < DE_LENGTH_OF_ARRAY(pipelineStages); ++pipelineStageNdx)
2242 		{
2243 			de::MovePtr<tcu::TestCaseGroup>	sourceTypeGroup			(new tcu::TestCaseGroup(group->getTestContext(), pipelineStages[pipelineStageNdx].name, ""));
2244 			const VkShaderStageFlagBits		stage					= pipelineStages[pipelineStageNdx].stage;
2245 			const CheckSupportFunc			pipelineCheckSupport	= getPipelineCheckSupport(stage);
2246 			const InitProgramsFunc			pipelineInitPrograms	= getPipelineInitPrograms(stage);
2247 			const deUint32					instancesGroupCount		= 1;
2248 			const deUint32					geometriesGroupCount	= 1;
2249 			const deUint32					squaresGroupCount		= (TEST_WIDTH * TEST_HEIGHT) / geometriesGroupCount / instancesGroupCount;
2250 
2251 			DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == TEST_WIDTH * TEST_HEIGHT);
2252 
2253 			for (size_t geomTypeNdx = 0; geomTypeNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypeNdx)
2254 			{
2255 				const GeomType		geomType	= geomTypes[geomTypeNdx].geomType;
2256 				const TestParams	testParams	=
2257 				{
2258 					TEST_WIDTH,				//  deUint32				width;
2259 					TEST_HEIGHT,			//  deUint32				height;
2260 					imageDepth,				//  deUint32				depth;
2261 					seed,					//  deUint32				randomSeed;
2262 					testType,				//  TestType				testType;
2263 					stage,					//  VkShaderStageFlagBits	stage;
2264 					geomType,				//  GeomType				geomType;
2265 					squaresGroupCount,		//  deUint32				squaresGroupCount;
2266 					geometriesGroupCount,	//  deUint32				geometriesGroupCount;
2267 					instancesGroupCount,	//  deUint32				instancesGroupCount;
2268 					VK_FORMAT_R32_SINT,		//  VkFormat				format;
2269 					pipelineCheckSupport,	//  CheckSupportFunc		pipelineCheckSupport;
2270 					pipelineInitPrograms,	//  InitProgramsFunc		pipelineInitPrograms;
2271 					shaderBodyTextFunc,		//  ShaderTestTextFunc		testConfigShaderBodyText;
2272 				};
2273 
2274 				if (testType == TEST_TYPE_SINGLE_HIT && geomType == GEOM_TYPE_AABBS)
2275 					continue;
2276 
2277 				sourceTypeGroup->addChild(new RayQueryBuiltinTestCase(group->getTestContext(), geomTypes[geomTypeNdx].name, "", testParams));
2278 			}
2279 
2280 			testTypeGroup->addChild(sourceTypeGroup.release());
2281 		}
2282 
2283 		group->addChild(testTypeGroup.release());
2284 	}
2285 
2286 	return group.release();
2287 }
2288 
2289 }	// RayQuery
2290 }	// vkt
2291