• 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 Testing traversal control in ray query extension
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktRayQueryTraversalControlTests.hpp"
25 
26 #include <array>
27 
28 #include "vkDefs.hpp"
29 
30 #include "vktTestCase.hpp"
31 #include "vktTestGroupUtil.hpp"
32 #include "vkCmdUtil.hpp"
33 #include "vkObjUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkBarrierUtil.hpp"
36 #include "vkBufferWithMemory.hpp"
37 #include "vkImageWithMemory.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkImageUtil.hpp"
40 #include "deRandom.hpp"
41 #include "tcuTexture.hpp"
42 #include "tcuTextureUtil.hpp"
43 #include "tcuTestLog.hpp"
44 #include "tcuImageCompare.hpp"
45 
46 #include "vkRayTracingUtil.hpp"
47 
48 namespace vkt
49 {
50 namespace RayQuery
51 {
52 namespace
53 {
54 using namespace vk;
55 using namespace vkt;
56 
57 static const VkFlags	ALL_RAY_TRACING_STAGES	= VK_SHADER_STAGE_RAYGEN_BIT_KHR
58 												| VK_SHADER_STAGE_ANY_HIT_BIT_KHR
59 												| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
60 												| VK_SHADER_STAGE_MISS_BIT_KHR
61 												| VK_SHADER_STAGE_INTERSECTION_BIT_KHR
62 												| VK_SHADER_STAGE_CALLABLE_BIT_KHR;
63 
64 enum ShaderSourcePipeline
65 {
66 	SSP_GRAPHICS_PIPELINE,
67 	SSP_COMPUTE_PIPELINE,
68 	SSP_RAY_TRACING_PIPELINE
69 };
70 
71 enum ShaderSourceType
72 {
73 	SST_VERTEX_SHADER,
74 	SST_TESSELATION_CONTROL_SHADER,
75 	SST_TESSELATION_EVALUATION_SHADER,
76 	SST_GEOMETRY_SHADER,
77 	SST_FRAGMENT_SHADER,
78 	SST_COMPUTE_SHADER,
79 	SST_RAY_GENERATION_SHADER,
80 	SST_INTERSECTION_SHADER,
81 	SST_ANY_HIT_SHADER,
82 	SST_CLOSEST_HIT_SHADER,
83 	SST_MISS_SHADER,
84 	SST_CALLABLE_SHADER,
85 };
86 
87 enum ShaderTestType
88 {
89 	STT_GENERATE_INTERSECTION		= 0,
90 	STT_SKIP_INTERSECTION			= 1,
91 };
92 
93 enum BottomTestType
94 {
95 	BTT_TRIANGLES,
96 	BTT_AABBS
97 };
98 
99 const deUint32			TEST_WIDTH			= 8;
100 const deUint32			TEST_HEIGHT			= 8;
101 
102 struct TestParams;
103 
104 class TestConfiguration
105 {
106 public:
107 	virtual					~TestConfiguration					();
108 	virtual void			initConfiguration					(Context&						context,
109 																 TestParams&					testParams) = 0;
110 	virtual void			fillCommandBuffer					(Context&						context,
111 																 TestParams&					testParams,
112 																 VkCommandBuffer				commandBuffer,
113 																 const VkWriteDescriptorSetAccelerationStructureKHR&	rayQueryAccelerationStructureWriteDescriptorSet,
114 																 const VkDescriptorImageInfo&	resultImageInfo) = 0;
115 	virtual bool			verifyImage							(BufferWithMemory*				resultBuffer,
116 																 Context&						context,
117 																 TestParams&					testParams) = 0;
118 	virtual VkFormat		getResultImageFormat				() = 0;
119 	virtual size_t			getResultImageFormatSize			() = 0;
120 	virtual VkClearValue	getClearValue						() = 0;
121 };
122 
~TestConfiguration()123 TestConfiguration::~TestConfiguration()
124 {
125 }
126 
127 struct TestParams
128 {
129 	deUint32							width;
130 	deUint32							height;
131 	ShaderSourceType					shaderSourceType;
132 	ShaderSourcePipeline				shaderSourcePipeline;
133 	ShaderTestType						shaderTestType;
134 	BottomTestType						bottomType;
135 };
136 
getShaderGroupHandleSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)137 deUint32 getShaderGroupHandleSize (const InstanceInterface&	vki,
138 								   const VkPhysicalDevice	physicalDevice)
139 {
140 	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
141 
142 	rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physicalDevice);
143 	return rayTracingPropertiesKHR->getShaderGroupHandleSize();
144 }
145 
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)146 deUint32 getShaderGroupBaseAlignment (const InstanceInterface&	vki,
147 									  const VkPhysicalDevice	physicalDevice)
148 {
149 	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
150 
151 	rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
152 	return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
153 }
154 
makeImageCreateInfo(deUint32 width,deUint32 height,deUint32 depth,VkFormat format)155 VkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, deUint32 depth, VkFormat format)
156 {
157 	const VkImageCreateInfo			imageCreateInfo			=
158 	{
159 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,																// VkStructureType			sType;
160 		DE_NULL,																							// const void*				pNext;
161 		(VkImageCreateFlags)0u,																				// VkImageCreateFlags		flags;
162 		VK_IMAGE_TYPE_3D,																					// VkImageType				imageType;
163 		format,																								// VkFormat					format;
164 		makeExtent3D(width, height, depth),																	// VkExtent3D				extent;
165 		1u,																									// deUint32					mipLevels;
166 		1u,																									// deUint32					arrayLayers;
167 		VK_SAMPLE_COUNT_1_BIT,																				// VkSampleCountFlagBits	samples;
168 		VK_IMAGE_TILING_OPTIMAL,																			// VkImageTiling			tiling;
169 		VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,		// VkImageUsageFlags		usage;
170 		VK_SHARING_MODE_EXCLUSIVE,																			// VkSharingMode			sharingMode;
171 		0u,																									// deUint32					queueFamilyIndexCount;
172 		DE_NULL,																							// const deUint32*			pQueueFamilyIndices;
173 		VK_IMAGE_LAYOUT_UNDEFINED																			// VkImageLayout			initialLayout;
174 	};
175 
176 	return imageCreateInfo;
177 }
178 
registerShaderModule(const DeviceInterface & vkd,const VkDevice device,Context & context,std::vector<de::SharedPtr<Move<VkShaderModule>>> & shaderModules,std::vector<VkPipelineShaderStageCreateInfo> & shaderCreateInfos,VkShaderStageFlagBits stage,const std::string & externalNamePart,const std::string & internalNamePart)179 bool registerShaderModule (const DeviceInterface&								vkd,
180 						   const VkDevice										device,
181 						   Context&												context,
182 						   std::vector<de::SharedPtr<Move<VkShaderModule>>>&	shaderModules,
183 						   std::vector<VkPipelineShaderStageCreateInfo>&		shaderCreateInfos,
184 						   VkShaderStageFlagBits								stage,
185 						   const std::string&									externalNamePart,
186 						   const std::string&									internalNamePart)
187 {
188 	char fullShaderName[40];
189 	snprintf(fullShaderName, 40, externalNamePart.c_str(), internalNamePart.c_str());
190 	std::string fsn = fullShaderName;
191 	if (fsn.empty())
192 		return false;
193 
194 	shaderModules.push_back(makeVkSharedPtr(createShaderModule(vkd, device, context.getBinaryCollection().get(fsn), 0)));
195 
196 	shaderCreateInfos.push_back(
197 		{
198 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
199 			DE_NULL,
200 			(VkPipelineShaderStageCreateFlags)0,
201 			stage,														// stage
202 			shaderModules.back()->get(),								// shader
203 			"main",
204 			DE_NULL,													// pSpecializationInfo
205 		});
206 
207 	return true;
208 }
209 
registerShaderModule(const DeviceInterface & vkd,const VkDevice device,Context & context,RayTracingPipeline & rayTracingPipeline,VkShaderStageFlagBits shaderStage,const std::string & externalNamePart,const std::string & internalNamePart,deUint32 groupIndex)210 bool registerShaderModule (const DeviceInterface&	vkd,
211 						   const VkDevice			device,
212 						   Context&					context,
213 						   RayTracingPipeline&		rayTracingPipeline,
214 						   VkShaderStageFlagBits	shaderStage,
215 						   const std::string&		externalNamePart,
216 						   const std::string&		internalNamePart,
217 						   deUint32					groupIndex)
218 {
219 	char fullShaderName[40];
220 	snprintf(fullShaderName, 40, externalNamePart.c_str(), internalNamePart.c_str());
221 	std::string fsn = fullShaderName;
222 	if (fsn.empty())
223 		return false;
224 	Move<VkShaderModule> shaderModule = createShaderModule(vkd, device, context.getBinaryCollection().get(fsn), 0);
225 	if (*shaderModule == DE_NULL)
226 		return false;
227 	rayTracingPipeline.addShader(shaderStage, shaderModule, groupIndex);
228 	return true;
229 }
230 
231 class GraphicsConfiguration : public TestConfiguration
232 {
233 public:
234 	virtual							~GraphicsConfiguration		();
235 	void							initConfiguration			(Context&						context,
236 																 TestParams&					testParams) override;
237 	void							fillCommandBuffer			(Context&						context,
238 																 TestParams&					testParams,
239 																 VkCommandBuffer				commandBuffer,
240 																 const VkWriteDescriptorSetAccelerationStructureKHR&	rayQueryAccelerationStructureWriteDescriptorSet,
241 																 const VkDescriptorImageInfo&	resultImageInfo) override;
242 	bool							verifyImage					(BufferWithMemory*				resultBuffer,
243 																 Context&						context,
244 																 TestParams&					testParams) override;
245 	VkFormat						getResultImageFormat		() override;
246 	size_t							getResultImageFormatSize	() override;
247 	VkClearValue					getClearValue				() override;
248 protected:
249 	Move<VkDescriptorSetLayout>		descriptorSetLayout;
250 	Move<VkDescriptorPool>			descriptorPool;
251 	Move<VkDescriptorSet>			descriptorSet;
252 	Move<VkPipelineLayout>			pipelineLayout;
253 	Move<VkRenderPass>				renderPass;
254 	Move<VkFramebuffer>				framebuffer;
255 	std::vector<de::SharedPtr<Move<VkShaderModule> > >	shaderModules;
256 	Move<VkPipeline>				pipeline;
257 	std::vector<tcu::Vec3>			vertices;
258 	Move<VkBuffer>					vertexBuffer;
259 	de::MovePtr<Allocation>			vertexAlloc;
260 };
261 
~GraphicsConfiguration()262 GraphicsConfiguration::~GraphicsConfiguration()
263 {
264 	shaderModules.clear();
265 }
266 
initConfiguration(Context & context,TestParams & testParams)267 void GraphicsConfiguration::initConfiguration (Context&						context,
268 											   TestParams&					testParams)
269 {
270 	const DeviceInterface&										vkd								= context.getDeviceInterface();
271 	const VkDevice												device							= context.getDevice();
272 	const deUint32												queueFamilyIndex				= context.getUniversalQueueFamilyIndex();
273 	Allocator&													allocator						= context.getDefaultAllocator();
274 
275 	descriptorSetLayout																			= DescriptorSetLayoutBuilder()
276 																										.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL_GRAPHICS)
277 																										.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL_GRAPHICS)
278 																										.build(vkd, device);
279 	descriptorPool																				= DescriptorPoolBuilder()
280 																										.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
281 																										.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
282 																										.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
283 	descriptorSet																				= makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
284 	pipelineLayout																				= makePipelineLayout(vkd, device, descriptorSetLayout.get());
285 
286 	std::vector<std::vector<std::string>>						rayQueryTestName(2);
287 	rayQueryTestName[BTT_TRIANGLES].push_back("rq_gen_triangle");
288 	rayQueryTestName[BTT_AABBS].push_back("rq_gen_aabb");
289 	rayQueryTestName[BTT_TRIANGLES].push_back("rq_skip_triangle");
290 	rayQueryTestName[BTT_AABBS].push_back("rq_skip_aabb");
291 
292 	const std::map<ShaderSourceType,std::vector<std::string>>	shaderNames						=
293 	{
294 										//idx:		0				1				2				3				4
295 										//shader:	vert,			tesc,			tese,			geom,			frag,
296 		{	SST_VERTEX_SHADER,					{	"vert_%s",		"",				"",				"",				"",			}	},
297 		{	SST_TESSELATION_CONTROL_SHADER,		{	"vert",			"tesc_%s",		"tese",			"",				"",			}	},
298 		{	SST_TESSELATION_EVALUATION_SHADER,	{	"vert",			"tesc",			"tese_%s",		"",				"",			}	},
299 		{	SST_GEOMETRY_SHADER,				{	"vert",			"",				"",				"geom_%s",		"",			}	},
300 		{	SST_FRAGMENT_SHADER,				{	"vert",			"",				"",				"",				"frag_%s",	}	},
301 	};
302 
303 	auto														shaderNameIt					= shaderNames.find(testParams.shaderSourceType);
304 	if(shaderNameIt == end(shaderNames))
305 		TCU_THROW(InternalError, "Wrong shader source type");
306 
307 	std::vector<VkPipelineShaderStageCreateInfo>				shaderCreateInfos;
308 	bool tescX, teseX, fragX;
309 			registerShaderModule(vkd,	device,	context,	shaderModules,	shaderCreateInfos,	VK_SHADER_STAGE_VERTEX_BIT,						shaderNameIt->second[0],	rayQueryTestName[testParams.bottomType][testParams.shaderTestType]);
310 	tescX = registerShaderModule(vkd,	device, context,	shaderModules,	shaderCreateInfos,	VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,		shaderNameIt->second[1],	rayQueryTestName[testParams.bottomType][testParams.shaderTestType]);
311 	teseX = registerShaderModule(vkd,	device,	context,	shaderModules,	shaderCreateInfos,	VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,	shaderNameIt->second[2],	rayQueryTestName[testParams.bottomType][testParams.shaderTestType]);
312 			registerShaderModule(vkd,	device,	context,	shaderModules,	shaderCreateInfos,	VK_SHADER_STAGE_GEOMETRY_BIT,					shaderNameIt->second[3],	rayQueryTestName[testParams.bottomType][testParams.shaderTestType]);
313 	fragX = registerShaderModule(vkd,	device,	context,	shaderModules,	shaderCreateInfos,	VK_SHADER_STAGE_FRAGMENT_BIT,					shaderNameIt->second[4],	rayQueryTestName[testParams.bottomType][testParams.shaderTestType]);
314 
315 	const vk::VkSubpassDescription		subpassDesc			=
316 	{
317 		(vk::VkSubpassDescriptionFlags)0,
318 		vk::VK_PIPELINE_BIND_POINT_GRAPHICS,							// pipelineBindPoint
319 		0u,																// inputCount
320 		DE_NULL,														// pInputAttachments
321 		0u,																// colorCount
322 		DE_NULL,														// pColorAttachments
323 		DE_NULL,														// pResolveAttachments
324 		DE_NULL,														// depthStencilAttachment
325 		0u,																// preserveCount
326 		DE_NULL,														// pPreserveAttachments
327 	};
328 	const vk::VkRenderPassCreateInfo	renderPassParams	=
329 	{
330 		vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,					// sType
331 		DE_NULL,														// pNext
332 		(vk::VkRenderPassCreateFlags)0,
333 		0u,																// attachmentCount
334 		DE_NULL,														// pAttachments
335 		1u,																// subpassCount
336 		&subpassDesc,													// pSubpasses
337 		0u,																// dependencyCount
338 		DE_NULL,														// pDependencies
339 	};
340 
341 	renderPass = createRenderPass(vkd, device, &renderPassParams);
342 
343 	const vk::VkFramebufferCreateInfo	framebufferParams	=
344 	{
345 		vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,					// sType
346 		DE_NULL,														// pNext
347 		(vk::VkFramebufferCreateFlags)0,
348 		*renderPass,													// renderPass
349 		0u,																// attachmentCount
350 		DE_NULL,														// pAttachments
351 		testParams.width,												// width
352 		testParams.height,												// height
353 		1u,																// layers
354 	};
355 
356 	framebuffer = createFramebuffer(vkd, device, &framebufferParams);
357 
358 	VkPrimitiveTopology					testTopology		= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
359 	tcu::Vec3 v0(1.0f, 1.0f, 0.0f);
360 	tcu::Vec3 v1(float(testParams.width) - 1.0f, 1.0f, 0.0f);
361 	tcu::Vec3 v2(1.0f, float(testParams.height) - 1.0f, 0.0f);
362 	tcu::Vec3 v3(float(testParams.width) - 1.0f, float(testParams.height) - 1.0f, 0.0f);
363 
364 	switch (testParams.shaderSourceType)
365 	{
366 		case SST_TESSELATION_CONTROL_SHADER:
367 		case SST_TESSELATION_EVALUATION_SHADER:
368 			testTopology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
369 			vertices.push_back(v0);
370 			vertices.push_back(v1);
371 			vertices.push_back(v2);
372 			vertices.push_back(v1);
373 			vertices.push_back(v3);
374 			vertices.push_back(v2);
375 			break;
376 		case SST_VERTEX_SHADER:
377 		case SST_GEOMETRY_SHADER:
378 			vertices.push_back(v0);
379 			vertices.push_back(v1);
380 			vertices.push_back(v2);
381 			vertices.push_back(v3);
382 			break;
383 		case SST_FRAGMENT_SHADER:
384 			vertices.push_back( tcu::Vec3(-1.0f,  1.0f, 0.0f) );
385 			vertices.push_back( tcu::Vec3(-1.0f, -1.0f, 0.0f) );
386 			vertices.push_back( tcu::Vec3( 1.0f,  1.0f, 0.0f) );
387 			vertices.push_back( tcu::Vec3( 1.0f, -1.0f, 0.0f) );
388 			break;
389 		default:
390 			TCU_THROW(InternalError, "Wrong shader source type");
391 	}
392 
393 	const VkVertexInputBindingDescription vertexInputBindingDescription =
394 	{
395 		0u,																// uint32_t											binding;
396 		sizeof(tcu::Vec3),												// uint32_t											stride;
397 		VK_VERTEX_INPUT_RATE_VERTEX,									// VkVertexInputRate								inputRate;
398 	};
399 
400 	const VkVertexInputAttributeDescription vertexInputAttributeDescription =
401 	{
402 		0u,																// uint32_t											location;
403 		0u,																// uint32_t											binding;
404 		VK_FORMAT_R32G32B32_SFLOAT,										// VkFormat											format;
405 		0u,																// uint32_t											offset;
406 	};
407 
408 	const VkPipelineVertexInputStateCreateInfo					vertexInputStateCreateInfo		=
409 	{
410 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType									sType;
411 		DE_NULL,														// const void*										pNext;
412 		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags			flags;
413 		1u,																// deUint32											vertexBindingDescriptionCount;
414 		&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*			pVertexBindingDescriptions;
415 		1u,																// deUint32											vertexAttributeDescriptionCount;
416 		&vertexInputAttributeDescription								// const VkVertexInputAttributeDescription*			pVertexAttributeDescriptions;
417 	};
418 
419 	const VkPipelineInputAssemblyStateCreateInfo				inputAssemblyStateCreateInfo	=
420 	{
421 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType									sType;
422 		DE_NULL,														// const void*										pNext;
423 		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags			flags;
424 		testTopology,													// VkPrimitiveTopology								topology;
425 		VK_FALSE														// VkBool32											primitiveRestartEnable;
426 	};
427 
428 	const VkPipelineTessellationStateCreateInfo					tessellationStateCreateInfo		=
429 	{
430 		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,		// VkStructureType									sType;
431 		DE_NULL,														// const void*										pNext;
432 		VkPipelineTessellationStateCreateFlags(0u),						// VkPipelineTessellationStateCreateFlags			flags;
433 		3u																// deUint32											patchControlPoints;
434 	};
435 
436 	VkViewport													viewport						= makeViewport(testParams.width, testParams.height);
437 	VkRect2D													scissor							= makeRect2D(testParams.width, testParams.height);
438 
439 	const VkPipelineViewportStateCreateInfo						viewportStateCreateInfo			=
440 	{
441 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType									sType
442 		DE_NULL,														// const void*										pNext
443 		(VkPipelineViewportStateCreateFlags)0,							// VkPipelineViewportStateCreateFlags				flags
444 		1u,																// deUint32											viewportCount
445 		&viewport,														// const VkViewport*								pViewports
446 		1u,																// deUint32											scissorCount
447 		&scissor														// const VkRect2D*									pScissors
448 	};
449 
450 	const VkPipelineRasterizationStateCreateInfo				rasterizationStateCreateInfo =
451 	{
452 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType									sType;
453 		DE_NULL,														// const void*										pNext;
454 		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags			flags;
455 		VK_FALSE,														// VkBool32											depthClampEnable;
456 		fragX ? VK_FALSE : VK_TRUE,										// VkBool32											rasterizerDiscardEnable;
457 		VK_POLYGON_MODE_FILL,											// VkPolygonMode									polygonMode;
458 		VK_CULL_MODE_NONE,												// VkCullModeFlags									cullMode;
459 		VK_FRONT_FACE_CLOCKWISE,										// VkFrontFace										frontFace;
460 		VK_FALSE,														// VkBool32											depthBiasEnable;
461 		0.0f,															// float											depthBiasConstantFactor;
462 		0.0f,															// float											depthBiasClamp;
463 		0.0f,															// float											depthBiasSlopeFactor;
464 		1.0f															// float											lineWidth;
465 	};
466 
467 	const VkPipelineMultisampleStateCreateInfo		multisampleStateCreateInfo =
468 	{
469 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType									sType;
470 		DE_NULL,														// const void*										pNext;
471 		(VkPipelineMultisampleStateCreateFlags)0,						// VkPipelineMultisampleStateCreateFlags			flags;
472 		VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits							rasterizationSamples;
473 		VK_FALSE,														// VkBool32											sampleShadingEnable;
474 		0.0f,															// float											minSampleShading;
475 		DE_NULL,														// const VkSampleMask*								pSampleMask;
476 		VK_FALSE,														// VkBool32											alphaToCoverageEnable;
477 		VK_FALSE														// VkBool32											alphaToOneEnable;
478 	};
479 
480 	const VkPipelineColorBlendStateCreateInfo		colorBlendStateCreateInfo =
481 	{
482 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,		// VkStructureType									sType;
483 		DE_NULL,														// const void*										pNext;
484 		(VkPipelineColorBlendStateCreateFlags)0,						// VkPipelineColorBlendStateCreateFlags				flags;
485 		DE_FALSE,														// VkBool32											logicOpEnable;
486 		VK_LOGIC_OP_CLEAR,												// VkLogicOp										logicOp;
487 		0,																// deUint32											attachmentCount;
488 		DE_NULL,														// const VkPipelineColorBlendAttachmentState*		pAttachments;
489 		{ 1.0f, 1.0f, 1.0f, 1.0f }										// float											blendConstants[4];
490 	};
491 
492 	const VkGraphicsPipelineCreateInfo							graphicsPipelineCreateInfo		=
493 	{
494 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,				// VkStructureType									sType;
495 		DE_NULL,														// const void*										pNext;
496 		(VkPipelineCreateFlags)0,										// VkPipelineCreateFlags							flags;
497 		static_cast<deUint32>(shaderCreateInfos.size()),				// deUint32											stageCount;
498 		shaderCreateInfos.data(),										// const VkPipelineShaderStageCreateInfo*			pStages;
499 		&vertexInputStateCreateInfo,									// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
500 		&inputAssemblyStateCreateInfo,									// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
501 		(tescX||teseX) ? &tessellationStateCreateInfo : DE_NULL,		// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
502 		fragX ? &viewportStateCreateInfo : DE_NULL,						// const VkPipelineViewportStateCreateInfo*			pViewportState;
503 		&rasterizationStateCreateInfo,									// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
504 		fragX ? &multisampleStateCreateInfo : DE_NULL,					// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
505 		DE_NULL,														// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
506 		fragX ? &colorBlendStateCreateInfo : DE_NULL,					// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
507 		DE_NULL,														// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
508 		pipelineLayout.get(),											// VkPipelineLayout									layout;
509 		renderPass.get(),												// VkRenderPass										renderPass;
510 		0u,																// deUint32											subpass;
511 		DE_NULL,														// VkPipeline										basePipelineHandle;
512 		0																// int												basePipelineIndex;
513 	};
514 
515 	pipeline = createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineCreateInfo);
516 
517 	const VkBufferCreateInfo									vertexBufferParams				=
518 	{
519 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,							// VkStructureType									sType;
520 		DE_NULL,														// const void*										pNext;
521 		0u,																// VkBufferCreateFlags								flags;
522 		VkDeviceSize(sizeof(tcu::Vec3) * vertices.size()),				// VkDeviceSize										size;
523 		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
524 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,							// VkBufferUsageFlags								usage;
525 		VK_SHARING_MODE_EXCLUSIVE,										// VkSharingMode									sharingMode;
526 		1u,																// deUint32											queueFamilyIndexCount;
527 		&queueFamilyIndex												// const deUint32*									pQueueFamilyIndices;
528 	};
529 
530 	vertexBuffer	= createBuffer(vkd, device, &vertexBufferParams);
531 	vertexAlloc		= allocator.allocate(getBufferMemoryRequirements(vkd, device, *vertexBuffer), MemoryRequirement::HostVisible);
532 	VK_CHECK(vkd.bindBufferMemory(device, *vertexBuffer, vertexAlloc->getMemory(), vertexAlloc->getOffset()));
533 
534 	// Upload vertex data
535 	deMemcpy(vertexAlloc->getHostPtr(), vertices.data(), vertices.size() * sizeof(tcu::Vec3));
536 	flushAlloc(vkd, device, *vertexAlloc);
537 }
538 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)539 void GraphicsConfiguration::fillCommandBuffer (Context&						context,
540 											   TestParams&					testParams,
541 											   VkCommandBuffer				commandBuffer,
542 											   const VkWriteDescriptorSetAccelerationStructureKHR&	rayQueryAccelerationStructureWriteDescriptorSet,
543 											   const VkDescriptorImageInfo&	resultImageInfo)
544 {
545 	const DeviceInterface&				vkd									= context.getDeviceInterface();
546 	const VkDevice						device								= context.getDevice();
547 
548 	DescriptorSetUpdateBuilder()
549 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
550 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
551 		.update(vkd, device);
552 
553 	const VkRenderPassBeginInfo			renderPassBeginInfo					=
554 	{
555 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,							// VkStructureType								sType;
556 		DE_NULL,															// const void*									pNext;
557 		*renderPass,														// VkRenderPass									renderPass;
558 		*framebuffer,														// VkFramebuffer								framebuffer;
559 		makeRect2D(testParams.width, testParams.height),					// VkRect2D										renderArea;
560 		0u,																	// uint32_t										clearValueCount;
561 		DE_NULL																// const VkClearValue*							pClearValues;
562 	};
563 	VkDeviceSize						vertexBufferOffset					= 0u;
564 
565 	vkd.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
566 	vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
567 	vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
568 	vkd.cmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
569 	vkd.cmdDraw(commandBuffer, deUint32(vertices.size()), 1, 0, 0);
570 	vkd.cmdEndRenderPass(commandBuffer);
571 }
572 
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)573 bool GraphicsConfiguration::verifyImage (BufferWithMemory*					resultBuffer,
574 										 Context&							context,
575 										 TestParams&						testParams)
576 {
577 	// create result image
578 	tcu::TextureFormat			imageFormat						= vk::mapVkFormat(getResultImageFormat());
579 	tcu::ConstPixelBufferAccess	resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr());
580 
581 	// create reference image
582 	std::vector<deUint32>		reference(testParams.width * testParams.height * 2);
583 	tcu::PixelBufferAccess		referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
584 
585 	tcu::UVec4 rqValue0, rqValue1;
586 	switch (testParams.shaderTestType)
587 	{
588 		case STT_GENERATE_INTERSECTION:
589 			switch (testParams.bottomType)
590 			{
591 				case BTT_TRIANGLES:
592 					rqValue0 = tcu::UVec4(1, 0, 0, 0);
593 					rqValue1 = tcu::UVec4(1, 0, 0, 0);
594 					break;
595 				case BTT_AABBS:
596 					rqValue0 = tcu::UVec4(2, 0, 0, 0);
597 					rqValue1 = tcu::UVec4(1, 0, 0, 0);
598 					break;
599 				default:
600 					TCU_THROW(InternalError, "Wrong bottom test type");
601 			}
602 			break;
603 		case STT_SKIP_INTERSECTION:
604 			switch (testParams.bottomType)
605 			{
606 				case BTT_TRIANGLES:
607 					rqValue0 = tcu::UVec4(0, 0, 0, 0);
608 					rqValue1 = tcu::UVec4(1, 0, 0, 0);
609 					break;
610 				case BTT_AABBS:
611 					rqValue0 = tcu::UVec4(0, 0, 0, 0);
612 					rqValue1 = tcu::UVec4(1, 0, 0, 0);
613 					break;
614 				default:
615 					TCU_THROW(InternalError, "Wrong bottom test type");
616 			}
617 			break;
618 		default:
619 			TCU_THROW(InternalError, "Wrong shader test type");
620 	}
621 
622 	std::vector<std::vector<deUint32>> primitives =
623 	{
624 		{0, 1, 2},
625 		{1, 3, 2}
626 	};
627 
628 	tcu::UVec4 clearValue, missValue, hitValue0, hitValue1;
629 	hitValue0	= rqValue0;
630 	hitValue1	= rqValue1;
631 	missValue	= tcu::UVec4(0, 0, 0, 0);
632 	clearValue	= tcu::UVec4(0xFF, 0, 0, 0);
633 
634 	switch (testParams.shaderSourceType)
635 	{
636 		case SST_VERTEX_SHADER:
637 			tcu::clear(referenceAccess, clearValue);
638 			for (deUint32 vertexNdx = 0; vertexNdx < 4; ++vertexNdx)
639 			{
640 				if (vertexNdx == 0)
641 				{
642 					referenceAccess.setPixel(hitValue0, vertexNdx, 0, 0);
643 					referenceAccess.setPixel(hitValue1, vertexNdx, 0, 1);
644 				}
645 				else
646 				{
647 					referenceAccess.setPixel(missValue, vertexNdx, 0, 0);
648 					referenceAccess.setPixel(missValue, vertexNdx, 0, 1);
649 				}
650 			}
651 			break;
652 		case SST_TESSELATION_EVALUATION_SHADER:
653 		case SST_TESSELATION_CONTROL_SHADER:
654 		case SST_GEOMETRY_SHADER:
655 			tcu::clear(referenceAccess, clearValue);
656 			for (deUint32 primitiveNdx = 0; primitiveNdx < primitives.size(); ++primitiveNdx)
657 			for (deUint32 vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
658 			{
659 				deUint32 vNdx = primitives[primitiveNdx][vertexNdx];
660 				if (vNdx==0)
661 				{
662 					referenceAccess.setPixel(hitValue0, primitiveNdx, vertexNdx, 0);
663 					referenceAccess.setPixel(hitValue1, primitiveNdx, vertexNdx, 1);
664 				}
665 				else
666 				{
667 					referenceAccess.setPixel(missValue, primitiveNdx, vertexNdx, 0);
668 					referenceAccess.setPixel(missValue, primitiveNdx, vertexNdx, 1);
669 				}
670 			}
671 			break;
672 		case SST_FRAGMENT_SHADER:
673 			tcu::clear(referenceAccess, missValue);
674 			for (deUint32 y = 1; y < testParams.height - 1; ++y)
675 			for (deUint32 x = 1; x < testParams.width - 1; ++x)
676 			{
677 				referenceAccess.setPixel(hitValue0, x, y, 0);
678 				referenceAccess.setPixel(hitValue1, x, y, 1);
679 			}
680 			break;
681 		default:
682 			TCU_THROW(InternalError, "Wrong shader source type");
683 	}
684 
685 	// compare result and reference
686 	return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
687 }
688 
getResultImageFormat()689 VkFormat GraphicsConfiguration::getResultImageFormat ()
690 {
691 	return VK_FORMAT_R32_UINT;
692 }
693 
getResultImageFormatSize()694 size_t GraphicsConfiguration::getResultImageFormatSize ()
695 {
696 	return sizeof(deUint32);
697 }
698 
getClearValue()699 VkClearValue GraphicsConfiguration::getClearValue ()
700 {
701 	return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
702 }
703 
704 class ComputeConfiguration : public TestConfiguration
705 {
706 public:
707 	virtual							~ComputeConfiguration		();
708 	void							initConfiguration			(Context&						context,
709 																 TestParams&					testParams) override;
710 	void							fillCommandBuffer			(Context&						context,
711 																 TestParams&					testParams,
712 																 VkCommandBuffer				commandBuffer,
713 																 const VkWriteDescriptorSetAccelerationStructureKHR&	rayQueryAccelerationStructureWriteDescriptorSet,
714 																 const VkDescriptorImageInfo&	resultImageInfo) override;
715 	bool							verifyImage					(BufferWithMemory*				resultBuffer,
716 																 Context&						context,
717 																 TestParams&					testParams) override;
718 	VkFormat						getResultImageFormat		() override;
719 	size_t							getResultImageFormatSize	() override;
720 	VkClearValue					getClearValue				() override;
721 protected:
722 	Move<VkDescriptorSetLayout>		descriptorSetLayout;
723 	Move<VkDescriptorPool>			descriptorPool;
724 	Move<VkDescriptorSet>			descriptorSet;
725 	Move<VkPipelineLayout>			pipelineLayout;
726 	Move<VkShaderModule>			shaderModule;
727 	Move<VkPipeline>				pipeline;
728 };
729 
~ComputeConfiguration()730 ComputeConfiguration::~ComputeConfiguration()
731 {
732 }
733 
initConfiguration(Context & context,TestParams & testParams)734 void ComputeConfiguration::initConfiguration (Context&						context,
735 											  TestParams&					testParams)
736 {
737 	const DeviceInterface&				vkd									= context.getDeviceInterface();
738 	const VkDevice						device								= context.getDevice();
739 
740 	descriptorSetLayout														= DescriptorSetLayoutBuilder()
741 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
742 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_COMPUTE_BIT)
743 																					.build(vkd, device);
744 	descriptorPool															= DescriptorPoolBuilder()
745 																					.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
746 																					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
747 																					.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
748 	descriptorSet															= makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
749 	pipelineLayout															= makePipelineLayout(vkd, device, descriptorSetLayout.get());
750 
751 	std::vector<std::vector<std::string>> rayQueryTestName(2);
752 	rayQueryTestName[BTT_TRIANGLES].push_back("comp_rq_gen_triangle");
753 	rayQueryTestName[BTT_AABBS].push_back("comp_rq_gen_aabb");
754 	rayQueryTestName[BTT_TRIANGLES].push_back("comp_rq_skip_triangle");
755 	rayQueryTestName[BTT_AABBS].push_back("comp_rq_skip_aabb");
756 
757 	shaderModule															= createShaderModule(vkd, device, context.getBinaryCollection().get(rayQueryTestName[testParams.bottomType][testParams.shaderTestType]), 0u);
758 	const VkPipelineShaderStageCreateInfo pipelineShaderStageParams			=
759 	{
760 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
761 		DE_NULL,												// const void*							pNext;
762 		0u,														// VkPipelineShaderStageCreateFlags		flags;
763 		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
764 		*shaderModule,											// VkShaderModule						module;
765 		"main",													// const char*							pName;
766 		DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
767 	};
768 	const VkComputePipelineCreateInfo pipelineCreateInfo =
769 	{
770 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
771 		DE_NULL,											// const void*						pNext;
772 		0u,													// VkPipelineCreateFlags			flags;
773 		pipelineShaderStageParams,							// VkPipelineShaderStageCreateInfo	stage;
774 		*pipelineLayout,									// VkPipelineLayout					layout;
775 		DE_NULL,											// VkPipeline						basePipelineHandle;
776 		0,													// deInt32							basePipelineIndex;
777 	};
778 
779 	pipeline																= createComputePipeline(vkd, device, DE_NULL, &pipelineCreateInfo);
780 }
781 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)782 void ComputeConfiguration::fillCommandBuffer (Context&						context,
783 											  TestParams&					testParams,
784 											  VkCommandBuffer				commandBuffer,
785 											  const VkWriteDescriptorSetAccelerationStructureKHR&	rayQueryAccelerationStructureWriteDescriptorSet,
786 											  const VkDescriptorImageInfo&	resultImageInfo)
787 {
788 	const DeviceInterface&				vkd									= context.getDeviceInterface();
789 	const VkDevice						device								= context.getDevice();
790 
791 	DescriptorSetUpdateBuilder()
792 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
793 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
794 		.update(vkd, device);
795 
796 	vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
797 
798 	vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
799 
800 	vkd.cmdDispatch(commandBuffer, testParams.width, testParams.height, 1);
801 }
802 
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)803 bool ComputeConfiguration::verifyImage (BufferWithMemory*					resultBuffer,
804 										Context&							context,
805 										TestParams&							testParams)
806 {
807 	// create result image
808 	tcu::TextureFormat			imageFormat						= vk::mapVkFormat(getResultImageFormat());
809 	tcu::ConstPixelBufferAccess	resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr());
810 
811 	// create reference image
812 	std::vector<deUint32>		reference(testParams.width * testParams.height * 2);
813 	tcu::PixelBufferAccess		referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
814 
815 	tcu::UVec4 rqValue0, rqValue1;
816 	switch (testParams.shaderTestType)
817 	{
818 		case STT_GENERATE_INTERSECTION:
819 			switch (testParams.bottomType)
820 			{
821 				case BTT_TRIANGLES:
822 					rqValue0 = tcu::UVec4(1, 0, 0, 0);
823 					rqValue1 = tcu::UVec4(1, 0, 0, 0);
824 					break;
825 				case BTT_AABBS:
826 					rqValue0 = tcu::UVec4(2, 0, 0, 0);
827 					rqValue1 = tcu::UVec4(1, 0, 0, 0);
828 					break;
829 				default:
830 					TCU_THROW(InternalError, "Wrong bottom test type");
831 			}
832 			break;
833 		case STT_SKIP_INTERSECTION:
834 			switch (testParams.bottomType)
835 			{
836 				case BTT_TRIANGLES:
837 					rqValue0 = tcu::UVec4(0, 0, 0, 0);
838 					rqValue1 = tcu::UVec4(1, 0, 0, 0);
839 					break;
840 				case BTT_AABBS:
841 					rqValue0 = tcu::UVec4(0, 0, 0, 0);
842 					rqValue1 = tcu::UVec4(1, 0, 0, 0);
843 					break;
844 				default:
845 					TCU_THROW(InternalError, "Wrong bottom test type");
846 			}
847 			break;
848 		default:
849 			TCU_THROW(InternalError, "Wrong shader test type");
850 	}
851 
852 	tcu::UVec4 missValue0, missValue1, hitValue0, hitValue1;
853 	hitValue0	= rqValue0;
854 	hitValue1	= rqValue1;
855 	missValue0	= tcu::UVec4(0, 0, 0, 0);
856 	missValue1	= tcu::UVec4(0, 0, 0, 0);
857 
858 	tcu::clear(referenceAccess, missValue0);
859 	for (deUint32 y = 0; y < testParams.height; ++y)
860 	for (deUint32 x = 0; x < testParams.width; ++x)
861 		referenceAccess.setPixel(missValue1, x, y, 1);
862 
863 	for (deUint32 y = 1; y < testParams.height - 1; ++y)
864 	for (deUint32 x = 1; x < testParams.width - 1; ++x)
865 	{
866 		referenceAccess.setPixel(hitValue0, x, y, 0);
867 		referenceAccess.setPixel(hitValue1, x, y, 1);
868 	}
869 
870 	// compare result and reference
871 	return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
872 }
873 
getResultImageFormat()874 VkFormat ComputeConfiguration::getResultImageFormat ()
875 {
876 	return VK_FORMAT_R32_UINT;
877 }
878 
getResultImageFormatSize()879 size_t ComputeConfiguration::getResultImageFormatSize ()
880 {
881 	return sizeof(deUint32);
882 }
883 
getClearValue()884 VkClearValue ComputeConfiguration::getClearValue ()
885 {
886 	return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
887 }
888 
889 class RayTracingConfiguration : public TestConfiguration
890 {
891 public:
892 	virtual							~RayTracingConfiguration	();
893 	void							initConfiguration			(Context&						context,
894 																 TestParams&					testParams) override;
895 	void							fillCommandBuffer			(Context&						context,
896 																 TestParams&					testParams,
897 																 VkCommandBuffer				commandBuffer,
898 																 const VkWriteDescriptorSetAccelerationStructureKHR&	rayQueryAccelerationStructureWriteDescriptorSet,
899 																 const VkDescriptorImageInfo&	resultImageInfo) override;
900 	bool							verifyImage					(BufferWithMemory*				resultBuffer,
901 																 Context&						context,
902 																 TestParams&					testParams) override;
903 	VkFormat						getResultImageFormat		() override;
904 	size_t							getResultImageFormatSize	() override;
905 	VkClearValue					getClearValue				() override;
906 protected:
907 	Move<VkDescriptorSetLayout>		descriptorSetLayout;
908 	Move<VkDescriptorPool>			descriptorPool;
909 	Move<VkDescriptorSet>			descriptorSet;
910 	Move<VkPipelineLayout>			pipelineLayout;
911 
912 	de::MovePtr<RayTracingPipeline>	rayTracingPipeline;
913 	Move<VkPipeline>				rtPipeline;
914 
915 	de::MovePtr<BufferWithMemory>	raygenShaderBindingTable;
916 	de::MovePtr<BufferWithMemory>	hitShaderBindingTable;
917 	de::MovePtr<BufferWithMemory>	missShaderBindingTable;
918 	de::MovePtr<BufferWithMemory>	callableShaderBindingTable;
919 
920 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >	bottomLevelAccelerationStructures;
921 	de::MovePtr<TopLevelAccelerationStructure>						topLevelAccelerationStructure;
922 };
923 
~RayTracingConfiguration()924 RayTracingConfiguration::~RayTracingConfiguration()
925 {
926 }
927 
initConfiguration(Context & context,TestParams & testParams)928 void RayTracingConfiguration::initConfiguration (Context&						context,
929 												 TestParams&					testParams)
930 {
931 	const InstanceInterface&			vki									= context.getInstanceInterface();
932 	const DeviceInterface&				vkd									= context.getDeviceInterface();
933 	const VkDevice						device								= context.getDevice();
934 	const VkPhysicalDevice				physicalDevice						= context.getPhysicalDevice();
935 	Allocator&							allocator							= context.getDefaultAllocator();
936 
937 	descriptorSetLayout														= DescriptorSetLayoutBuilder()
938 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
939 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
940 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
941 																					.build(vkd, device);
942 	descriptorPool															= DescriptorPoolBuilder()
943 																					.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
944 																					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
945 																					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
946 																					.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
947 	descriptorSet															= makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
948 	pipelineLayout															= makePipelineLayout(vkd, device, descriptorSetLayout.get());
949 
950 	rayTracingPipeline														= de::newMovePtr<RayTracingPipeline>();
951 
952 	const std::map<ShaderSourceType,std::vector<std::string>> shaderNames =
953 	{
954 								//idx:		0				1				2				3				4				5
955 								//shader:	rgen,			isect,			ahit,			chit,			miss,			call
956 								//group:	0				1				1				1				2				3
957 		{	SST_RAY_GENERATION_SHADER,	{	"rgen_%s",		"",				"",				"",				"",				""			}	},
958 		{	SST_INTERSECTION_SHADER,	{	"rgen",			"isect_%s",		"",				"chit_isect",	"miss",			""			}	},
959 		{	SST_ANY_HIT_SHADER,			{	"rgen",			"isect",		"ahit_%s",		"",				"miss",			""			}	},
960 		{	SST_CLOSEST_HIT_SHADER,		{	"rgen",			"isect",		"",				"chit_%s",		"miss",			""			}	},
961 		{	SST_MISS_SHADER,			{	"rgen",			"isect",		"",				"chit",			"miss_%s",		""			}	},
962 		{	SST_CALLABLE_SHADER,		{	"rgen_call",	"",				"",				"chit",			"miss",			"call_%s"	}	},
963 	};
964 
965 	std::vector<std::vector<std::string>> rayQueryTestName(2);
966 	rayQueryTestName[BTT_TRIANGLES].push_back("rq_gen_triangle");
967 	rayQueryTestName[BTT_AABBS].push_back("rq_gen_aabb");
968 	rayQueryTestName[BTT_TRIANGLES].push_back("rq_skip_triangle");
969 	rayQueryTestName[BTT_AABBS].push_back("rq_skip_aabb");
970 
971 	auto shaderNameIt = shaderNames.find(testParams.shaderSourceType);
972 	if(shaderNameIt == end(shaderNames))
973 		TCU_THROW(InternalError, "Wrong shader source type");
974 
975 	bool rgenX, isectX, ahitX, chitX, missX, callX;
976 	rgenX = registerShaderModule(vkd,	device,	context,		*rayTracingPipeline,	VK_SHADER_STAGE_RAYGEN_BIT_KHR,			shaderNameIt->second[0],	rayQueryTestName[testParams.bottomType][testParams.shaderTestType],	0);
977 	if (testParams.shaderSourceType == SST_INTERSECTION_SHADER)
978 		isectX = registerShaderModule(vkd, device, context,		*rayTracingPipeline,	VK_SHADER_STAGE_INTERSECTION_BIT_KHR,	shaderNameIt->second[1],	rayQueryTestName[testParams.bottomType][testParams.shaderTestType],	1);
979 	else
980 		isectX = false;
981 	ahitX = registerShaderModule(vkd,	device,	context,		*rayTracingPipeline,	VK_SHADER_STAGE_ANY_HIT_BIT_KHR,		shaderNameIt->second[2],	rayQueryTestName[testParams.bottomType][testParams.shaderTestType],	1);
982 	chitX = registerShaderModule(vkd,	device,	context,		*rayTracingPipeline,	VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,	shaderNameIt->second[3],	rayQueryTestName[testParams.bottomType][testParams.shaderTestType],	1);
983 	missX = registerShaderModule(vkd,	device,	context,		*rayTracingPipeline,	VK_SHADER_STAGE_MISS_BIT_KHR,			shaderNameIt->second[4],	rayQueryTestName[testParams.bottomType][testParams.shaderTestType],	2);
984 	callX = registerShaderModule(vkd,	device,	context,		*rayTracingPipeline,	VK_SHADER_STAGE_CALLABLE_BIT_KHR,		shaderNameIt->second[5],	rayQueryTestName[testParams.bottomType][testParams.shaderTestType],	3);
985 	bool hitX = isectX || ahitX || chitX;
986 
987 	rtPipeline																= rayTracingPipeline->createPipeline(vkd, device, *pipelineLayout);
988 
989 	deUint32							shaderGroupHandleSize				= getShaderGroupHandleSize(vki, physicalDevice);
990 	deUint32							shaderGroupBaseAlignment			= getShaderGroupBaseAlignment(vki, physicalDevice);
991 
992 	if (rgenX)	raygenShaderBindingTable									= rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
993 	if (hitX)	hitShaderBindingTable										= rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
994 	if (missX)	missShaderBindingTable										= rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1);
995 	if (callX)	callableShaderBindingTable									= rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 3, 1);
996 }
997 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)998 void RayTracingConfiguration::fillCommandBuffer (Context&						context,
999 												 TestParams&					testParams,
1000 												 VkCommandBuffer				commandBuffer,
1001 												 const VkWriteDescriptorSetAccelerationStructureKHR&	rayQueryAccelerationStructureWriteDescriptorSet,
1002 												 const VkDescriptorImageInfo&	resultImageInfo)
1003 {
1004 	const InstanceInterface&			vki									= context.getInstanceInterface();
1005 	const DeviceInterface&				vkd									= context.getDeviceInterface();
1006 	const VkDevice						device								= context.getDevice();
1007 	const VkPhysicalDevice				physicalDevice						= context.getPhysicalDevice();
1008 	Allocator&							allocator							= context.getDefaultAllocator();
1009 
1010 	{
1011 		de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1012 		bottomLevelAccelerationStructure->setGeometryCount(1);
1013 
1014 		de::SharedPtr<RaytracedGeometryBase> geometry;
1015 		if (testParams.shaderSourceType != SST_INTERSECTION_SHADER)
1016 		{
1017 			tcu::Vec3 v0(0.0f, 0.5f * float(testParams.height), 0.0f);
1018 			tcu::Vec3 v1(0.0f, 0.0f, 0.0f);
1019 			tcu::Vec3 v2(float(testParams.width), 0.5f * float(testParams.height), 0.0f);
1020 			tcu::Vec3 v3(float(testParams.width), 0.0f, 0.0f);
1021 
1022 			geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1023 			geometry->addVertex(v0);
1024 			geometry->addVertex(v1);
1025 			geometry->addVertex(v2);
1026 			geometry->addVertex(v2);
1027 			geometry->addVertex(v1);
1028 			geometry->addVertex(v3);
1029 		}
1030 		else // testParams.shaderSourceType == SST_INTERSECTION_SHADER
1031 		{
1032 			tcu::Vec3 v0(0.0f, 0.0f, -0.1f);
1033 			tcu::Vec3 v1(float(testParams.width), 0.5f * float(testParams.height), 0.1f);
1034 
1035 			geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1036 			geometry->addVertex(v0);
1037 			geometry->addVertex(v1);
1038 		}
1039 		bottomLevelAccelerationStructure->addGeometry(geometry);
1040 		bottomLevelAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1041 
1042 		for (auto& blas : bottomLevelAccelerationStructures)
1043 			blas->createAndBuild(vkd, device, commandBuffer, allocator);
1044 	}
1045 
1046 	topLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1047 	topLevelAccelerationStructure->setInstanceCount(1);
1048 	topLevelAccelerationStructure->addInstance(bottomLevelAccelerationStructures[0]);
1049 	topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1050 
1051 	const TopLevelAccelerationStructure*			topLevelAccelerationStructurePtr		= topLevelAccelerationStructure.get();
1052 	VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet	=
1053 	{
1054 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
1055 		DE_NULL,															//  const void*							pNext;
1056 		1u,																	//  deUint32							accelerationStructureCount;
1057 		topLevelAccelerationStructurePtr->getPtr(),							//  const VkAccelerationStructureKHR*	pAccelerationStructures;
1058 	};
1059 
1060 	DescriptorSetUpdateBuilder()
1061 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
1062 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1063 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
1064 		.update(vkd, device);
1065 
1066 	vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
1067 
1068 	vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *rtPipeline);
1069 
1070 	deUint32							shaderGroupHandleSize				= getShaderGroupHandleSize(vki, physicalDevice);
1071 	VkStridedDeviceAddressRegionKHR		raygenShaderBindingTableRegion		= raygenShaderBindingTable.get() != DE_NULL		? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize)		: makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1072 	VkStridedDeviceAddressRegionKHR		hitShaderBindingTableRegion			= hitShaderBindingTable.get() != DE_NULL		? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize)			: makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1073 	VkStridedDeviceAddressRegionKHR		missShaderBindingTableRegion		= missShaderBindingTable.get() != DE_NULL		? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize)		: makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1074 	VkStridedDeviceAddressRegionKHR		callableShaderBindingTableRegion	= callableShaderBindingTable.get() != DE_NULL	? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize)	: makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1075 
1076 	cmdTraceRays(vkd,
1077 		commandBuffer,
1078 		&raygenShaderBindingTableRegion,
1079 		&missShaderBindingTableRegion,
1080 		&hitShaderBindingTableRegion,
1081 		&callableShaderBindingTableRegion,
1082 		testParams.width, testParams.height, 1);
1083 }
1084 
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)1085 bool RayTracingConfiguration::verifyImage (BufferWithMemory*					resultBuffer,
1086 										   Context&								context,
1087 										   TestParams&							testParams)
1088 {
1089 	// create result image
1090 	tcu::TextureFormat			imageFormat						= vk::mapVkFormat(getResultImageFormat());
1091 	tcu::ConstPixelBufferAccess	resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr());
1092 
1093 	// create reference image
1094 	std::vector<deUint32>		reference(testParams.width * testParams.height * 2);
1095 	tcu::PixelBufferAccess		referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
1096 
1097 	tcu::UVec4 rqValue0, rqValue1;
1098 	switch (testParams.shaderTestType)
1099 	{
1100 		case STT_GENERATE_INTERSECTION:
1101 			switch (testParams.bottomType)
1102 			{
1103 				case BTT_TRIANGLES:
1104 					rqValue0 = tcu::UVec4(1, 0, 0, 0);
1105 					rqValue1 = tcu::UVec4(1, 0, 0, 0);
1106 					break;
1107 				case BTT_AABBS:
1108 					rqValue0 = tcu::UVec4(2, 0, 0, 0);
1109 					rqValue1 = tcu::UVec4(1, 0, 0, 0);
1110 					break;
1111 				default:
1112 					TCU_THROW(InternalError, "Wrong bottom test type");
1113 			}
1114 			break;
1115 		case STT_SKIP_INTERSECTION:
1116 			switch (testParams.bottomType)
1117 			{
1118 				case BTT_TRIANGLES:
1119 					rqValue0 = tcu::UVec4(0, 0, 0, 0);
1120 					rqValue1 = tcu::UVec4(1, 0, 0, 0);
1121 					break;
1122 				case BTT_AABBS:
1123 					rqValue0 = tcu::UVec4(0, 0, 0, 0);
1124 					rqValue1 = tcu::UVec4(1, 0, 0, 0);
1125 					break;
1126 				default:
1127 					TCU_THROW(InternalError, "Wrong bottom test type");
1128 			}
1129 			break;
1130 		default:
1131 			TCU_THROW(InternalError, "Wrong shader test type");
1132 	}
1133 
1134 	std::array<tcu::UVec4,2> missMissValue, missHitValue, hitMissValue, hitHitValue;
1135 	switch (testParams.shaderSourceType)
1136 	{
1137 		case SST_RAY_GENERATION_SHADER:
1138 			missMissValue	= {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1139 			missHitValue	= {{ rqValue0 , rqValue1 }};
1140 			hitMissValue	= {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1141 			hitHitValue		= {{ rqValue0 , rqValue1 }};
1142 			break;
1143 		case SST_INTERSECTION_SHADER:
1144 			missMissValue	= {{ tcu::UVec4(4, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1145 			missHitValue	= {{ tcu::UVec4(4, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1146 			hitMissValue	= {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1147 			hitHitValue		= {{ rqValue0 , rqValue1 }};
1148 			break;
1149 		case SST_ANY_HIT_SHADER:
1150 			missMissValue	= {{ tcu::UVec4(4, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1151 			missHitValue	= {{ tcu::UVec4(4, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1152 			hitMissValue	= {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1153 			hitHitValue		= {{ rqValue0 , rqValue1 }};
1154 			break;
1155 		case SST_CLOSEST_HIT_SHADER:
1156 			missMissValue	= {{ tcu::UVec4(4, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1157 			missHitValue	= {{ tcu::UVec4(4, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1158 			hitMissValue	= {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1159 			hitHitValue		= {{ rqValue0 , rqValue1 }};
1160 			break;
1161 		case SST_MISS_SHADER:
1162 			missMissValue	= {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1163 			missHitValue	= {{ rqValue0 , rqValue1 }};
1164 			hitMissValue	= {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(3, 0, 0, 0) }};
1165 			hitHitValue		= {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(3, 0, 0, 0) }};
1166 			break;
1167 		case SST_CALLABLE_SHADER:
1168 			missMissValue	= {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1169 			missHitValue	= {{ rqValue0 , rqValue1 }};
1170 			hitMissValue	= {{ tcu::UVec4(0, 0, 0, 0) , tcu::UVec4(0, 0, 0, 0) }};
1171 			hitHitValue		= {{ rqValue0 , rqValue1 }};
1172 			break;
1173 		default:
1174 			TCU_THROW(InternalError, "Wrong shader source type");
1175 	}
1176 
1177 	for (deUint32 y = 0; y < testParams.height / 2; ++y)
1178 	for (deUint32 x = 0; x < testParams.width; ++x)
1179 	{
1180 		referenceAccess.setPixel(hitMissValue[0], x, y, 0);
1181 		referenceAccess.setPixel(hitMissValue[1], x, y, 1);
1182 	}
1183 	for (deUint32 y = testParams.height / 2; y < testParams.height; ++y)
1184 	for (deUint32 x = 0; x < testParams.width; ++x)
1185 	{
1186 		referenceAccess.setPixel(missMissValue[0], x, y, 0);
1187 		referenceAccess.setPixel(missMissValue[1], x, y, 1);
1188 	}
1189 
1190 	for (deUint32 y = 1; y < testParams.height / 2; ++y)
1191 	for (deUint32 x = 1; x < testParams.width - 1; ++x)
1192 	{
1193 		referenceAccess.setPixel(hitHitValue[0], x, y, 0);
1194 		referenceAccess.setPixel(hitHitValue[1], x, y, 1);
1195 	}
1196 
1197 	for (deUint32 y = testParams.height/2; y < testParams.height - 1; ++y)
1198 	for (deUint32 x = 1; x < testParams.width - 1; ++x)
1199 	{
1200 		referenceAccess.setPixel(missHitValue[0], x, y, 0);
1201 		referenceAccess.setPixel(missHitValue[1], x, y, 1);
1202 	}
1203 
1204 	// compare result and reference
1205 	return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
1206 }
1207 
getResultImageFormat()1208 VkFormat RayTracingConfiguration::getResultImageFormat ()
1209 {
1210 	return VK_FORMAT_R32_UINT;
1211 }
1212 
getResultImageFormatSize()1213 size_t RayTracingConfiguration::getResultImageFormatSize ()
1214 {
1215 	return sizeof(deUint32);
1216 }
1217 
getClearValue()1218 VkClearValue RayTracingConfiguration::getClearValue ()
1219 {
1220 	return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
1221 }
1222 
1223 class RayQueryTraversalControlTestCase : public TestCase
1224 {
1225 	public:
1226 							RayQueryTraversalControlTestCase			(tcu::TestContext& context, const char* name, const char* desc, const TestParams data);
1227 							~RayQueryTraversalControlTestCase			(void);
1228 
1229 	virtual void			checkSupport								(Context& context) const;
1230 	virtual	void			initPrograms								(SourceCollections& programCollection) const;
1231 	virtual TestInstance*	createInstance								(Context& context) const;
1232 private:
1233 	TestParams				m_data;
1234 };
1235 
1236 class TraversalControlTestInstance : public TestInstance
1237 {
1238 public:
1239 																	TraversalControlTestInstance	(Context& context, const TestParams& data);
1240 																	~TraversalControlTestInstance	(void);
1241 	tcu::TestStatus													iterate									(void);
1242 
1243 private:
1244 	TestParams														m_data;
1245 };
1246 
RayQueryTraversalControlTestCase(tcu::TestContext & context,const char * name,const char * desc,const TestParams data)1247 RayQueryTraversalControlTestCase::RayQueryTraversalControlTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams data)
1248 	: vkt::TestCase	(context, name, desc)
1249 	, m_data		(data)
1250 {
1251 }
1252 
~RayQueryTraversalControlTestCase(void)1253 RayQueryTraversalControlTestCase::~RayQueryTraversalControlTestCase (void)
1254 {
1255 }
1256 
checkSupport(Context & context) const1257 void RayQueryTraversalControlTestCase::checkSupport (Context& context) const
1258 {
1259 	context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
1260 	context.requireDeviceFunctionality("VK_KHR_ray_query");
1261 
1262 	const VkPhysicalDeviceRayQueryFeaturesKHR&	rayQueryFeaturesKHR								= context.getRayQueryFeatures();
1263 	if (rayQueryFeaturesKHR.rayQuery == DE_FALSE)
1264 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");
1265 
1266 	const VkPhysicalDeviceAccelerationStructureFeaturesKHR&	accelerationStructureFeaturesKHR	= context.getAccelerationStructureFeatures();
1267 	if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
1268 		TCU_THROW(TestError, "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
1269 
1270 	const VkPhysicalDeviceFeatures2&			features2										= context.getDeviceFeatures2();
1271 
1272 	if ((m_data.shaderSourceType == SST_TESSELATION_CONTROL_SHADER ||
1273 		 m_data.shaderSourceType == SST_TESSELATION_EVALUATION_SHADER) &&
1274 		features2.features.tessellationShader == DE_FALSE )
1275 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.tessellationShader");
1276 
1277 	if (m_data.shaderSourceType == SST_GEOMETRY_SHADER &&
1278 		features2.features.geometryShader == DE_FALSE )
1279 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.geometryShader");
1280 
1281 	switch (m_data.shaderSourceType)
1282 	{
1283 	case SST_VERTEX_SHADER:
1284 	case SST_TESSELATION_CONTROL_SHADER:
1285 	case SST_TESSELATION_EVALUATION_SHADER:
1286 	case SST_GEOMETRY_SHADER:
1287 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
1288 		break;
1289 	default:
1290 		break;
1291 	}
1292 
1293 	if (m_data.shaderSourceType == SST_RAY_GENERATION_SHADER ||
1294 		m_data.shaderSourceType == SST_INTERSECTION_SHADER ||
1295 		m_data.shaderSourceType == SST_ANY_HIT_SHADER ||
1296 		m_data.shaderSourceType == SST_CLOSEST_HIT_SHADER ||
1297 		m_data.shaderSourceType == SST_MISS_SHADER ||
1298 		m_data.shaderSourceType == SST_CALLABLE_SHADER)
1299 	{
1300 		context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1301 
1302 		const VkPhysicalDeviceRayTracingPipelineFeaturesKHR&	rayTracingPipelineFeaturesKHR	= context.getRayTracingPipelineFeatures();
1303 
1304 		if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE)
1305 			TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1306 	}
1307 }
1308 
initPrograms(SourceCollections & programCollection) const1309 void RayQueryTraversalControlTestCase::initPrograms (SourceCollections& programCollection) const
1310 {
1311 	const vk::ShaderBuildOptions	buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1312 
1313 	// create parts of programs responsible for test execution
1314 	std::vector<std::vector<std::string>> rayQueryTest(2);
1315 	std::vector<std::vector<std::string>> rayQueryTestName(2);
1316 	{
1317 		// STT_GENERATE_INTERSECTION for triangles
1318 		std::stringstream css;
1319 		css <<
1320 			"  float tmin     = 0.0;\n"
1321 			"  float tmax     = 1.0;\n"
1322 			"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1323 			"  rayQueryEXT rq;\n"
1324 			"  rayQueryInitializeEXT(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);\n"
1325 			"  if(rayQueryProceedEXT(rq))\n"
1326 			"  {\n"
1327 			"    if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT)\n"
1328 			"    {\n"
1329 			"      hitValue.y=1;\n"
1330 			"      rayQueryConfirmIntersectionEXT(rq);\n"
1331 			"      rayQueryProceedEXT(rq);\n"
1332 			"      hitValue.x = rayQueryGetIntersectionTypeEXT(rq, true);\n"
1333 			"    }\n"
1334 			"  }\n";
1335 		rayQueryTest[BTT_TRIANGLES].push_back(css.str());
1336 		rayQueryTestName[BTT_TRIANGLES].push_back("rq_gen_triangle");
1337 	}
1338 	{
1339 		// STT_GENERATE_INTERSECTION for AABBs
1340 		std::stringstream css;
1341 		css <<
1342 			"  float tmin     = 0.0;\n"
1343 			"  float tmax     = 1.0;\n"
1344 			"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1345 			"  rayQueryEXT rq;\n"
1346 			"  rayQueryInitializeEXT(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);\n"
1347 			"  if(rayQueryProceedEXT(rq))\n"
1348 			"  {\n"
1349 			"    if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionAABBEXT)\n"
1350 			"    {\n"
1351 			"      hitValue.y=1;\n"
1352 			"      rayQueryGenerateIntersectionEXT(rq, 0.5);\n"
1353 			"      rayQueryProceedEXT(rq);\n"
1354 			"      hitValue.x = rayQueryGetIntersectionTypeEXT(rq, true);\n"
1355 			"    }\n"
1356 			"  }\n";
1357 		rayQueryTest[BTT_AABBS].push_back(css.str());
1358 		rayQueryTestName[BTT_AABBS].push_back("rq_gen_aabb");
1359 	}
1360 	{
1361 		// STT_SKIP_INTERSECTION for triangles
1362 		std::stringstream css;
1363 		css <<
1364 			"  float tmin     = 0.0;\n"
1365 			"  float tmax     = 1.0;\n"
1366 			"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1367 			"  rayQueryEXT rq;\n"
1368 			"  rayQueryInitializeEXT(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);\n"
1369 			"  if(rayQueryProceedEXT(rq))\n"
1370 			"  {\n"
1371 			"    if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT)\n"
1372 			"    {\n"
1373 			"      hitValue.y=1;\n"
1374 			"      rayQueryProceedEXT(rq);\n"
1375 			"      hitValue.x = rayQueryGetIntersectionTypeEXT(rq, true);\n"
1376 			"    }\n"
1377 			"  }\n";
1378 		rayQueryTest[BTT_TRIANGLES].push_back(css.str());
1379 		rayQueryTestName[BTT_TRIANGLES].push_back("rq_skip_triangle");
1380 	}
1381 	{
1382 		// STT_SKIP_INTERSECTION for AABBs
1383 		std::stringstream css;
1384 		css <<
1385 			"  float tmin     = 0.0;\n"
1386 			"  float tmax     = 1.0;\n"
1387 			"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1388 			"  rayQueryEXT rq;\n"
1389 			"  rayQueryInitializeEXT(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);\n"
1390 			"  if(rayQueryProceedEXT(rq))\n"
1391 			"  {\n"
1392 			"    if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionAABBEXT)\n"
1393 			"    {\n"
1394 			"      hitValue.y=1;\n"
1395 			"      rayQueryProceedEXT(rq);\n"
1396 			"      hitValue.x = rayQueryGetIntersectionTypeEXT(rq, true);\n"
1397 			"    }\n"
1398 			"  }\n";
1399 		rayQueryTest[BTT_AABBS].push_back(css.str());
1400 		rayQueryTestName[BTT_AABBS].push_back("rq_skip_aabb");
1401 	}
1402 
1403 	// create all programs
1404 	if (m_data.shaderSourcePipeline == SSP_GRAPHICS_PIPELINE)
1405 	{
1406 		{
1407 			std::stringstream css;
1408 			css <<
1409 				"#version 460 core\n"
1410 				"layout (location = 0) in vec3 position;\n"
1411 				"out gl_PerVertex\n"
1412 				"{\n"
1413 				"  vec4 gl_Position;\n"
1414 				"};\n"
1415 				"void main()\n"
1416 				"{\n"
1417 				"  gl_Position = vec4(position, 1.0);\n"
1418 				"}\n";
1419 			programCollection.glslSources.add("vert") << glu::VertexSource(css.str()) << buildOptions;
1420 		}
1421 
1422 		{
1423 			std::stringstream css;
1424 			css <<
1425 				"#version 460 core\n"
1426 				"#extension GL_EXT_ray_query : require\n"
1427 				"layout (location = 0) in vec3 position;\n"
1428 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1429 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1430 				"void main()\n"
1431 				"{\n"
1432 				"  vec3  origin   = vec3(float(position.x) + 0.5, float(position.y) + 0.5, 0.5);\n"
1433 				"  uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1434 				rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1435 				"  imageStore(result, ivec3(gl_VertexIndex, 0, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1436 				"  imageStore(result, ivec3(gl_VertexIndex, 0, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1437 				"  gl_Position = vec4(position,1);\n"
1438 				"}\n";
1439 			std::stringstream cssName;
1440 			cssName << "vert_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1441 
1442 			programCollection.glslSources.add(cssName.str()) << glu::VertexSource(css.str()) << buildOptions;
1443 		}
1444 
1445 		{
1446 			std::stringstream css;
1447 			css <<
1448 				"#version 460 core\n"
1449 				"#extension GL_EXT_tessellation_shader : require\n"
1450 				"in gl_PerVertex {\n"
1451 				"  vec4  gl_Position;\n"
1452 				"} gl_in[];\n"
1453 				"layout(vertices = 3) out;\n"
1454 				"void main (void)\n"
1455 				"{\n"
1456 				"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1457 				"  gl_TessLevelInner[0] = 1;\n"
1458 				"  gl_TessLevelOuter[0] = 1;\n"
1459 				"  gl_TessLevelOuter[1] = 1;\n"
1460 				"  gl_TessLevelOuter[2] = 1;\n"
1461 				"}\n";
1462 			programCollection.glslSources.add("tesc") << glu::TessellationControlSource(css.str()) << buildOptions;
1463 		}
1464 
1465 		{
1466 			std::stringstream css;
1467 			css <<
1468 				"#version 460 core\n"
1469 				"#extension GL_EXT_tessellation_shader : require\n"
1470 				"#extension GL_EXT_ray_query : require\n"
1471 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1472 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1473 				"in gl_PerVertex {\n"
1474 				"  vec4  gl_Position;\n"
1475 				"} gl_in[];\n"
1476 				"layout(vertices = 3) out;\n"
1477 				"void main (void)\n"
1478 				"{\n"
1479 				"  vec3  origin   = vec3(gl_in[gl_InvocationID].gl_Position.x + 0.5, gl_in[gl_InvocationID].gl_Position.y + 0.5, 0.5);\n"
1480 				"  uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1481 				rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1482 				"  imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1483 				"  imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1484 				"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1485 				"  gl_TessLevelInner[0] = 1;\n"
1486 				"  gl_TessLevelOuter[0] = 1;\n"
1487 				"  gl_TessLevelOuter[1] = 1;\n"
1488 				"  gl_TessLevelOuter[2] = 1;\n"
1489 				"}\n";
1490 			std::stringstream cssName;
1491 			cssName << "tesc_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1492 
1493 			programCollection.glslSources.add(cssName.str()) << glu::TessellationControlSource(css.str()) << buildOptions;
1494 		}
1495 
1496 		{
1497 			std::stringstream css;
1498 			css <<
1499 				"#version 460 core\n"
1500 				"#extension GL_EXT_tessellation_shader : require\n"
1501 				"#extension GL_EXT_ray_query : require\n"
1502 				"layout(triangles, equal_spacing, ccw) in;\n"
1503 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1504 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1505 				"void main (void)\n"
1506 				"{\n"
1507 				"  for (int i = 0; i < 3; ++i)\n"
1508 				"  {\n"
1509 				"    vec3  origin   = vec3(gl_in[i].gl_Position.x + 0.5, gl_in[i].gl_Position.y + 0.5, 0.5);\n"
1510 				"    uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1511 				rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1512 				"    imageStore(result, ivec3(gl_PrimitiveID, i, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1513 				"    imageStore(result, ivec3(gl_PrimitiveID, i, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1514 				"  }\n"
1515 				"  gl_Position = gl_in[0].gl_Position;\n"
1516 				"}\n";
1517 			std::stringstream cssName;
1518 			cssName << "tese_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1519 
1520 			programCollection.glslSources.add(cssName.str()) << glu::TessellationEvaluationSource(css.str()) << buildOptions;
1521 		}
1522 
1523 		{
1524 			std::stringstream css;
1525 			css <<
1526 				"#version 460 core\n"
1527 				"#extension GL_EXT_tessellation_shader : require\n"
1528 				"layout(triangles, equal_spacing, ccw) in;\n"
1529 				"void main (void)\n"
1530 				"{\n"
1531 				"  gl_Position = gl_in[0].gl_Position;\n"
1532 				"}\n";
1533 
1534 			programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(css.str()) << buildOptions;
1535 		}
1536 
1537 		{
1538 			std::stringstream css;
1539 			css <<
1540 				"#version 460 core\n"
1541 				"#extension GL_EXT_ray_query : require\n"
1542 				"layout(triangles) in;\n"
1543 				"layout (triangle_strip, max_vertices = 4) out;\n"
1544 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1545 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1546 				"\n"
1547 				"in gl_PerVertex {\n"
1548 				"  vec4  gl_Position;\n"
1549 				"} gl_in[];\n"
1550 				"out gl_PerVertex {\n"
1551 				"  vec4 gl_Position;\n"
1552 				"};\n"
1553 				"void main (void)\n"
1554 				"{\n"
1555 				"  for (int i = 0; i < gl_in.length(); ++i)\n"
1556 				"  {\n"
1557 				"    vec3  origin   = vec3(gl_in[i].gl_Position.x + 0.5, gl_in[i].gl_Position.y + 0.5, 0.5);\n"
1558 				"    uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1559 				rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1560 				"    imageStore(result, ivec3(gl_PrimitiveIDIn, i, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1561 				"    imageStore(result, ivec3(gl_PrimitiveIDIn, i, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1562 				"    gl_Position      = gl_in[i].gl_Position;\n"
1563 				"    EmitVertex();\n"
1564 				"  }\n"
1565 				"  EndPrimitive();\n"
1566 				"}\n";
1567 			std::stringstream cssName;
1568 			cssName << "geom_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1569 
1570 			programCollection.glslSources.add(cssName.str()) << glu::GeometrySource(css.str()) << buildOptions;
1571 		}
1572 
1573 		{
1574 			std::stringstream css;
1575 			css <<
1576 				"#version 460 core\n"
1577 				"#extension GL_EXT_ray_query : require\n"
1578 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1579 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1580 				"void main()\n"
1581 				"{\n"
1582 				"  vec3  origin   = vec3(gl_FragCoord.x, gl_FragCoord.y, 0.5);\n"
1583 				"  uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1584 				rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1585 				"  imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 0), uvec4(hitValue.x, 0, 0, 0));\n"
1586 				"  imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 1), uvec4(hitValue.y, 0, 0, 0));\n"
1587 				"}\n";
1588 			std::stringstream cssName;
1589 			cssName << "frag_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1590 
1591 			programCollection.glslSources.add(cssName.str()) << glu::FragmentSource(css.str()) << buildOptions;
1592 		}
1593 	}
1594 	else if (m_data.shaderSourcePipeline == SSP_COMPUTE_PIPELINE)
1595 	{
1596 		{
1597 			std::stringstream css;
1598 			css <<
1599 				"#version 460 core\n"
1600 				"#extension GL_EXT_ray_query : require\n"
1601 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1602 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1603 				"void main()\n"
1604 				"{\n"
1605 				"  vec3  origin   = vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + 0.5, 0.5);\n"
1606 				"  uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1607 				rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1608 				"  imageStore(result, ivec3(gl_GlobalInvocationID.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1609 				"  imageStore(result, ivec3(gl_GlobalInvocationID.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1610 				"}\n";
1611 			std::stringstream cssName;
1612 			cssName << "comp_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1613 
1614 			programCollection.glslSources.add(cssName.str()) << glu::ComputeSource(css.str()) << buildOptions;
1615 		}
1616 	}
1617 	else if (m_data.shaderSourcePipeline == SSP_RAY_TRACING_PIPELINE)
1618 	{
1619 		{
1620 			std::stringstream css;
1621 			css <<
1622 				"#version 460 core\n"
1623 				"#extension GL_EXT_ray_tracing : require\n"
1624 				"layout(location = 0) rayPayloadEXT uvec4 hitValue;\n"
1625 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1626 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1627 				"void main()\n"
1628 				"{\n"
1629 				"  float tmin     = 0.0;\n"
1630 				"  float tmax     = 1.0;\n"
1631 				"  vec3  origin   = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1632 				"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1633 				"  hitValue       = uvec4(0,0,0,0);\n"
1634 				"  traceRayEXT(topLevelAS, 0, 0xFF, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
1635 				"  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1636 				"  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1637 				"}\n";
1638 			programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1639 		}
1640 
1641 		{
1642 			std::stringstream css;
1643 			css <<
1644 				"#version 460 core\n"
1645 				"#extension GL_EXT_ray_tracing : require\n"
1646 				"#extension GL_EXT_ray_query : require\n"
1647 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1648 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1649 				"layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1650 				"void main()\n"
1651 				"{\n"
1652 				"  vec3  origin    = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1653 				"  uvec4  hitValue = uvec4(0,0,0,0);\n" <<
1654 				rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1655 				"  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1656 				"  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1657 				"}\n";
1658 			std::stringstream cssName;
1659 			cssName << "rgen_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1660 
1661 			programCollection.glslSources.add(cssName.str()) << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1662 		}
1663 
1664 		{
1665 			std::stringstream css;
1666 			css <<
1667 				"#version 460 core\n"
1668 				"#extension GL_EXT_ray_tracing : require\n"
1669 				"struct CallValue\n{\n"
1670 				"  vec3  origin;\n"
1671 				"  uvec4 hitValue;\n"
1672 				"};\n"
1673 				"layout(location = 0) callableDataEXT CallValue param;\n"
1674 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1675 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1676 				"void main()\n"
1677 				"{\n"
1678 				"  param.origin   = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1679 				"  param.hitValue = uvec4(0, 0, 0, 0);\n"
1680 				"  executeCallableEXT(0, 0);\n"
1681 				"  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(param.hitValue.x, 0, 0, 0));\n"
1682 				"  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(param.hitValue.y, 0, 0, 0));\n"
1683 				"}\n";
1684 			programCollection.glslSources.add("rgen_call") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1685 		}
1686 
1687 		{
1688 			std::stringstream css;
1689 			css <<
1690 				"#version 460 core\n"
1691 				"#extension GL_EXT_ray_tracing : require\n"
1692 				"hitAttributeEXT uvec4 hitValue;\n"
1693 				"void main()\n"
1694 				"{\n"
1695 				"  reportIntersectionEXT(0.5f, 0);\n"
1696 				"}\n";
1697 
1698 			programCollection.glslSources.add("isect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1699 		}
1700 
1701 		{
1702 			std::stringstream css;
1703 			css <<
1704 				"#version 460 core\n"
1705 				"#extension GL_EXT_ray_tracing : require\n"
1706 				"#extension GL_EXT_ray_query : require\n"
1707 				"hitAttributeEXT uvec4 hitValue;\n"
1708 				"layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1709 				"void main()\n"
1710 				"{\n"
1711 				"  vec3 origin = gl_WorldRayOriginEXT;\n"
1712 				"  hitValue    = uvec4(0,0,0,0);\n" <<
1713 				rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1714 				"  reportIntersectionEXT(0.5f, 0);\n"
1715 				"}\n";
1716 			std::stringstream cssName;
1717 			cssName << "isect_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1718 
1719 			programCollection.glslSources.add(cssName.str()) << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1720 		}
1721 
1722 		{
1723 			std::stringstream css;
1724 			css <<
1725 				"#version 460 core\n"
1726 				"#extension GL_EXT_ray_tracing : require\n"
1727 				"#extension GL_EXT_ray_query : require\n"
1728 				"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1729 				"layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1730 				"void main()\n"
1731 				"{\n"
1732 				"  vec3 origin = gl_WorldRayOriginEXT;\n" <<
1733 				rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1734 				"}\n";
1735 			std::stringstream cssName;
1736 			cssName << "ahit_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1737 
1738 			programCollection.glslSources.add(cssName.str()) << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1739 		}
1740 
1741 		{
1742 			std::stringstream css;
1743 			css <<
1744 				"#version 460 core\n"
1745 				"#extension GL_EXT_ray_tracing : require\n"
1746 				"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1747 				"void main()\n"
1748 				"{\n"
1749 				"  hitValue.y = 3;\n"
1750 				"}\n";
1751 
1752 			programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1753 		}
1754 
1755 		{
1756 			std::stringstream css;
1757 			css <<
1758 				"#version 460 core\n"
1759 				"#extension GL_EXT_ray_tracing : require\n"
1760 				"#extension GL_EXT_ray_query : require\n"
1761 				"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1762 				"layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1763 				"void main()\n"
1764 				"{\n"
1765 				"  vec3 origin = gl_WorldRayOriginEXT;\n" <<
1766 				rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1767 				"}\n";
1768 			std::stringstream cssName;
1769 			cssName << "chit_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1770 
1771 			programCollection.glslSources.add(cssName.str()) << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1772 		}
1773 
1774 		{
1775 			std::stringstream css;
1776 			css <<
1777 				"#version 460 core\n"
1778 				"#extension GL_EXT_ray_tracing : require\n"
1779 				"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1780 				"hitAttributeEXT uvec4 hitAttrib;\n"
1781 				"void main()\n"
1782 				"{\n"
1783 				"  hitValue = hitAttrib;\n"
1784 				"}\n";
1785 
1786 			programCollection.glslSources.add("chit_isect") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1787 		}
1788 
1789 		{
1790 			std::stringstream css;
1791 			css <<
1792 				"#version 460 core\n"
1793 				"#extension GL_EXT_ray_tracing : require\n"
1794 				"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1795 				"void main()\n"
1796 				"{\n"
1797 				"  hitValue.x = 4;\n"
1798 				"}\n";
1799 
1800 			programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1801 		}
1802 
1803 		{
1804 			std::stringstream css;
1805 			css <<
1806 				"#version 460 core\n"
1807 				"#extension GL_EXT_ray_tracing : require\n"
1808 				"#extension GL_EXT_ray_query : require\n"
1809 				"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
1810 				"layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1811 				"void main()\n"
1812 				"{\n"
1813 				"  vec3 origin = gl_WorldRayOriginEXT;\n" <<
1814 				rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1815 				"}\n";
1816 			std::stringstream cssName;
1817 			cssName << "miss_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1818 
1819 			programCollection.glslSources.add(cssName.str()) << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1820 		}
1821 
1822 		{
1823 			std::stringstream css;
1824 			css <<
1825 				"#version 460 core\n"
1826 				"#extension GL_EXT_ray_tracing : require\n"
1827 				"#extension GL_EXT_ray_query : require\n"
1828 				"struct CallValue\n{\n"
1829 				"  vec3  origin;\n"
1830 				"  uvec4 hitValue;\n"
1831 				"};\n"
1832 				"layout(location = 0) callableDataInEXT CallValue result;\n"
1833 				"layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1834 				"void main()\n"
1835 				"{\n"
1836 				"  vec3 origin    = result.origin;\n"
1837 				"  uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1838 				rayQueryTest[m_data.bottomType][m_data.shaderTestType] <<
1839 				"  result.hitValue = hitValue;\n"
1840 				"}\n";
1841 			std::stringstream cssName;
1842 			cssName << "call_" << rayQueryTestName[m_data.bottomType][m_data.shaderTestType];
1843 
1844 			programCollection.glslSources.add(cssName.str()) << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
1845 		}
1846 	}
1847 }
1848 
createInstance(Context & context) const1849 TestInstance* RayQueryTraversalControlTestCase::createInstance (Context& context) const
1850 {
1851 	return new TraversalControlTestInstance(context, m_data);
1852 }
1853 
TraversalControlTestInstance(Context & context,const TestParams & data)1854 TraversalControlTestInstance::TraversalControlTestInstance (Context& context, const TestParams& data)
1855 	: vkt::TestInstance		(context)
1856 	, m_data				(data)
1857 {
1858 }
1859 
~TraversalControlTestInstance(void)1860 TraversalControlTestInstance::~TraversalControlTestInstance (void)
1861 {
1862 }
1863 
iterate(void)1864 tcu::TestStatus TraversalControlTestInstance::iterate (void)
1865 {
1866 	de::SharedPtr<TestConfiguration> testConfiguration;
1867 
1868 	switch (m_data.shaderSourcePipeline)
1869 	{
1870 	case SSP_GRAPHICS_PIPELINE:
1871 		testConfiguration = de::SharedPtr<TestConfiguration>(new GraphicsConfiguration());
1872 		break;
1873 	case SSP_COMPUTE_PIPELINE:
1874 		testConfiguration = de::SharedPtr<TestConfiguration>(new ComputeConfiguration());
1875 		break;
1876 	case SSP_RAY_TRACING_PIPELINE:
1877 		testConfiguration = de::SharedPtr<TestConfiguration>(new RayTracingConfiguration());
1878 		break;
1879 	default:
1880 		TCU_THROW(InternalError, "Wrong shader source pipeline");
1881 	}
1882 
1883 	testConfiguration->initConfiguration(m_context, m_data);
1884 
1885 	const DeviceInterface&				vkd									= m_context.getDeviceInterface();
1886 	const VkDevice						device								= m_context.getDevice();
1887 	const VkQueue						queue								= m_context.getUniversalQueue();
1888 	Allocator&							allocator							= m_context.getDefaultAllocator();
1889 	const deUint32						queueFamilyIndex					= m_context.getUniversalQueueFamilyIndex();
1890 
1891 	const VkFormat						imageFormat							= testConfiguration->getResultImageFormat();
1892 	const VkImageCreateInfo				imageCreateInfo						= makeImageCreateInfo(m_data.width, m_data.height, 2, imageFormat);
1893 	const VkImageSubresourceRange		imageSubresourceRange				= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1894 	const de::MovePtr<ImageWithMemory>	image								= de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1895 	const Move<VkImageView>				imageView							= makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, imageFormat, imageSubresourceRange);
1896 
1897 	const VkBufferCreateInfo			resultBufferCreateInfo				= makeBufferCreateInfo(m_data.width * m_data.height * 2 * testConfiguration->getResultImageFormatSize(), VK_BUFFER_USAGE_TRANSFER_DST_BIT);
1898 	const VkImageSubresourceLayers		resultBufferImageSubresourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1899 	const VkBufferImageCopy				resultBufferImageRegion				= makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, 2), resultBufferImageSubresourceLayers);
1900 	de::MovePtr<BufferWithMemory>		resultBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
1901 
1902 	const VkDescriptorImageInfo			resultImageInfo						= makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
1903 
1904 	const Move<VkCommandPool>			cmdPool								= createCommandPool(vkd, device, 0, queueFamilyIndex);
1905 	const Move<VkCommandBuffer>			cmdBuffer							= allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1906 
1907 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >	rayQueryBottomLevelAccelerationStructures;
1908 	de::MovePtr<TopLevelAccelerationStructure>						rayQueryTopLevelAccelerationStructure;
1909 
1910 	beginCommandBuffer(vkd, *cmdBuffer, 0u);
1911 	{
1912 		const VkImageMemoryBarrier			preImageBarrier					= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
1913 																					VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1914 																					**image, imageSubresourceRange);
1915 		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
1916 
1917 		const VkClearValue					clearValue						= testConfiguration->getClearValue();
1918 		vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
1919 
1920 		const VkImageMemoryBarrier			postImageBarrier				= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
1921 																				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1922 																				**image, imageSubresourceRange);
1923 		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
1924 
1925 		// build acceleration structures for ray query
1926 		{
1927 			de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1928 			bottomLevelAccelerationStructure->setGeometryCount(1);
1929 
1930 			de::SharedPtr<RaytracedGeometryBase> geometry;
1931 			if (m_data.bottomType == BTT_TRIANGLES)
1932 			{
1933 				tcu::Vec3 v0(1.0f, float(m_data.height) - 1.0f, 0.0f);
1934 				tcu::Vec3 v1(1.0f, 1.0f, 0.0f);
1935 				tcu::Vec3 v2(float(m_data.width) - 1.0f, float(m_data.height) - 1.0f, 0.0f);
1936 				tcu::Vec3 v3(float(m_data.width) - 1.0f, 1.0f, 0.0f);
1937 
1938 				geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1939 				geometry->addVertex(v0);
1940 				geometry->addVertex(v1);
1941 				geometry->addVertex(v2);
1942 				geometry->addVertex(v2);
1943 				geometry->addVertex(v1);
1944 				geometry->addVertex(v3);
1945 			}
1946 			else // testParams.bottomType != BTT_TRIANGLES
1947 			{
1948 				tcu::Vec3 v0(1.0f, 1.0f, -0.1f);
1949 				tcu::Vec3 v1(float(m_data.width) - 1.0f, float(m_data.height) - 1.0f, 0.1f);
1950 
1951 				geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1952 				geometry->addVertex(v0);
1953 				geometry->addVertex(v1);
1954 			}
1955 			bottomLevelAccelerationStructure->addGeometry(geometry);
1956 			rayQueryBottomLevelAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1957 		}
1958 
1959 		for (auto& blas : rayQueryBottomLevelAccelerationStructures)
1960 			blas->createAndBuild(vkd, device, *cmdBuffer, allocator);
1961 
1962 		rayQueryTopLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1963 		rayQueryTopLevelAccelerationStructure->setInstanceCount(1);
1964 		rayQueryTopLevelAccelerationStructure->addInstance(rayQueryBottomLevelAccelerationStructures[0]);
1965 		rayQueryTopLevelAccelerationStructure->createAndBuild(vkd, device, *cmdBuffer, allocator);
1966 
1967 		const TopLevelAccelerationStructure*			rayQueryTopLevelAccelerationStructurePtr	= rayQueryTopLevelAccelerationStructure.get();
1968 		VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet		=
1969 		{
1970 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
1971 			DE_NULL,															//  const void*							pNext;
1972 			1u,																	//  deUint32							accelerationStructureCount;
1973 			rayQueryTopLevelAccelerationStructurePtr->getPtr(),					//  const VkAccelerationStructureKHR*	pAccelerationStructures;
1974 		};
1975 
1976 		testConfiguration->fillCommandBuffer(m_context, m_data, *cmdBuffer, accelerationStructureWriteDescriptorSet, resultImageInfo);
1977 
1978 		const VkMemoryBarrier							postTestMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
1979 		const VkMemoryBarrier							postCopyMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
1980 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTestMemoryBarrier);
1981 
1982 		vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
1983 
1984 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
1985 	}
1986 	endCommandBuffer(vkd, *cmdBuffer);
1987 
1988 	submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1989 
1990 	invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
1991 
1992 	bool result = testConfiguration->verifyImage(resultBuffer.get(), m_context, m_data);
1993 
1994 	rayQueryTopLevelAccelerationStructure.clear();
1995 	rayQueryBottomLevelAccelerationStructures.clear();
1996 	testConfiguration.clear();
1997 
1998 	if (!result)
1999 		return tcu::TestStatus::fail("Fail");
2000 	return tcu::TestStatus::pass("Pass");
2001 }
2002 
2003 }	// anonymous
2004 
createTraversalControlTests(tcu::TestContext & testCtx)2005 tcu::TestCaseGroup*	createTraversalControlTests(tcu::TestContext& testCtx)
2006 {
2007 	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "traversal_control", "Tests verifying traversal control in RT hit shaders"));
2008 
2009 	struct ShaderSourceTypeData
2010 	{
2011 		ShaderSourceType						shaderSourceType;
2012 		ShaderSourcePipeline					shaderSourcePipeline;
2013 		const char*								name;
2014 	} shaderSourceTypes[] =
2015 	{
2016 		{ SST_VERTEX_SHADER,					SSP_GRAPHICS_PIPELINE,		"vertex_shader"				},
2017 		{ SST_TESSELATION_CONTROL_SHADER,		SSP_GRAPHICS_PIPELINE,		"tess_control_shader"		},
2018 		{ SST_TESSELATION_EVALUATION_SHADER,	SSP_GRAPHICS_PIPELINE,		"tess_evaluation_shader"	},
2019 		{ SST_GEOMETRY_SHADER,					SSP_GRAPHICS_PIPELINE,		"geometry_shader",			},
2020 		{ SST_FRAGMENT_SHADER,					SSP_GRAPHICS_PIPELINE,		"fragment_shader",			},
2021 		{ SST_COMPUTE_SHADER,					SSP_COMPUTE_PIPELINE,		"compute_shader",			},
2022 		{ SST_RAY_GENERATION_SHADER,			SSP_RAY_TRACING_PIPELINE,	"rgen_shader",				},
2023 		{ SST_INTERSECTION_SHADER,				SSP_RAY_TRACING_PIPELINE,	"isect_shader",				},
2024 		{ SST_ANY_HIT_SHADER,					SSP_RAY_TRACING_PIPELINE,	"ahit_shader",				},
2025 		{ SST_CLOSEST_HIT_SHADER,				SSP_RAY_TRACING_PIPELINE,	"chit_shader",				},
2026 		{ SST_MISS_SHADER,						SSP_RAY_TRACING_PIPELINE,	"miss_shader",				},
2027 		{ SST_CALLABLE_SHADER,					SSP_RAY_TRACING_PIPELINE,	"call_shader",				},
2028 	};
2029 
2030 	struct ShaderTestTypeData
2031 	{
2032 		ShaderTestType							shaderTestType;
2033 		const char*								name;
2034 	} shaderTestTypes[] =
2035 	{
2036 		{ STT_GENERATE_INTERSECTION,			"generate_intersection"	},
2037 		{ STT_SKIP_INTERSECTION,				"skip_intersection"		},
2038 	};
2039 
2040 	struct
2041 	{
2042 		BottomTestType							testType;
2043 		const char*								name;
2044 	} bottomTestTypes[] =
2045 	{
2046 		{ BTT_TRIANGLES,						"triangles" },
2047 		{ BTT_AABBS,							"aabbs" },
2048 	};
2049 
2050 	for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
2051 	{
2052 		de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name, ""));
2053 
2054 		for (size_t shaderTestNdx = 0; shaderTestNdx < DE_LENGTH_OF_ARRAY(shaderTestTypes); ++shaderTestNdx)
2055 		{
2056 			de::MovePtr<tcu::TestCaseGroup> testTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderTestTypes[shaderTestNdx].name, ""));
2057 
2058 			for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++testTypeNdx)
2059 			{
2060 				TestParams testParams
2061 				{
2062 					TEST_WIDTH,
2063 					TEST_HEIGHT,
2064 					shaderSourceTypes[shaderSourceNdx].shaderSourceType,
2065 					shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
2066 					shaderTestTypes[shaderTestNdx].shaderTestType,
2067 					bottomTestTypes[testTypeNdx].testType
2068 				};
2069 				testTypeGroup->addChild(new RayQueryTraversalControlTestCase(group->getTestContext(), bottomTestTypes[testTypeNdx].name, "", testParams));
2070 			}
2071 			sourceTypeGroup->addChild(testTypeGroup.release());
2072 		}
2073 		group->addChild(sourceTypeGroup.release());
2074 	}
2075 
2076 	return group.release();
2077 }
2078 
2079 }	// RayQuery
2080 
2081 }	// vkt
2082