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