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