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
48namespace vkt
49{
50namespace RayQuery
51{
52namespace
53{
54using namespace vk;
55using namespace vkt;
56
57static 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
64enum ShaderSourcePipeline
65{
66	SSP_GRAPHICS_PIPELINE,
67	SSP_COMPUTE_PIPELINE,
68	SSP_RAY_TRACING_PIPELINE
69};
70
71enum 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
87enum ShaderTestType
88{
89	STT_GENERATE_INTERSECTION		= 0,
90	STT_SKIP_INTERSECTION			= 1,
91};
92
93enum BottomTestType
94{
95	BTT_TRIANGLES,
96	BTT_AABBS
97};
98
99const deUint32			TEST_WIDTH			= 8;
100const deUint32			TEST_HEIGHT			= 8;
101
102struct TestParams;
103
104class TestConfiguration
105{
106public:
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
123TestConfiguration::~TestConfiguration()
124{
125}
126
127struct TestParams
128{
129	deUint32							width;
130	deUint32							height;
131	ShaderSourceType					shaderSourceType;
132	ShaderSourcePipeline				shaderSourcePipeline;
133	ShaderTestType						shaderTestType;
134	BottomTestType						bottomType;
135};
136
137deUint32 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
146deUint32 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
155VkImageCreateInfo 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
179bool 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
210bool 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
231class GraphicsConfiguration : public TestConfiguration
232{
233public:
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;
248protected:
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
262GraphicsConfiguration::~GraphicsConfiguration()
263{
264	shaderModules.clear();
265}
266
267void 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
539void 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
573bool 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
689VkFormat GraphicsConfiguration::getResultImageFormat ()
690{
691	return VK_FORMAT_R32_UINT;
692}
693
694size_t GraphicsConfiguration::getResultImageFormatSize ()
695{
696	return sizeof(deUint32);
697}
698
699VkClearValue GraphicsConfiguration::getClearValue ()
700{
701	return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
702}
703
704class ComputeConfiguration : public TestConfiguration
705{
706public:
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;
721protected:
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
730ComputeConfiguration::~ComputeConfiguration()
731{
732}
733
734void 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
782void 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
803bool 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
874VkFormat ComputeConfiguration::getResultImageFormat ()
875{
876	return VK_FORMAT_R32_UINT;
877}
878
879size_t ComputeConfiguration::getResultImageFormatSize ()
880{
881	return sizeof(deUint32);
882}
883
884VkClearValue ComputeConfiguration::getClearValue ()
885{
886	return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
887}
888
889class RayTracingConfiguration : public TestConfiguration
890{
891public:
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;
906protected:
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
924RayTracingConfiguration::~RayTracingConfiguration()
925{
926}
927
928void 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
998void 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
1085bool 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
1208VkFormat RayTracingConfiguration::getResultImageFormat ()
1209{
1210	return VK_FORMAT_R32_UINT;
1211}
1212
1213size_t RayTracingConfiguration::getResultImageFormatSize ()
1214{
1215	return sizeof(deUint32);
1216}
1217
1218VkClearValue RayTracingConfiguration::getClearValue ()
1219{
1220	return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
1221}
1222
1223class RayQueryTraversalControlTestCase : public TestCase
1224{
1225	public:
1226							RayQueryTraversalControlTestCase			(tcu::TestContext& context, const char* name, 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;
1232private:
1233	TestParams				m_data;
1234};
1235
1236class TraversalControlTestInstance : public TestInstance
1237{
1238public:
1239																	TraversalControlTestInstance	(Context& context, const TestParams& data);
1240																	~TraversalControlTestInstance	(void);
1241	tcu::TestStatus													iterate									(void);
1242
1243private:
1244	TestParams														m_data;
1245};
1246
1247RayQueryTraversalControlTestCase::RayQueryTraversalControlTestCase (tcu::TestContext& context, const char* name, const TestParams data)
1248	: vkt::TestCase	(context, name)
1249	, m_data		(data)
1250{
1251}
1252
1253RayQueryTraversalControlTestCase::~RayQueryTraversalControlTestCase (void)
1254{
1255}
1256
1257void 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
1309void 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
1849TestInstance* RayQueryTraversalControlTestCase::createInstance (Context& context) const
1850{
1851	return new TraversalControlTestInstance(context, m_data);
1852}
1853
1854TraversalControlTestInstance::TraversalControlTestInstance (Context& context, const TestParams& data)
1855	: vkt::TestInstance		(context)
1856	, m_data				(data)
1857{
1858}
1859
1860TraversalControlTestInstance::~TraversalControlTestInstance (void)
1861{
1862}
1863
1864tcu::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
2005tcu::TestCaseGroup*	createTraversalControlTests(tcu::TestContext& testCtx)
2006{
2007	// Tests verifying traversal control in RT hit shaders
2008	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "traversal_control"));
2009
2010	struct ShaderSourceTypeData
2011	{
2012		ShaderSourceType						shaderSourceType;
2013		ShaderSourcePipeline					shaderSourcePipeline;
2014		const char*								name;
2015	} shaderSourceTypes[] =
2016	{
2017		{ SST_VERTEX_SHADER,					SSP_GRAPHICS_PIPELINE,		"vertex_shader"				},
2018		{ SST_TESSELATION_CONTROL_SHADER,		SSP_GRAPHICS_PIPELINE,		"tess_control_shader"		},
2019		{ SST_TESSELATION_EVALUATION_SHADER,	SSP_GRAPHICS_PIPELINE,		"tess_evaluation_shader"	},
2020		{ SST_GEOMETRY_SHADER,					SSP_GRAPHICS_PIPELINE,		"geometry_shader",			},
2021		{ SST_FRAGMENT_SHADER,					SSP_GRAPHICS_PIPELINE,		"fragment_shader",			},
2022		{ SST_COMPUTE_SHADER,					SSP_COMPUTE_PIPELINE,		"compute_shader",			},
2023		{ SST_RAY_GENERATION_SHADER,			SSP_RAY_TRACING_PIPELINE,	"rgen_shader",				},
2024		{ SST_INTERSECTION_SHADER,				SSP_RAY_TRACING_PIPELINE,	"isect_shader",				},
2025		{ SST_ANY_HIT_SHADER,					SSP_RAY_TRACING_PIPELINE,	"ahit_shader",				},
2026		{ SST_CLOSEST_HIT_SHADER,				SSP_RAY_TRACING_PIPELINE,	"chit_shader",				},
2027		{ SST_MISS_SHADER,						SSP_RAY_TRACING_PIPELINE,	"miss_shader",				},
2028		{ SST_CALLABLE_SHADER,					SSP_RAY_TRACING_PIPELINE,	"call_shader",				},
2029	};
2030
2031	struct ShaderTestTypeData
2032	{
2033		ShaderTestType							shaderTestType;
2034		const char*								name;
2035	} shaderTestTypes[] =
2036	{
2037		{ STT_GENERATE_INTERSECTION,			"generate_intersection"	},
2038		{ STT_SKIP_INTERSECTION,				"skip_intersection"		},
2039	};
2040
2041	struct
2042	{
2043		BottomTestType							testType;
2044		const char*								name;
2045	} bottomTestTypes[] =
2046	{
2047		{ BTT_TRIANGLES,						"triangles" },
2048		{ BTT_AABBS,							"aabbs" },
2049	};
2050
2051	for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
2052	{
2053		de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name));
2054
2055		for (size_t shaderTestNdx = 0; shaderTestNdx < DE_LENGTH_OF_ARRAY(shaderTestTypes); ++shaderTestNdx)
2056		{
2057			de::MovePtr<tcu::TestCaseGroup> testTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderTestTypes[shaderTestNdx].name));
2058
2059			for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++testTypeNdx)
2060			{
2061				TestParams testParams
2062				{
2063					TEST_WIDTH,
2064					TEST_HEIGHT,
2065					shaderSourceTypes[shaderSourceNdx].shaderSourceType,
2066					shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
2067					shaderTestTypes[shaderTestNdx].shaderTestType,
2068					bottomTestTypes[testTypeNdx].testType
2069				};
2070				testTypeGroup->addChild(new RayQueryTraversalControlTestCase(group->getTestContext(), bottomTestTypes[testTypeNdx].name, testParams));
2071			}
2072			sourceTypeGroup->addChild(testTypeGroup.release());
2073		}
2074		group->addChild(sourceTypeGroup.release());
2075	}
2076
2077	return group.release();
2078}
2079
2080}	// RayQuery
2081
2082}	// vkt
2083