• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2020 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *	  http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Testing acceleration structures in ray query extension
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktRayQueryAccelerationStructuresTests.hpp"
25 
26 #include <array>
27 #include <set>
28 #include <limits>
29 
30 #include "vkDefs.hpp"
31 #include "deClock.h"
32 #include "vktTestCase.hpp"
33 #include "vktTestGroupUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkObjUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkBarrierUtil.hpp"
38 #include "vkBufferWithMemory.hpp"
39 #include "vkImageWithMemory.hpp"
40 #include "vkTypeUtil.hpp"
41 #include "vkImageUtil.hpp"
42 #include "vkRayTracingUtil.hpp"
43 #include "deRandom.hpp"
44 #include "tcuTexture.hpp"
45 #include "tcuTextureUtil.hpp"
46 #include "tcuTestLog.hpp"
47 #include "tcuImageCompare.hpp"
48 #include "tcuFloat.hpp"
49 
50 namespace vkt
51 {
52 namespace RayQuery
53 {
54 namespace
55 {
56 using namespace vk;
57 using namespace vkt;
58 
59 static const VkFlags	ALL_RAY_TRACING_STAGES	= VK_SHADER_STAGE_RAYGEN_BIT_KHR
60 												| VK_SHADER_STAGE_ANY_HIT_BIT_KHR
61 												| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
62 												| VK_SHADER_STAGE_MISS_BIT_KHR
63 												| VK_SHADER_STAGE_INTERSECTION_BIT_KHR
64 												| VK_SHADER_STAGE_CALLABLE_BIT_KHR;
65 
66 enum ShaderSourcePipeline
67 {
68 	SSP_GRAPHICS_PIPELINE,
69 	SSP_COMPUTE_PIPELINE,
70 	SSP_RAY_TRACING_PIPELINE
71 };
72 
73 enum ShaderSourceType
74 {
75 	SST_VERTEX_SHADER,
76 	SST_TESSELATION_CONTROL_SHADER,
77 	SST_TESSELATION_EVALUATION_SHADER,
78 	SST_GEOMETRY_SHADER,
79 	SST_FRAGMENT_SHADER,
80 	SST_COMPUTE_SHADER,
81 	SST_RAY_GENERATION_SHADER,
82 	SST_INTERSECTION_SHADER,
83 	SST_ANY_HIT_SHADER,
84 	SST_CLOSEST_HIT_SHADER,
85 	SST_MISS_SHADER,
86 	SST_CALLABLE_SHADER,
87 };
88 
89 enum ShaderTestType
90 {
91 	STT_GENERATE_INTERSECTION		= 0,
92 	STT_SKIP_INTERSECTION			= 1,
93 };
94 
95 enum BottomTestType
96 {
97 	BTT_TRIANGLES,
98 	BTT_AABBS
99 };
100 
101 enum TopTestType
102 {
103 	TTT_IDENTICAL_INSTANCES,
104 	TTT_DIFFERENT_INSTANCES
105 };
106 
107 enum OperationTarget
108 {
109 	OT_NONE,
110 	OT_TOP_ACCELERATION,
111 	OT_BOTTOM_ACCELERATION
112 };
113 
114 enum OperationType
115 {
116 	OP_NONE,
117 	OP_COPY,
118 	OP_COMPACT,
119 	OP_SERIALIZE
120 };
121 
122 enum class InstanceCullFlags
123 {
124 	NONE,
125 	CULL_DISABLE,
126 	COUNTERCLOCKWISE,
127 	ALL,
128 };
129 
130 enum class EmptyAccelerationStructureCase
131 {
132 	NOT_EMPTY				= 0,
133 	INACTIVE_TRIANGLES		= 1,
134 	INACTIVE_INSTANCES		= 2,
135 	NO_GEOMETRIES_BOTTOM	= 3,	// geometryCount zero when building.
136 	NO_PRIMITIVES_BOTTOM	= 4,	// primitiveCount zero when building.
137 	NO_PRIMITIVES_TOP		= 5,	// primitiveCount zero when building.
138 };
139 
140 const deUint32			TEST_WIDTH			= 8;
141 const deUint32			TEST_HEIGHT			= 8;
142 
143 struct TestParams;
144 
145 class TestConfiguration
146 {
147 public:
148 	virtual					~TestConfiguration					();
149 	virtual void			initConfiguration					(Context&						context,
150 																 TestParams&					testParams) = 0;
151 	virtual void			fillCommandBuffer					(Context&						context,
152 																 TestParams&					testParams,
153 																 VkCommandBuffer				commandBuffer,
154 																 const VkWriteDescriptorSetAccelerationStructureKHR&	rayQueryAccelerationStructureWriteDescriptorSet,
155 																 const VkDescriptorImageInfo&	resultImageInfo) = 0;
156 	virtual bool			verifyImage							(BufferWithMemory*				resultBuffer,
157 																 Context&						context,
158 																 TestParams&					testParams) = 0;
159 	virtual VkFormat		getResultImageFormat				() = 0;
160 	virtual size_t			getResultImageFormatSize			() = 0;
161 	virtual VkClearValue	getClearValue						() = 0;
162 };
163 
~TestConfiguration()164 TestConfiguration::~TestConfiguration()
165 {
166 }
167 
168 class SceneBuilder
169 {
170 public:
171 	virtual std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	initBottomAccelerationStructures	(Context&							context,
172 																												 TestParams&						testParams) = 0;
173 	virtual de::MovePtr<TopLevelAccelerationStructure>						initTopAccelerationStructure		(Context&							context,
174 																												 TestParams&						testParams,
175 																												 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >&	bottomLevelAccelerationStructures) = 0;
176 };
177 
178 struct TestParams
179 {
180 	ShaderSourceType						shaderSourceType;
181 	ShaderSourcePipeline					shaderSourcePipeline;
182 	vk::VkAccelerationStructureBuildTypeKHR	buildType;		// are we making AS on CPU or GPU
183 	VkFormat								vertexFormat;
184 	bool									padVertices;
185 	VkIndexType								indexType;
186 	BottomTestType							bottomTestType; // what kind of geometry is stored in bottom AS
187 	InstanceCullFlags						cullFlags;		// Flags for instances, if needed.
188 	bool									bottomUsesAOP;	// does bottom AS use arrays, or arrays of pointers
189 	bool									bottomGeneric;	// Bottom created as generic AS type.
190 	TopTestType								topTestType;	// If instances are identical then bottom geometries must have different vertices/aabbs
191 	bool									topUsesAOP;		// does top AS use arrays, or arrays of pointers
192 	bool									topGeneric;		// Top created as generic AS type.
193 	VkBuildAccelerationStructureFlagsKHR	buildFlags;
194 	OperationTarget							operationTarget;
195 	OperationType							operationType;
196 	deUint32								width;
197 	deUint32								height;
198 	deUint32								workerThreadsCount;
199 	EmptyAccelerationStructureCase			emptyASCase;
200 };
201 
getShaderGroupHandleSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)202 deUint32 getShaderGroupHandleSize (const InstanceInterface&	vki,
203 								   const VkPhysicalDevice	physicalDevice)
204 {
205 	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
206 
207 	rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physicalDevice);
208 	return rayTracingPropertiesKHR->getShaderGroupHandleSize();
209 }
210 
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)211 deUint32 getShaderGroupBaseAlignment (const InstanceInterface&	vki,
212 									  const VkPhysicalDevice	physicalDevice)
213 {
214 	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
215 
216 	rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
217 	return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
218 }
219 
makeImageCreateInfo(deUint32 width,deUint32 height,deUint32 depth,VkFormat format)220 VkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, deUint32 depth, VkFormat format)
221 {
222 	const VkImageCreateInfo			imageCreateInfo			=
223 	{
224 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,																// VkStructureType			sType;
225 		DE_NULL,																							// const void*				pNext;
226 		(VkImageCreateFlags)0u,																				// VkImageCreateFlags		flags;
227 		VK_IMAGE_TYPE_3D,																					// VkImageType				imageType;
228 		format,																								// VkFormat					format;
229 		makeExtent3D(width, height, depth),																	// VkExtent3D				extent;
230 		1u,																									// deUint32					mipLevels;
231 		1u,																									// deUint32					arrayLayers;
232 		VK_SAMPLE_COUNT_1_BIT,																				// VkSampleCountFlagBits	samples;
233 		VK_IMAGE_TILING_OPTIMAL,																			// VkImageTiling			tiling;
234 		VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,		// VkImageUsageFlags		usage;
235 		VK_SHARING_MODE_EXCLUSIVE,																			// VkSharingMode			sharingMode;
236 		0u,																									// deUint32					queueFamilyIndexCount;
237 		DE_NULL,																							// const deUint32*			pQueueFamilyIndices;
238 		VK_IMAGE_LAYOUT_UNDEFINED																			// VkImageLayout			initialLayout;
239 	};
240 
241 	return imageCreateInfo;
242 }
243 
makeQueryPool(const DeviceInterface & vk,const VkDevice device,const VkQueryType queryType,deUint32 queryCount)244 Move<VkQueryPool> makeQueryPool(const DeviceInterface&		vk,
245 								const VkDevice				device,
246 								const VkQueryType			queryType,
247 								deUint32					queryCount)
248 {
249 	const VkQueryPoolCreateInfo				queryPoolCreateInfo =
250 	{
251 		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,		// sType
252 		DE_NULL,										// pNext
253 		(VkQueryPoolCreateFlags)0,						// flags
254 		queryType,										// queryType
255 		queryCount,										// queryCount
256 		0u,												// pipelineStatistics
257 	};
258 	return createQueryPool(vk, device, &queryPoolCreateInfo);
259 }
260 
261 
registerShaderModule(const DeviceInterface & vkd,const VkDevice device,Context & context,std::vector<de::SharedPtr<Move<VkShaderModule>>> & shaderModules,std::vector<VkPipelineShaderStageCreateInfo> & shaderCreateInfos,VkShaderStageFlagBits stage,const std::string & externalNamePart,const std::string & internalNamePart)262 bool registerShaderModule (const DeviceInterface&								vkd,
263 						   const VkDevice										device,
264 						   Context&												context,
265 						   std::vector<de::SharedPtr<Move<VkShaderModule>>>&	shaderModules,
266 						   std::vector<VkPipelineShaderStageCreateInfo>&		shaderCreateInfos,
267 						   VkShaderStageFlagBits								stage,
268 						   const std::string&									externalNamePart,
269 						   const std::string&									internalNamePart)
270 {
271 	char fullShaderName[40];
272 	snprintf(fullShaderName, 40, externalNamePart.c_str(), internalNamePart.c_str());
273 	std::string fsn = fullShaderName;
274 	if (fsn.empty())
275 		return false;
276 
277 	shaderModules.push_back(makeVkSharedPtr(createShaderModule(vkd, device, context.getBinaryCollection().get(fsn), 0)));
278 
279 	shaderCreateInfos.push_back(
280 		{
281 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
282 			DE_NULL,
283 			(VkPipelineShaderStageCreateFlags)0,
284 			stage,														// stage
285 			shaderModules.back()->get(),								// shader
286 			"main",
287 			DE_NULL,													// pSpecializationInfo
288 		});
289 
290 	return true;
291 }
292 
registerShaderModule(const DeviceInterface & vkd,const VkDevice device,Context & context,RayTracingPipeline & rayTracingPipeline,VkShaderStageFlagBits shaderStage,const std::string & externalNamePart,const std::string & internalNamePart,deUint32 groupIndex)293 bool registerShaderModule (const DeviceInterface&	vkd,
294 						   const VkDevice			device,
295 						   Context&					context,
296 						   RayTracingPipeline&		rayTracingPipeline,
297 						   VkShaderStageFlagBits	shaderStage,
298 						   const std::string&		externalNamePart,
299 						   const std::string&		internalNamePart,
300 						   deUint32					groupIndex)
301 {
302 	char fullShaderName[40];
303 	snprintf(fullShaderName, 40, externalNamePart.c_str(), internalNamePart.c_str());
304 	std::string fsn = fullShaderName;
305 	if (fsn.empty())
306 		return false;
307 	Move<VkShaderModule> shaderModule = createShaderModule(vkd, device, context.getBinaryCollection().get(fsn), 0);
308 	if (*shaderModule == DE_NULL)
309 		return false;
310 	rayTracingPipeline.addShader(shaderStage, shaderModule, groupIndex);
311 	return true;
312 }
313 
getCullFlags(InstanceCullFlags flags)314 VkGeometryInstanceFlagsKHR getCullFlags (InstanceCullFlags flags)
315 {
316 	VkGeometryInstanceFlagsKHR cullFlags = 0u;
317 
318 	if (flags == InstanceCullFlags::CULL_DISABLE || flags == InstanceCullFlags::ALL)
319 		cullFlags |= VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
320 
321 	if (flags == InstanceCullFlags::COUNTERCLOCKWISE || flags == InstanceCullFlags::ALL)
322 		cullFlags |= VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR;
323 
324 	return cullFlags;
325 }
326 
327 class GraphicsConfiguration : public TestConfiguration
328 {
329 public:
330 	virtual							~GraphicsConfiguration		();
331 	void							initConfiguration			(Context&						context,
332 																 TestParams&					testParams) override;
333 	void							fillCommandBuffer			(Context&						context,
334 																 TestParams&					testParams,
335 																 VkCommandBuffer				commandBuffer,
336 																 const VkWriteDescriptorSetAccelerationStructureKHR&	rayQueryAccelerationStructureWriteDescriptorSet,
337 																 const VkDescriptorImageInfo&	resultImageInfo) override;
338 	bool							verifyImage					(BufferWithMemory*				resultBuffer,
339 																 Context&						context,
340 																 TestParams&					testParams) override;
341 	VkFormat						getResultImageFormat		() override;
342 	size_t							getResultImageFormatSize	() override;
343 	VkClearValue					getClearValue				() override;
344 protected:
345 	Move<VkDescriptorSetLayout>		descriptorSetLayout;
346 	Move<VkDescriptorPool>			descriptorPool;
347 	Move<VkDescriptorSet>			descriptorSet;
348 	Move<VkPipelineLayout>			pipelineLayout;
349 	Move<VkRenderPass>				renderPass;
350 	Move<VkFramebuffer>				framebuffer;
351 	std::vector<de::SharedPtr<Move<VkShaderModule> > >	shaderModules;
352 	Move<VkPipeline>				pipeline;
353 	std::vector<tcu::Vec3>			vertices;
354 	Move<VkBuffer>					vertexBuffer;
355 	de::MovePtr<Allocation>			vertexAlloc;
356 };
357 
~GraphicsConfiguration()358 GraphicsConfiguration::~GraphicsConfiguration()
359 {
360 	shaderModules.clear();
361 }
362 
initConfiguration(Context & context,TestParams & testParams)363 void GraphicsConfiguration::initConfiguration (Context&						context,
364 											   TestParams&					testParams)
365 {
366 	const DeviceInterface&										vkd								= context.getDeviceInterface();
367 	const VkDevice												device							= context.getDevice();
368 	const deUint32												queueFamilyIndex				= context.getUniversalQueueFamilyIndex();
369 	Allocator&													allocator						= context.getDefaultAllocator();
370 
371 	descriptorSetLayout																			= DescriptorSetLayoutBuilder()
372 																										.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL_GRAPHICS)
373 																										.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL_GRAPHICS)
374 																										.build(vkd, device);
375 	descriptorPool																				= DescriptorPoolBuilder()
376 																										.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
377 																										.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
378 																										.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
379 	descriptorSet																				= makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
380 	pipelineLayout																				= makePipelineLayout(vkd, device, descriptorSetLayout.get());
381 
382 	std::vector<std::string> rayQueryTestName;
383 	rayQueryTestName.push_back("as_triangle");
384 	rayQueryTestName.push_back("as_aabb");
385 
386 	const std::map<ShaderSourceType,std::vector<std::string>>	shaderNames						=
387 	{
388 										//idx:		0				1				2				3				4
389 										//shader:	vert,			tesc,			tese,			geom,			frag,
390 		{	SST_VERTEX_SHADER,					{	"vert_%s",		"",				"",				"",				"",			}	},
391 		{	SST_TESSELATION_CONTROL_SHADER,		{	"vert",			"tesc_%s",		"tese",			"",				"",			}	},
392 		{	SST_TESSELATION_EVALUATION_SHADER,	{	"vert",			"tesc",			"tese_%s",		"",				"",			}	},
393 		{	SST_GEOMETRY_SHADER,				{	"vert_vid",		"",				"",				"geom_%s",		"",			}	},
394 		{	SST_FRAGMENT_SHADER,				{	"vert",			"",				"",				"",				"frag_%s",	}	},
395 	};
396 
397 	auto														shaderNameIt					= shaderNames.find(testParams.shaderSourceType);
398 	if(shaderNameIt == end(shaderNames))
399 		TCU_THROW(InternalError, "Wrong shader source type");
400 
401 	std::vector<VkPipelineShaderStageCreateInfo>				shaderCreateInfos;
402 	bool tescX, teseX, fragX;
403 			registerShaderModule(vkd,	device,	context,	shaderModules,	shaderCreateInfos,	VK_SHADER_STAGE_VERTEX_BIT,						shaderNameIt->second[0],	rayQueryTestName[testParams.bottomTestType]);
404 	tescX = registerShaderModule(vkd,	device, context,	shaderModules,	shaderCreateInfos,	VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,		shaderNameIt->second[1],	rayQueryTestName[testParams.bottomTestType]);
405 	teseX = registerShaderModule(vkd,	device,	context,	shaderModules,	shaderCreateInfos,	VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,	shaderNameIt->second[2],	rayQueryTestName[testParams.bottomTestType]);
406 			registerShaderModule(vkd,	device,	context,	shaderModules,	shaderCreateInfos,	VK_SHADER_STAGE_GEOMETRY_BIT,					shaderNameIt->second[3],	rayQueryTestName[testParams.bottomTestType]);
407 	fragX = registerShaderModule(vkd,	device,	context,	shaderModules,	shaderCreateInfos,	VK_SHADER_STAGE_FRAGMENT_BIT,					shaderNameIt->second[4],	rayQueryTestName[testParams.bottomTestType]);
408 
409 	const vk::VkSubpassDescription		subpassDesc			=
410 	{
411 		(vk::VkSubpassDescriptionFlags)0,
412 		vk::VK_PIPELINE_BIND_POINT_GRAPHICS,							// pipelineBindPoint
413 		0u,																// inputCount
414 		DE_NULL,														// pInputAttachments
415 		0u,																// colorCount
416 		DE_NULL,														// pColorAttachments
417 		DE_NULL,														// pResolveAttachments
418 		DE_NULL,														// depthStencilAttachment
419 		0u,																// preserveCount
420 		DE_NULL,														// pPreserveAttachments
421 	};
422 	const vk::VkRenderPassCreateInfo	renderPassParams	=
423 	{
424 		vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,					// sType
425 		DE_NULL,														// pNext
426 		(vk::VkRenderPassCreateFlags)0,
427 		0u,																// attachmentCount
428 		DE_NULL,														// pAttachments
429 		1u,																// subpassCount
430 		&subpassDesc,													// pSubpasses
431 		0u,																// dependencyCount
432 		DE_NULL,														// pDependencies
433 	};
434 
435 	renderPass = createRenderPass(vkd, device, &renderPassParams);
436 
437 	const vk::VkFramebufferCreateInfo	framebufferParams	=
438 	{
439 		vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,					// sType
440 		DE_NULL,														// pNext
441 		(vk::VkFramebufferCreateFlags)0,
442 		*renderPass,													// renderPass
443 		0u,																// attachmentCount
444 		DE_NULL,														// pAttachments
445 		testParams.width,												// width
446 		testParams.height,												// height
447 		1u,																// layers
448 	};
449 
450 	framebuffer = createFramebuffer(vkd, device, &framebufferParams);
451 
452 	VkPrimitiveTopology					testTopology		= VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
453 	tcu::Vec3 v0(0.0f, 0.0f, 0.0f);
454 	tcu::Vec3 v1(float(testParams.width) - 1.0f, 0.0f, 0.0f);
455 	tcu::Vec3 v2(0.0f, float(testParams.height) - 1.0f, 0.0f);
456 	tcu::Vec3 v3(float(testParams.width) - 1.0f, float(testParams.height) - 1.0f, 0.0f);
457 
458 	switch (testParams.shaderSourceType)
459 	{
460 		case SST_TESSELATION_CONTROL_SHADER:
461 		case SST_TESSELATION_EVALUATION_SHADER:
462 			testTopology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
463 			vertices.push_back(v0);
464 			vertices.push_back(v1);
465 			vertices.push_back(v2);
466 			vertices.push_back(v1);
467 			vertices.push_back(v3);
468 			vertices.push_back(v2);
469 			break;
470 		case SST_VERTEX_SHADER:
471 		case SST_GEOMETRY_SHADER:
472 			vertices.push_back(v0);
473 			vertices.push_back(v1);
474 			vertices.push_back(v2);
475 			vertices.push_back(v3);
476 			break;
477 		case SST_FRAGMENT_SHADER:
478 			vertices.push_back( tcu::Vec3(-1.0f,  1.0f, 0.0f) );
479 			vertices.push_back( tcu::Vec3(-1.0f, -1.0f, 0.0f) );
480 			vertices.push_back( tcu::Vec3( 1.0f,  1.0f, 0.0f) );
481 			vertices.push_back( tcu::Vec3( 1.0f, -1.0f, 0.0f) );
482 			break;
483 		default:
484 			TCU_THROW(InternalError, "Wrong shader source type");
485 	}
486 
487 	const VkVertexInputBindingDescription vertexInputBindingDescription =
488 	{
489 		0u,																// uint32_t											binding;
490 		sizeof(tcu::Vec3),												// uint32_t											stride;
491 		VK_VERTEX_INPUT_RATE_VERTEX,									// VkVertexInputRate								inputRate;
492 	};
493 
494 	const VkVertexInputAttributeDescription vertexInputAttributeDescription =
495 	{
496 		0u,																// uint32_t											location;
497 		0u,																// uint32_t											binding;
498 		VK_FORMAT_R32G32B32_SFLOAT,										// VkFormat											format;
499 		0u,																// uint32_t											offset;
500 	};
501 
502 	const VkPipelineVertexInputStateCreateInfo					vertexInputStateCreateInfo		=
503 	{
504 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType									sType;
505 		DE_NULL,														// const void*										pNext;
506 		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags			flags;
507 		1u,																// deUint32											vertexBindingDescriptionCount;
508 		&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*			pVertexBindingDescriptions;
509 		1u,																// deUint32											vertexAttributeDescriptionCount;
510 		&vertexInputAttributeDescription								// const VkVertexInputAttributeDescription*			pVertexAttributeDescriptions;
511 	};
512 
513 	const VkPipelineInputAssemblyStateCreateInfo				inputAssemblyStateCreateInfo	=
514 	{
515 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType									sType;
516 		DE_NULL,														// const void*										pNext;
517 		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags			flags;
518 		testTopology,													// VkPrimitiveTopology								topology;
519 		VK_FALSE														// VkBool32											primitiveRestartEnable;
520 	};
521 
522 	const VkPipelineTessellationStateCreateInfo					tessellationStateCreateInfo		=
523 	{
524 		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,		// VkStructureType									sType;
525 		DE_NULL,														// const void*										pNext;
526 		VkPipelineTessellationStateCreateFlags(0u),						// VkPipelineTessellationStateCreateFlags			flags;
527 		3u																// deUint32											patchControlPoints;
528 	};
529 
530 	VkViewport													viewport						= makeViewport(testParams.width, testParams.height);
531 	VkRect2D													scissor							= makeRect2D(testParams.width, testParams.height);
532 
533 	const VkPipelineViewportStateCreateInfo						viewportStateCreateInfo			=
534 	{
535 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,			// VkStructureType									sType
536 		DE_NULL,														// const void*										pNext
537 		(VkPipelineViewportStateCreateFlags)0,							// VkPipelineViewportStateCreateFlags				flags
538 		1u,																// deUint32											viewportCount
539 		&viewport,														// const VkViewport*								pViewports
540 		1u,																// deUint32											scissorCount
541 		&scissor														// const VkRect2D*									pScissors
542 	};
543 
544 	const VkPipelineRasterizationStateCreateInfo				rasterizationStateCreateInfo =
545 	{
546 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType									sType;
547 		DE_NULL,														// const void*										pNext;
548 		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags			flags;
549 		VK_FALSE,														// VkBool32											depthClampEnable;
550 		fragX ? VK_FALSE : VK_TRUE,										// VkBool32											rasterizerDiscardEnable;
551 		VK_POLYGON_MODE_FILL,											// VkPolygonMode									polygonMode;
552 		VK_CULL_MODE_NONE,												// VkCullModeFlags									cullMode;
553 		VK_FRONT_FACE_CLOCKWISE,										// VkFrontFace										frontFace;
554 		VK_FALSE,														// VkBool32											depthBiasEnable;
555 		0.0f,															// float											depthBiasConstantFactor;
556 		0.0f,															// float											depthBiasClamp;
557 		0.0f,															// float											depthBiasSlopeFactor;
558 		1.0f															// float											lineWidth;
559 	};
560 
561 	const VkPipelineMultisampleStateCreateInfo		multisampleStateCreateInfo =
562 	{
563 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType									sType;
564 		DE_NULL,														// const void*										pNext;
565 		(VkPipelineMultisampleStateCreateFlags)0,						// VkPipelineMultisampleStateCreateFlags			flags;
566 		VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagBits							rasterizationSamples;
567 		VK_FALSE,														// VkBool32											sampleShadingEnable;
568 		0.0f,															// float											minSampleShading;
569 		DE_NULL,														// const VkSampleMask*								pSampleMask;
570 		VK_FALSE,														// VkBool32											alphaToCoverageEnable;
571 		VK_FALSE														// VkBool32											alphaToOneEnable;
572 	};
573 
574 	const VkPipelineColorBlendStateCreateInfo		colorBlendStateCreateInfo =
575 	{
576 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,		// VkStructureType									sType;
577 		DE_NULL,														// const void*										pNext;
578 		(VkPipelineColorBlendStateCreateFlags)0,						// VkPipelineColorBlendStateCreateFlags				flags;
579 		DE_FALSE,														// VkBool32											logicOpEnable;
580 		VK_LOGIC_OP_CLEAR,												// VkLogicOp										logicOp;
581 		0,																// deUint32											attachmentCount;
582 		DE_NULL,														// const VkPipelineColorBlendAttachmentState*		pAttachments;
583 		{ 1.0f, 1.0f, 1.0f, 1.0f }										// float											blendConstants[4];
584 	};
585 
586 	const VkGraphicsPipelineCreateInfo							graphicsPipelineCreateInfo		=
587 	{
588 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,				// VkStructureType									sType;
589 		DE_NULL,														// const void*										pNext;
590 		(VkPipelineCreateFlags)0,										// VkPipelineCreateFlags							flags;
591 		static_cast<deUint32>(shaderCreateInfos.size()),				// deUint32											stageCount;
592 		shaderCreateInfos.data(),										// const VkPipelineShaderStageCreateInfo*			pStages;
593 		&vertexInputStateCreateInfo,									// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
594 		&inputAssemblyStateCreateInfo,									// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
595 		(tescX||teseX) ? &tessellationStateCreateInfo : DE_NULL,		// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
596 		fragX ? &viewportStateCreateInfo : DE_NULL,						// const VkPipelineViewportStateCreateInfo*			pViewportState;
597 		&rasterizationStateCreateInfo,									// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
598 		fragX ? &multisampleStateCreateInfo : DE_NULL,					// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
599 		DE_NULL,														// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
600 		fragX ? &colorBlendStateCreateInfo : DE_NULL,					// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
601 		DE_NULL,														// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
602 		pipelineLayout.get(),											// VkPipelineLayout									layout;
603 		renderPass.get(),												// VkRenderPass										renderPass;
604 		0u,																// deUint32											subpass;
605 		DE_NULL,														// VkPipeline										basePipelineHandle;
606 		0																// int												basePipelineIndex;
607 	};
608 
609 	pipeline = createGraphicsPipeline(vkd, device, DE_NULL, &graphicsPipelineCreateInfo);
610 
611 	const VkBufferCreateInfo									vertexBufferParams				=
612 	{
613 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,							// VkStructureType									sType;
614 		DE_NULL,														// const void*										pNext;
615 		0u,																// VkBufferCreateFlags								flags;
616 		VkDeviceSize(sizeof(tcu::Vec3) * vertices.size()),				// VkDeviceSize										size;
617 		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
618 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,							// VkBufferUsageFlags								usage;
619 		VK_SHARING_MODE_EXCLUSIVE,										// VkSharingMode									sharingMode;
620 		1u,																// deUint32											queueFamilyIndexCount;
621 		&queueFamilyIndex												// const deUint32*									pQueueFamilyIndices;
622 	};
623 
624 	vertexBuffer	= createBuffer(vkd, device, &vertexBufferParams);
625 	vertexAlloc		= allocator.allocate(getBufferMemoryRequirements(vkd, device, *vertexBuffer), MemoryRequirement::HostVisible);
626 	VK_CHECK(vkd.bindBufferMemory(device, *vertexBuffer, vertexAlloc->getMemory(), vertexAlloc->getOffset()));
627 
628 	// Upload vertex data
629 	deMemcpy(vertexAlloc->getHostPtr(), vertices.data(), vertices.size() * sizeof(tcu::Vec3));
630 	flushAlloc(vkd, device, *vertexAlloc);
631 }
632 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)633 void GraphicsConfiguration::fillCommandBuffer (Context&						context,
634 											   TestParams&					testParams,
635 											   VkCommandBuffer				commandBuffer,
636 											   const VkWriteDescriptorSetAccelerationStructureKHR&	rayQueryAccelerationStructureWriteDescriptorSet,
637 											   const VkDescriptorImageInfo&	resultImageInfo)
638 {
639 	const DeviceInterface&				vkd									= context.getDeviceInterface();
640 	const VkDevice						device								= context.getDevice();
641 
642 	DescriptorSetUpdateBuilder()
643 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
644 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
645 		.update(vkd, device);
646 
647 	const VkRenderPassBeginInfo			renderPassBeginInfo					=
648 	{
649 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,							// VkStructureType								sType;
650 		DE_NULL,															// const void*									pNext;
651 		*renderPass,														// VkRenderPass									renderPass;
652 		*framebuffer,														// VkFramebuffer								framebuffer;
653 		makeRect2D(testParams.width, testParams.height),					// VkRect2D										renderArea;
654 		0u,																	// uint32_t										clearValueCount;
655 		DE_NULL																// const VkClearValue*							pClearValues;
656 	};
657 	VkDeviceSize						vertexBufferOffset					= 0u;
658 
659 	vkd.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
660 	vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
661 	vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
662 	vkd.cmdBindVertexBuffers(commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
663 	vkd.cmdDraw(commandBuffer, deUint32(vertices.size()), 1, 0, 0);
664 	vkd.cmdEndRenderPass(commandBuffer);
665 }
666 
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)667 bool GraphicsConfiguration::verifyImage (BufferWithMemory*					resultBuffer,
668 										 Context&							context,
669 										 TestParams&						testParams)
670 {
671 	// create result image
672 	const bool					allMiss							= (testParams.emptyASCase != EmptyAccelerationStructureCase::NOT_EMPTY);
673 	tcu::TextureFormat			imageFormat						= vk::mapVkFormat(getResultImageFormat());
674 	tcu::ConstPixelBufferAccess	resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr());
675 
676 	// create reference image
677 	std::vector<deUint32>		reference(testParams.width * testParams.height * 2);
678 	tcu::PixelBufferAccess		referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
679 
680 	std::vector<std::vector<deUint32>> primitives				=
681 	{
682 		{0, 1, 2},
683 		{1, 3, 2}
684 	};
685 
686 	tcu::UVec4					hitValue0						= tcu::UVec4(1, 0, 0, 0);
687 	tcu::UVec4					hitValue1						= tcu::UVec4(1, 0, 0, 0);
688 	tcu::UVec4					missValue						= tcu::UVec4(0, 0, 0, 0);
689 	tcu::UVec4					clearValue						= tcu::UVec4(0xFF, 0, 0, 0);
690 
691 	switch (testParams.shaderSourceType)
692 	{
693 		case SST_VERTEX_SHADER:
694 			tcu::clear(referenceAccess, clearValue);
695 			for (deUint32 vertexNdx = 0; vertexNdx < 4; ++vertexNdx)
696 			{
697 				if (!allMiss && (vertexNdx == 1 || vertexNdx == 2))
698 				{
699 					referenceAccess.setPixel(hitValue0, vertexNdx, 0, 0);
700 					referenceAccess.setPixel(hitValue1, vertexNdx, 0, 1);
701 				}
702 				else
703 				{
704 					referenceAccess.setPixel(missValue, vertexNdx, 0, 0);
705 					referenceAccess.setPixel(missValue, vertexNdx, 0, 1);
706 				}
707 			}
708 			break;
709 		case SST_TESSELATION_EVALUATION_SHADER:
710 		case SST_TESSELATION_CONTROL_SHADER:
711 		case SST_GEOMETRY_SHADER:
712 			tcu::clear(referenceAccess, clearValue);
713 			for (deUint32 primitiveNdx = 0; primitiveNdx < primitives.size(); ++primitiveNdx)
714 			for (deUint32 vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
715 			{
716 				deUint32 vNdx = primitives[primitiveNdx][vertexNdx];
717 				if (!allMiss && (vNdx==1 || vNdx==2))
718 				{
719 					referenceAccess.setPixel(hitValue0, primitiveNdx, vertexNdx, 0);
720 					referenceAccess.setPixel(hitValue1, primitiveNdx, vertexNdx, 1);
721 				}
722 				else
723 				{
724 					referenceAccess.setPixel(missValue, primitiveNdx, vertexNdx, 0);
725 					referenceAccess.setPixel(missValue, primitiveNdx, vertexNdx, 1);
726 				}
727 			}
728 			break;
729 		case SST_FRAGMENT_SHADER:
730 			tcu::clear(referenceAccess, missValue);
731 			for (deUint32 y = 0; y < testParams.height; ++y)
732 			for (deUint32 x = 0; x < testParams.width; ++x)
733 			{
734 				if (allMiss || ((x + y) % 2) == 0)
735 					continue;
736 
737 				referenceAccess.setPixel(hitValue0, x, y, 0);
738 				referenceAccess.setPixel(hitValue1, x, y, 1);
739 			}
740 			break;
741 		default:
742 			TCU_THROW(InternalError, "Wrong shader source type");
743 	}
744 
745 	// compare result and reference
746 	return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
747 }
748 
getResultImageFormat()749 VkFormat GraphicsConfiguration::getResultImageFormat ()
750 {
751 	return VK_FORMAT_R32_UINT;
752 }
753 
getResultImageFormatSize()754 size_t GraphicsConfiguration::getResultImageFormatSize ()
755 {
756 	return sizeof(deUint32);
757 }
758 
getClearValue()759 VkClearValue GraphicsConfiguration::getClearValue ()
760 {
761 	return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
762 }
763 
764 class ComputeConfiguration : public TestConfiguration
765 {
766 public:
767 	virtual							~ComputeConfiguration		();
768 	void							initConfiguration			(Context&						context,
769 																 TestParams&					testParams) override;
770 	void							fillCommandBuffer			(Context&						context,
771 																 TestParams&					testParams,
772 																 VkCommandBuffer				commandBuffer,
773 																 const VkWriteDescriptorSetAccelerationStructureKHR&	rayQueryAccelerationStructureWriteDescriptorSet,
774 																 const VkDescriptorImageInfo&	resultImageInfo) override;
775 	bool							verifyImage					(BufferWithMemory*				resultBuffer,
776 																 Context&						context,
777 																 TestParams&					testParams) override;
778 	VkFormat						getResultImageFormat		() override;
779 	size_t							getResultImageFormatSize	() override;
780 	VkClearValue					getClearValue				() override;
781 protected:
782 	Move<VkDescriptorSetLayout>		descriptorSetLayout;
783 	Move<VkDescriptorPool>			descriptorPool;
784 	Move<VkDescriptorSet>			descriptorSet;
785 	Move<VkPipelineLayout>			pipelineLayout;
786 	Move<VkShaderModule>			shaderModule;
787 	Move<VkPipeline>				pipeline;
788 };
789 
~ComputeConfiguration()790 ComputeConfiguration::~ComputeConfiguration()
791 {
792 }
793 
initConfiguration(Context & context,TestParams & testParams)794 void ComputeConfiguration::initConfiguration (Context&						context,
795 											  TestParams&					testParams)
796 {
797 	const DeviceInterface&				vkd									= context.getDeviceInterface();
798 	const VkDevice						device								= context.getDevice();
799 
800 	descriptorSetLayout														= DescriptorSetLayoutBuilder()
801 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
802 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_COMPUTE_BIT)
803 																					.build(vkd, device);
804 	descriptorPool															= DescriptorPoolBuilder()
805 																					.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
806 																					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
807 																					.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
808 	descriptorSet															= makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
809 	pipelineLayout															= makePipelineLayout(vkd, device, descriptorSetLayout.get());
810 
811 	std::vector<std::string> rayQueryTestName;
812 	rayQueryTestName.push_back("comp_as_triangle");
813 	rayQueryTestName.push_back("comp_as_aabb");
814 
815 	shaderModule															= createShaderModule(vkd, device, context.getBinaryCollection().get(rayQueryTestName[testParams.bottomTestType]), 0u);
816 	const VkPipelineShaderStageCreateInfo pipelineShaderStageParams			=
817 	{
818 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
819 		DE_NULL,												// const void*							pNext;
820 		0u,														// VkPipelineShaderStageCreateFlags		flags;
821 		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
822 		*shaderModule,											// VkShaderModule						module;
823 		"main",													// const char*							pName;
824 		DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
825 	};
826 	const VkComputePipelineCreateInfo pipelineCreateInfo =
827 	{
828 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
829 		DE_NULL,											// const void*						pNext;
830 		0u,													// VkPipelineCreateFlags			flags;
831 		pipelineShaderStageParams,							// VkPipelineShaderStageCreateInfo	stage;
832 		*pipelineLayout,									// VkPipelineLayout					layout;
833 		DE_NULL,											// VkPipeline						basePipelineHandle;
834 		0,													// deInt32							basePipelineIndex;
835 	};
836 
837 	pipeline																= createComputePipeline(vkd, device, DE_NULL, &pipelineCreateInfo);
838 }
839 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)840 void ComputeConfiguration::fillCommandBuffer (Context&						context,
841 											  TestParams&					testParams,
842 											  VkCommandBuffer				commandBuffer,
843 											  const VkWriteDescriptorSetAccelerationStructureKHR&	rayQueryAccelerationStructureWriteDescriptorSet,
844 											  const VkDescriptorImageInfo&	resultImageInfo)
845 {
846 	const DeviceInterface&				vkd									= context.getDeviceInterface();
847 	const VkDevice						device								= context.getDevice();
848 
849 	DescriptorSetUpdateBuilder()
850 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
851 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
852 		.update(vkd, device);
853 
854 	vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
855 
856 	vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
857 
858 	vkd.cmdDispatch(commandBuffer, testParams.width, testParams.height, 1);
859 }
860 
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)861 bool ComputeConfiguration::verifyImage (BufferWithMemory*					resultBuffer,
862 										Context&							context,
863 										TestParams&							testParams)
864 {
865 	// create result image
866 	const bool					allMiss							= (testParams.emptyASCase != EmptyAccelerationStructureCase::NOT_EMPTY);
867 	tcu::TextureFormat			imageFormat						= vk::mapVkFormat(getResultImageFormat());
868 	tcu::ConstPixelBufferAccess	resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr());
869 
870 	// create reference image
871 	std::vector<deUint32>		reference(testParams.width * testParams.height * 2);
872 	tcu::PixelBufferAccess		referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
873 
874 	tcu::UVec4 hitValue0	= tcu::UVec4(1, 0, 0, 0);
875 	tcu::UVec4 hitValue1	= tcu::UVec4(1, 0, 0, 0);
876 	tcu::UVec4 missValue	= tcu::UVec4(0, 0, 0, 0);
877 
878 	tcu::clear(referenceAccess, missValue);
879 
880 	for (deUint32 y = 0; y < testParams.height; ++y)
881 	for (deUint32 x = 0; x < testParams.width; ++x)
882 	{
883 		if (allMiss || ((x + y) % 2) == 0)
884 			continue;
885 
886 		referenceAccess.setPixel(hitValue0, x, y, 0);
887 		referenceAccess.setPixel(hitValue1, x, y, 1);
888 	}
889 
890 	// compare result and reference
891 	return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
892 }
893 
getResultImageFormat()894 VkFormat ComputeConfiguration::getResultImageFormat ()
895 {
896 	return VK_FORMAT_R32_UINT;
897 }
898 
getResultImageFormatSize()899 size_t ComputeConfiguration::getResultImageFormatSize ()
900 {
901 	return sizeof(deUint32);
902 }
903 
getClearValue()904 VkClearValue ComputeConfiguration::getClearValue ()
905 {
906 	return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
907 }
908 
909 class RayTracingConfiguration : public TestConfiguration
910 {
911 public:
912 	virtual							~RayTracingConfiguration	();
913 	void							initConfiguration			(Context&						context,
914 																 TestParams&					testParams) override;
915 	void							fillCommandBuffer			(Context&						context,
916 																 TestParams&					testParams,
917 																 VkCommandBuffer				commandBuffer,
918 																 const VkWriteDescriptorSetAccelerationStructureKHR&	rayQueryAccelerationStructureWriteDescriptorSet,
919 																 const VkDescriptorImageInfo&	resultImageInfo) override;
920 	bool							verifyImage					(BufferWithMemory*				resultBuffer,
921 																 Context&						context,
922 																 TestParams&					testParams) override;
923 	VkFormat						getResultImageFormat		() override;
924 	size_t							getResultImageFormatSize	() override;
925 	VkClearValue					getClearValue				() override;
926 protected:
927 	Move<VkDescriptorSetLayout>		descriptorSetLayout;
928 	Move<VkDescriptorPool>			descriptorPool;
929 	Move<VkDescriptorSet>			descriptorSet;
930 	Move<VkPipelineLayout>			pipelineLayout;
931 
932 	de::MovePtr<RayTracingPipeline>	rayTracingPipeline;
933 	Move<VkPipeline>				rtPipeline;
934 
935 	de::MovePtr<BufferWithMemory>	raygenShaderBindingTable;
936 	de::MovePtr<BufferWithMemory>	hitShaderBindingTable;
937 	de::MovePtr<BufferWithMemory>	missShaderBindingTable;
938 	de::MovePtr<BufferWithMemory>	callableShaderBindingTable;
939 
940 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >	bottomLevelAccelerationStructures;
941 	de::MovePtr<TopLevelAccelerationStructure>						topLevelAccelerationStructure;
942 };
943 
~RayTracingConfiguration()944 RayTracingConfiguration::~RayTracingConfiguration()
945 {
946 }
947 
initConfiguration(Context & context,TestParams & testParams)948 void RayTracingConfiguration::initConfiguration (Context&						context,
949 												 TestParams&					testParams)
950 {
951 	const InstanceInterface&			vki									= context.getInstanceInterface();
952 	const DeviceInterface&				vkd									= context.getDeviceInterface();
953 	const VkDevice						device								= context.getDevice();
954 	const VkPhysicalDevice				physicalDevice						= context.getPhysicalDevice();
955 	Allocator&							allocator							= context.getDefaultAllocator();
956 
957 	descriptorSetLayout														= DescriptorSetLayoutBuilder()
958 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
959 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
960 																					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
961 																					.build(vkd, device);
962 	descriptorPool															= DescriptorPoolBuilder()
963 																					.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
964 																					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
965 																					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
966 																					.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
967 	descriptorSet															= makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
968 	pipelineLayout															= makePipelineLayout(vkd, device, descriptorSetLayout.get());
969 
970 	rayTracingPipeline														= de::newMovePtr<RayTracingPipeline>();
971 
972 	const std::map<ShaderSourceType,std::vector<std::string>> shaderNames =
973 	{
974 								//idx:		0				1				2				3				4				5
975 								//shader:	rgen,			isect,			ahit,			chit,			miss,			call
976 								//group:	0				1				1				1				2				3
977 		{	SST_RAY_GENERATION_SHADER,	{	"rgen_%s",		"",				"",				"",				"",				""			}	},
978 		{	SST_INTERSECTION_SHADER,	{	"rgen",			"isect_%s",		"",				"chit_isect",	"miss",			""			}	},
979 		{	SST_ANY_HIT_SHADER,			{	"rgen",			"isect",		"ahit_%s",		"",				"miss",			""			}	},
980 		{	SST_CLOSEST_HIT_SHADER,		{	"rgen",			"isect",		"",				"chit_%s",		"miss",			""			}	},
981 		{	SST_MISS_SHADER,			{	"rgen",			"isect",		"",				"chit",			"miss_%s",		""			}	},
982 		{	SST_CALLABLE_SHADER,		{	"rgen_call",	"",				"",				"chit",			"miss",			"call_%s"	}	},
983 	};
984 
985 	std::vector<std::string> rayQueryTestName;
986 	rayQueryTestName.push_back("as_triangle");
987 	rayQueryTestName.push_back("as_aabb");
988 
989 	auto shaderNameIt = shaderNames.find(testParams.shaderSourceType);
990 	if(shaderNameIt == end(shaderNames))
991 		TCU_THROW(InternalError, "Wrong shader source type");
992 
993 	bool rgenX, isectX, ahitX, chitX, missX, callX;
994 	rgenX = registerShaderModule(vkd,	device,	context,		*rayTracingPipeline,	VK_SHADER_STAGE_RAYGEN_BIT_KHR,			shaderNameIt->second[0],	rayQueryTestName[testParams.bottomTestType],	0);
995 	if (testParams.shaderSourceType == SST_INTERSECTION_SHADER)
996 		isectX = registerShaderModule(vkd, device, context,		*rayTracingPipeline,	VK_SHADER_STAGE_INTERSECTION_BIT_KHR,	shaderNameIt->second[1],	rayQueryTestName[testParams.bottomTestType],	1);
997 	else
998 		isectX = false;
999 	ahitX = registerShaderModule(vkd,	device,	context,		*rayTracingPipeline,	VK_SHADER_STAGE_ANY_HIT_BIT_KHR,		shaderNameIt->second[2],	rayQueryTestName[testParams.bottomTestType],	1);
1000 	chitX = registerShaderModule(vkd,	device,	context,		*rayTracingPipeline,	VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,	shaderNameIt->second[3],	rayQueryTestName[testParams.bottomTestType],	1);
1001 	missX = registerShaderModule(vkd,	device,	context,		*rayTracingPipeline,	VK_SHADER_STAGE_MISS_BIT_KHR,			shaderNameIt->second[4],	rayQueryTestName[testParams.bottomTestType],	2);
1002 	callX = registerShaderModule(vkd,	device,	context,		*rayTracingPipeline,	VK_SHADER_STAGE_CALLABLE_BIT_KHR,		shaderNameIt->second[5],	rayQueryTestName[testParams.bottomTestType],	3);
1003 	bool hitX = isectX || ahitX || chitX;
1004 
1005 	rtPipeline																= rayTracingPipeline->createPipeline(vkd, device, *pipelineLayout);
1006 
1007 	deUint32							shaderGroupHandleSize				= getShaderGroupHandleSize(vki, physicalDevice);
1008 	deUint32							shaderGroupBaseAlignment			= getShaderGroupBaseAlignment(vki, physicalDevice);
1009 
1010 	if (rgenX)	raygenShaderBindingTable									= rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
1011 	if (hitX)	hitShaderBindingTable										= rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
1012 	if (missX)	missShaderBindingTable										= rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1);
1013 	if (callX)	callableShaderBindingTable									= rayTracingPipeline->createShaderBindingTable(vkd, device, *rtPipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 3, 1);
1014 }
1015 
fillCommandBuffer(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer,const VkWriteDescriptorSetAccelerationStructureKHR & rayQueryAccelerationStructureWriteDescriptorSet,const VkDescriptorImageInfo & resultImageInfo)1016 void RayTracingConfiguration::fillCommandBuffer (Context&						context,
1017 												 TestParams&					testParams,
1018 												 VkCommandBuffer				commandBuffer,
1019 												 const VkWriteDescriptorSetAccelerationStructureKHR&	rayQueryAccelerationStructureWriteDescriptorSet,
1020 												 const VkDescriptorImageInfo&	resultImageInfo)
1021 {
1022 	const InstanceInterface&			vki									= context.getInstanceInterface();
1023 	const DeviceInterface&				vkd									= context.getDeviceInterface();
1024 	const VkDevice						device								= context.getDevice();
1025 	const VkPhysicalDevice				physicalDevice						= context.getPhysicalDevice();
1026 	Allocator&							allocator							= context.getDefaultAllocator();
1027 
1028 	{
1029 		de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1030 		bottomLevelAccelerationStructure->setGeometryCount(1);
1031 
1032 		de::SharedPtr<RaytracedGeometryBase> geometry;
1033 		if (testParams.shaderSourceType != SST_INTERSECTION_SHADER)
1034 		{
1035 			tcu::Vec3 v0(0.0f, float(testParams.height), 0.0f);
1036 			tcu::Vec3 v1(0.0f, 0.0f, 0.0f);
1037 			tcu::Vec3 v2(float(testParams.width), float(testParams.height), 0.0f);
1038 			tcu::Vec3 v3(float(testParams.width), 0.0f, 0.0f);
1039 			tcu::Vec3 missOffset(0.0f, 0.0f, 0.0f);
1040 			if (testParams.shaderSourceType == SST_MISS_SHADER)
1041 				missOffset = tcu::Vec3(1.0f + float(testParams.width), 0.0f, 0.0f);
1042 
1043 			geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1044 			geometry->addVertex(v0 + missOffset);
1045 			geometry->addVertex(v1 + missOffset);
1046 			geometry->addVertex(v2 + missOffset);
1047 			geometry->addVertex(v2 + missOffset);
1048 			geometry->addVertex(v1 + missOffset);
1049 			geometry->addVertex(v3 + missOffset);
1050 		}
1051 		else // testParams.shaderSourceType == SST_INTERSECTION_SHADER
1052 		{
1053 			tcu::Vec3 v0(0.0f, 0.0f, -0.1f);
1054 			tcu::Vec3 v1(float(testParams.width), float(testParams.height), 0.1f);
1055 
1056 			geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
1057 			geometry->addVertex(v0);
1058 			geometry->addVertex(v1);
1059 		}
1060 		bottomLevelAccelerationStructure->addGeometry(geometry);
1061 		bottomLevelAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1062 
1063 		for (auto& blas : bottomLevelAccelerationStructures)
1064 			blas->createAndBuild(vkd, device, commandBuffer, allocator);
1065 	}
1066 
1067 	topLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1068 	topLevelAccelerationStructure->setInstanceCount(1);
1069 	topLevelAccelerationStructure->addInstance(bottomLevelAccelerationStructures[0]);
1070 	topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1071 
1072 	const TopLevelAccelerationStructure*			topLevelAccelerationStructurePtr		= topLevelAccelerationStructure.get();
1073 	VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet	=
1074 	{
1075 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
1076 		DE_NULL,															//  const void*							pNext;
1077 		1u,																	//  deUint32							accelerationStructureCount;
1078 		topLevelAccelerationStructurePtr->getPtr(),							//  const VkAccelerationStructureKHR*	pAccelerationStructures;
1079 	};
1080 
1081 	DescriptorSetUpdateBuilder()
1082 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
1083 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1084 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
1085 		.update(vkd, device);
1086 
1087 	vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
1088 
1089 	vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *rtPipeline);
1090 
1091 	deUint32							shaderGroupHandleSize				= getShaderGroupHandleSize(vki, physicalDevice);
1092 	VkStridedDeviceAddressRegionKHR		raygenShaderBindingTableRegion		= raygenShaderBindingTable.get() != DE_NULL		? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize)		: makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1093 	VkStridedDeviceAddressRegionKHR		hitShaderBindingTableRegion			= hitShaderBindingTable.get() != DE_NULL		? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize)			: makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1094 	VkStridedDeviceAddressRegionKHR		missShaderBindingTableRegion		= missShaderBindingTable.get() != DE_NULL		? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize)		: makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1095 	VkStridedDeviceAddressRegionKHR		callableShaderBindingTableRegion	= callableShaderBindingTable.get() != DE_NULL	? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize)	: makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1096 
1097 	cmdTraceRays(vkd,
1098 		commandBuffer,
1099 		&raygenShaderBindingTableRegion,
1100 		&missShaderBindingTableRegion,
1101 		&hitShaderBindingTableRegion,
1102 		&callableShaderBindingTableRegion,
1103 		testParams.width, testParams.height, 1);
1104 }
1105 
verifyImage(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)1106 bool RayTracingConfiguration::verifyImage (BufferWithMemory*					resultBuffer,
1107 										   Context&								context,
1108 										   TestParams&							testParams)
1109 {
1110 	// create result image
1111 	const bool					allMiss							= (testParams.emptyASCase != EmptyAccelerationStructureCase::NOT_EMPTY);
1112 	tcu::TextureFormat			imageFormat						= vk::mapVkFormat(getResultImageFormat());
1113 	tcu::ConstPixelBufferAccess	resultAccess(imageFormat, testParams.width, testParams.height, 2, resultBuffer->getAllocation().getHostPtr());
1114 
1115 	// create reference image
1116 	std::vector<deUint32>		reference(testParams.width * testParams.height * 2);
1117 	tcu::PixelBufferAccess		referenceAccess(imageFormat, testParams.width, testParams.height, 2, reference.data());
1118 
1119 	tcu::UVec4					missValue	(0, 0, 0, 0);
1120 	tcu::UVec4					hitValue	(1, 0, 0, 0);
1121 
1122 	for (deUint32 y = 0; y < testParams.height; ++y)
1123 	for (deUint32 x = 0; x < testParams.width; ++x)
1124 	{
1125 		if (allMiss || ((x + y) % 2) == 0)
1126 		{
1127 			referenceAccess.setPixel(missValue, x, y, 0);
1128 			referenceAccess.setPixel(missValue, x, y, 1);
1129 		}
1130 		else
1131 		{
1132 			referenceAccess.setPixel(hitValue, x, y, 0);
1133 			referenceAccess.setPixel(hitValue, x, y, 1);
1134 		}
1135 	}
1136 
1137 	// compare result and reference
1138 	return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
1139 }
1140 
getResultImageFormat()1141 VkFormat RayTracingConfiguration::getResultImageFormat ()
1142 {
1143 	return VK_FORMAT_R32_UINT;
1144 }
1145 
getResultImageFormatSize()1146 size_t RayTracingConfiguration::getResultImageFormatSize ()
1147 {
1148 	return sizeof(deUint32);
1149 }
1150 
getClearValue()1151 VkClearValue RayTracingConfiguration::getClearValue ()
1152 {
1153 	return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
1154 }
1155 
createTestConfiguration(const ShaderSourcePipeline & shaderSourcePipeline)1156 de::SharedPtr<TestConfiguration> createTestConfiguration(const ShaderSourcePipeline& shaderSourcePipeline)
1157 {
1158 	switch (shaderSourcePipeline)
1159 	{
1160 	case SSP_GRAPHICS_PIPELINE:
1161 		return de::SharedPtr<TestConfiguration>(new GraphicsConfiguration());
1162 	case SSP_COMPUTE_PIPELINE:
1163 		return de::SharedPtr<TestConfiguration>(new ComputeConfiguration());
1164 	case SSP_RAY_TRACING_PIPELINE:
1165 		return de::SharedPtr<TestConfiguration>(new RayTracingConfiguration());
1166 	default:
1167 		TCU_THROW(InternalError, "Wrong shader source pipeline");
1168 	}
1169 	return de::SharedPtr<TestConfiguration>();
1170 }
1171 
1172 class CheckerboardSceneBuilder : public SceneBuilder
1173 {
1174 public:
1175 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	initBottomAccelerationStructures (Context&							context,
1176 																									  TestParams&						testParams) override;
1177 	de::MovePtr<TopLevelAccelerationStructure>						initTopAccelerationStructure	 (Context&							context,
1178 																									  TestParams&						testParams,
1179 																									  std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >&	bottomLevelAccelerationStructures) override;
1180 };
1181 
initBottomAccelerationStructures(Context & context,TestParams & testParams)1182 std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> CheckerboardSceneBuilder::initBottomAccelerationStructures (Context&			context,
1183 																														  TestParams&		testParams)
1184 {
1185 	DE_UNREF(context);
1186 
1187 	// Cull flags can only be used with triangles.
1188 	DE_ASSERT(testParams.cullFlags == InstanceCullFlags::NONE || testParams.bottomTestType == BTT_TRIANGLES);
1189 
1190 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >	result;
1191 
1192 	const auto instanceFlags = getCullFlags(testParams.cullFlags);
1193 
1194 	tcu::Vec3 v0(0.0, 1.0, 0.0);
1195 	tcu::Vec3 v1(0.0, 0.0, 0.0);
1196 	tcu::Vec3 v2(1.0, 1.0, 0.0);
1197 	tcu::Vec3 v3(1.0, 0.0, 0.0);
1198 
1199 	// Different vertex configurations of a triangle whose parameter x is set to NaN during inactive_triangles tests
1200 	const bool nanConfig[4][4] =
1201 	{
1202 		{ true,		true,		true,		true	},
1203 		{ false,	true,		true,		false	},
1204 		{ false,	false,		true,		false	},
1205 		{ false,	true,		false,		false	},
1206 	};
1207 
1208 	unsigned int geometryCount = testParams.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_TRIANGLES ? 4U : 1U;
1209 
1210 	if (testParams.topTestType == TTT_DIFFERENT_INSTANCES)
1211 	{
1212 		de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1213 		bottomLevelAccelerationStructure->setGeometryCount(1u);
1214 		de::SharedPtr<RaytracedGeometryBase> geometry;
1215 		if (testParams.bottomTestType == BTT_TRIANGLES)
1216 		{
1217 			geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices);
1218 			if (testParams.indexType == VK_INDEX_TYPE_NONE_KHR)
1219 			{
1220 				if (instanceFlags == 0u)
1221 				{
1222 					geometry->addVertex(v0);
1223 					geometry->addVertex(v1);
1224 					geometry->addVertex(v2);
1225 					geometry->addVertex(v2);
1226 					geometry->addVertex(v1);
1227 					geometry->addVertex(v3);
1228 				}
1229 				else // Counterclockwise so the flags will be needed for the geometry to be visible.
1230 				{
1231 					geometry->addVertex(v2);
1232 					geometry->addVertex(v1);
1233 					geometry->addVertex(v0);
1234 					geometry->addVertex(v3);
1235 					geometry->addVertex(v1);
1236 					geometry->addVertex(v2);
1237 				}
1238 			}
1239 			else // m_data.indexType != VK_INDEX_TYPE_NONE_KHR
1240 			{
1241 				geometry->addVertex(v0);
1242 				geometry->addVertex(v1);
1243 				geometry->addVertex(v2);
1244 				geometry->addVertex(v3);
1245 
1246 				if (instanceFlags == 0u)
1247 				{
1248 					geometry->addIndex(0);
1249 					geometry->addIndex(1);
1250 					geometry->addIndex(2);
1251 					geometry->addIndex(2);
1252 					geometry->addIndex(1);
1253 					geometry->addIndex(3);
1254 				}
1255 				else // Counterclockwise so the flags will be needed for the geometry to be visible.
1256 				{
1257 					geometry->addIndex(2);
1258 					geometry->addIndex(1);
1259 					geometry->addIndex(0);
1260 					geometry->addIndex(3);
1261 					geometry->addIndex(1);
1262 					geometry->addIndex(2);
1263 				}
1264 
1265 			}
1266 		}
1267 		else // m_data.bottomTestType == BTT_AABBS
1268 		{
1269 			geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices);
1270 
1271 			if (!testParams.padVertices)
1272 			{
1273 				// Single AABB.
1274 				geometry->addVertex(tcu::Vec3(0.0f, 0.0f, -0.1f));
1275 				geometry->addVertex(tcu::Vec3(1.0f, 1.0f, 0.1f));
1276 			}
1277 			else
1278 			{
1279 				// Multiple AABBs covering the same space.
1280 				geometry->addVertex(tcu::Vec3(0.0f, 0.0f, -0.1f));
1281 				geometry->addVertex(tcu::Vec3(0.5f, 0.5f,  0.1f));
1282 
1283 				geometry->addVertex(tcu::Vec3(0.5f, 0.5f, -0.1f));
1284 				geometry->addVertex(tcu::Vec3(1.0f, 1.0f,  0.1f));
1285 
1286 				geometry->addVertex(tcu::Vec3(0.0f, 0.5f, -0.1f));
1287 				geometry->addVertex(tcu::Vec3(0.5f, 1.0f,  0.1f));
1288 
1289 				geometry->addVertex(tcu::Vec3(0.5f, 0.0f, -0.1f));
1290 				geometry->addVertex(tcu::Vec3(1.0f, 0.5f,  0.1f));
1291 			}
1292 		}
1293 
1294 		bottomLevelAccelerationStructure->addGeometry(geometry);
1295 		result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1296 	}
1297 	else // m_data.topTestType == TTT_IDENTICAL_INSTANCES
1298 	{
1299 		tcu::TextureFormat	texFormat	= mapVkFormat(testParams.vertexFormat);
1300 		tcu::Vec3			scale		( 1.0f, 1.0f, 1.0f );
1301 		if (tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
1302 			scale = tcu::Vec3(1.0f / float(testParams.width), 1.0f / float(testParams.height), 1.0f);
1303 
1304 		// triangle and aabb tests use geometries/aabbs with different vertex positions and the same identity matrix in each instance data
1305 		for (deUint32 y = 0; y < testParams.height; ++y)
1306 		for (deUint32 x = 0; x < testParams.width; ++x)
1307 		{
1308 			// let's build a chessboard of geometries
1309 			if (((x + y) % 2) == 0)
1310 				continue;
1311 			tcu::Vec3 xyz((float)x, (float)y, 0.0f);
1312 
1313 			de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1314 			bottomLevelAccelerationStructure->setGeometryCount(geometryCount);
1315 
1316 			if (testParams.bottomTestType == BTT_TRIANGLES)
1317 			{
1318 				for (unsigned int i = 0; i < geometryCount; i++)
1319 				{
1320 					de::SharedPtr<RaytracedGeometryBase> geometry;
1321 					geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices);
1322 
1323 					if (testParams.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_TRIANGLES)
1324 					{
1325 						const auto nanValue = tcu::Float32::nan().asFloat();
1326 
1327 						if (nanConfig[i][0])
1328 							v0.x() = nanValue;
1329 						if (nanConfig[i][1])
1330 							v1.x() = nanValue;
1331 						if (nanConfig[i][2])
1332 							v2.x() = nanValue;
1333 						if (nanConfig[i][3])
1334 							v3.x() = nanValue;
1335 					}
1336 
1337 					if (testParams.indexType == VK_INDEX_TYPE_NONE_KHR)
1338 					{
1339 						if (instanceFlags == 0u)
1340 						{
1341 							geometry->addVertex(scale * (xyz + v0));
1342 							geometry->addVertex(scale * (xyz + v1));
1343 							geometry->addVertex(scale * (xyz + v2));
1344 							geometry->addVertex(scale * (xyz + v2));
1345 							geometry->addVertex(scale * (xyz + v1));
1346 							geometry->addVertex(scale * (xyz + v3));
1347 						}
1348 						else // Counterclockwise so the flags will be needed for the geometry to be visible.
1349 						{
1350 							geometry->addVertex(scale * (xyz + v2));
1351 							geometry->addVertex(scale * (xyz + v1));
1352 							geometry->addVertex(scale * (xyz + v0));
1353 							geometry->addVertex(scale * (xyz + v3));
1354 							geometry->addVertex(scale * (xyz + v1));
1355 							geometry->addVertex(scale * (xyz + v2));
1356 						}
1357 					}
1358 
1359 					else
1360 					{
1361 						geometry->addVertex(scale * (xyz + v0));
1362 						geometry->addVertex(scale * (xyz + v1));
1363 						geometry->addVertex(scale * (xyz + v2));
1364 						geometry->addVertex(scale * (xyz + v3));
1365 
1366 						if (instanceFlags == 0u)
1367 						{
1368 							geometry->addIndex(0);
1369 							geometry->addIndex(1);
1370 							geometry->addIndex(2);
1371 							geometry->addIndex(2);
1372 							geometry->addIndex(1);
1373 							geometry->addIndex(3);
1374 						}
1375 						else // Counterclockwise so the flags will be needed for the geometry to be visible.
1376 						{
1377 							geometry->addIndex(2);
1378 							geometry->addIndex(1);
1379 							geometry->addIndex(0);
1380 							geometry->addIndex(3);
1381 							geometry->addIndex(1);
1382 							geometry->addIndex(2);
1383 						}
1384 					}
1385 
1386 					bottomLevelAccelerationStructure->addGeometry(geometry);
1387 				}
1388 			}
1389 			else // testParams.bottomTestType == BTT_AABBS
1390 			{
1391 				de::SharedPtr<RaytracedGeometryBase> geometry;
1392 				geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_AABBS_KHR, testParams.vertexFormat, testParams.indexType, testParams.padVertices);
1393 
1394 				if (!testParams.padVertices)
1395 				{
1396 					// Single AABB.
1397 					geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.0f, -0.1f)));
1398 					geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 1.0f, 0.1f)));
1399 				}
1400 				else
1401 				{
1402 					// Multiple AABBs covering the same space.
1403 					geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.0f, -0.1f)));
1404 					geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.5f,  0.1f)));
1405 
1406 					geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.5f, -0.1f)));
1407 					geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 1.0f,  0.1f)));
1408 
1409 					geometry->addVertex(scale * (xyz + tcu::Vec3(0.0f, 0.5f, -0.1f)));
1410 					geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 1.0f,  0.1f)));
1411 
1412 					geometry->addVertex(scale * (xyz + tcu::Vec3(0.5f, 0.0f, -0.1f)));
1413 					geometry->addVertex(scale * (xyz + tcu::Vec3(1.0f, 0.5f,  0.1f)));
1414 				}
1415 
1416 				bottomLevelAccelerationStructure->addGeometry(geometry);
1417 			}
1418 
1419 			result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1420 		}
1421 	}
1422 
1423 	return result;
1424 }
1425 
initTopAccelerationStructure(Context & context,TestParams & testParams,std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> & bottomLevelAccelerationStructures)1426 de::MovePtr<TopLevelAccelerationStructure> CheckerboardSceneBuilder::initTopAccelerationStructure (Context&			context,
1427 																								   TestParams&		testParams,
1428 																								   std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures)
1429 {
1430 	DE_UNREF(context);
1431 
1432 	const auto instanceCount = testParams.width * testParams.height / 2u;
1433 	const auto instanceFlags = getCullFlags(testParams.cullFlags);
1434 
1435 	de::MovePtr<TopLevelAccelerationStructure>	result = makeTopLevelAccelerationStructure();
1436 	result->setInstanceCount(instanceCount);
1437 
1438 	if (testParams.topTestType == TTT_DIFFERENT_INSTANCES)
1439 	{
1440 
1441 		for (deUint32 y = 0; y < testParams.height; ++y)
1442 		for (deUint32 x = 0; x < testParams.width; ++x)
1443 		{
1444 			if (((x + y) % 2) == 0)
1445 				continue;
1446 			const VkTransformMatrixKHR			transformMatrixKHR =
1447 			{
1448 				{								//  float	matrix[3][4];
1449 					{ 1.0f, 0.0f, 0.0f, (float)x },
1450 					{ 0.0f, 1.0f, 0.0f, (float)y },
1451 					{ 0.0f, 0.0f, 1.0f, 0.0f },
1452 				}
1453 			};
1454 			result->addInstance(bottomLevelAccelerationStructures[0], transformMatrixKHR, 0u, 0xFFu, 0u, instanceFlags);
1455 		}
1456 	}
1457 	else // testParams.topTestType == TTT_IDENTICAL_INSTANCES
1458 	{
1459 		tcu::TextureFormat	texFormat	= mapVkFormat(testParams.vertexFormat);
1460 		tcu::Vec3			scale		( 1.0f, 1.0f, 1.0f );
1461 		if (tcu::getTextureChannelClass(texFormat.type) == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
1462 			scale = tcu::Vec3(float(testParams.width), float(testParams.height), 1.0f);
1463 
1464 		const VkTransformMatrixKHR			transformMatrixKHR =
1465 		{
1466 			{								//  float	matrix[3][4];
1467 				{ scale.x(), 0.0f, 0.0f, 0.0f },
1468 				{ 0.0f, scale.y(), 0.0f, 0.0f },
1469 				{ 0.0f, 0.0f, scale.z(), 0.0f },
1470 			}
1471 		};
1472 
1473 		deUint32 currentInstanceIndex = 0;
1474 
1475 		for (deUint32 y = 0; y < testParams.height; ++y)
1476 		for (deUint32 x = 0; x < testParams.width; ++x)
1477 		{
1478 			if (((x + y) % 2) == 0)
1479 				continue;
1480 			result->addInstance(bottomLevelAccelerationStructures[currentInstanceIndex++], transformMatrixKHR, 0u, 0xFFu, 0u, instanceFlags);
1481 		}
1482 	}
1483 
1484 	return result;
1485 }
1486 
commonASTestsCheckSupport(Context & context)1487 void commonASTestsCheckSupport(Context& context)
1488 {
1489 	context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
1490 	context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
1491 	context.requireDeviceFunctionality("VK_KHR_ray_query");
1492 
1493 	const VkPhysicalDeviceRayQueryFeaturesKHR&	rayQueryFeaturesKHR = context.getRayQueryFeatures();
1494 	if (rayQueryFeaturesKHR.rayQuery == DE_FALSE)
1495 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");
1496 
1497 	const VkPhysicalDeviceAccelerationStructureFeaturesKHR&	accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
1498 	if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
1499 		TCU_THROW(TestError, "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
1500 }
1501 
1502 class RayQueryASBasicTestCase : public TestCase
1503 {
1504 public:
1505 							RayQueryASBasicTestCase		(tcu::TestContext& context, const char* name, const char* desc, const TestParams& data);
1506 							~RayQueryASBasicTestCase	(void);
1507 
1508 	virtual void			checkSupport				(Context& context) const;
1509 	virtual	void			initPrograms				(SourceCollections& programCollection) const;
1510 	virtual TestInstance*	createInstance				(Context& context) const;
1511 protected:
1512 	TestParams				m_data;
1513 };
1514 
1515 class RayQueryASFuncArgTestCase : public RayQueryASBasicTestCase
1516 {
1517 public:
1518 							RayQueryASFuncArgTestCase		(tcu::TestContext& context, const char* name, const char* desc, const TestParams& data);
~RayQueryASFuncArgTestCase(void)1519 							~RayQueryASFuncArgTestCase		(void) {}
1520 
1521 	virtual	void			initPrograms					(SourceCollections& programCollection) const;
1522 };
1523 
1524 class RayQueryASBasicTestInstance : public TestInstance
1525 {
1526 public:
1527 									RayQueryASBasicTestInstance		(Context& context,
1528 																	 const TestParams& data);
1529 									~RayQueryASBasicTestInstance	(void);
1530 	tcu::TestStatus					iterate							(void);
1531 protected:
1532 	bool							iterateNoWorkers				(void);
1533 	bool							iterateWithWorkers				(void);
1534 	de::MovePtr<BufferWithMemory>	runTest							(TestConfiguration* testConfiguration,
1535 																	 SceneBuilder* sceneBuilder,
1536 																	 const deUint32 workerThreadsCount);
1537 
1538 
1539 private:
1540 	TestParams														m_data;
1541 };
1542 
RayQueryASBasicTestCase(tcu::TestContext & context,const char * name,const char * desc,const TestParams & data)1543 RayQueryASBasicTestCase::RayQueryASBasicTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams& data)
1544 	: vkt::TestCase	(context, name, desc)
1545 	, m_data		(data)
1546 {
1547 }
1548 
~RayQueryASBasicTestCase(void)1549 RayQueryASBasicTestCase::~RayQueryASBasicTestCase (void)
1550 {
1551 }
1552 
checkSupport(Context & context) const1553 void RayQueryASBasicTestCase::checkSupport (Context& context) const
1554 {
1555 	commonASTestsCheckSupport(context);
1556 
1557 	const VkPhysicalDeviceFeatures2& features2 = context.getDeviceFeatures2();
1558 
1559 	if ((m_data.shaderSourceType == SST_TESSELATION_CONTROL_SHADER ||
1560 		 m_data.shaderSourceType == SST_TESSELATION_EVALUATION_SHADER) &&
1561 		features2.features.tessellationShader == DE_FALSE )
1562 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.tessellationShader");
1563 
1564 	if (m_data.shaderSourceType == SST_GEOMETRY_SHADER &&
1565 		features2.features.geometryShader == DE_FALSE )
1566 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceFeatures2.geometryShader");
1567 
1568 	if (m_data.shaderSourceType == SST_RAY_GENERATION_SHADER ||
1569 		m_data.shaderSourceType == SST_INTERSECTION_SHADER ||
1570 		m_data.shaderSourceType == SST_ANY_HIT_SHADER ||
1571 		m_data.shaderSourceType == SST_CLOSEST_HIT_SHADER ||
1572 		m_data.shaderSourceType == SST_MISS_SHADER ||
1573 		m_data.shaderSourceType == SST_CALLABLE_SHADER)
1574 	{
1575 		context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1576 
1577 		const VkPhysicalDeviceRayTracingPipelineFeaturesKHR&	rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
1578 
1579 		if(rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE )
1580 			TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1581 	}
1582 
1583 	switch (m_data.shaderSourceType)
1584 	{
1585 	case SST_VERTEX_SHADER:
1586 	case SST_TESSELATION_CONTROL_SHADER:
1587 	case SST_TESSELATION_EVALUATION_SHADER:
1588 	case SST_GEOMETRY_SHADER:
1589 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
1590 		break;
1591 	default:
1592 		break;
1593 	}
1594 
1595 	const VkPhysicalDeviceAccelerationStructureFeaturesKHR&	accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
1596 	if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR && accelerationStructureFeaturesKHR.accelerationStructureHostCommands == DE_FALSE)
1597 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructureHostCommands");
1598 
1599 	// Check supported vertex format.
1600 	checkAccelerationStructureVertexBufferFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_data.vertexFormat);
1601 }
1602 
initPrograms(SourceCollections & programCollection) const1603 void RayQueryASBasicTestCase::initPrograms (SourceCollections& programCollection) const
1604 {
1605 	const vk::ShaderBuildOptions	buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1606 
1607 	// create parts of programs responsible for test execution
1608 	std::vector<std::string> rayQueryTest;
1609 	std::vector<std::string> rayQueryTestName;
1610 	rayQueryTestName.push_back("as_triangle");
1611 	rayQueryTestName.push_back("as_aabb");
1612 
1613 	{
1614 		std::stringstream css;
1615 		css <<
1616 			"  float tmin     = 0.0;\n"
1617 			"  float tmax     = 1.0;\n"
1618 			"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1619 			"  rayQueryEXT rq;\n"
1620 			"  rayQueryInitializeEXT(rq, rqTopLevelAS, " << ((m_data.cullFlags == InstanceCullFlags::NONE) ? "0" : "gl_RayFlagsCullBackFacingTrianglesEXT") << ", 0xFF, origin, tmin, direct, tmax);\n"
1621 			"  if(rayQueryProceedEXT(rq))\n"
1622 			"  {\n"
1623 			"    if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT)\n"
1624 			"    {\n"
1625 			"      hitValue.y = 1;\n"
1626 			"      hitValue.x = 1;\n"
1627 			"    }\n"
1628 			"  }\n";
1629 		rayQueryTest.push_back(css.str());
1630 	}
1631 	{
1632 		std::stringstream css;
1633 		css <<
1634 			"  float tmin     = 0.0;\n"
1635 			"  float tmax     = 1.0;\n"
1636 			"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1637 			"  rayQueryEXT rq;\n"
1638 			"  rayQueryInitializeEXT(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);\n"
1639 			"  if(rayQueryProceedEXT(rq))\n"
1640 			"  {\n"
1641 			"    if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionAABBEXT)\n"
1642 			"    {\n"
1643 			"      hitValue.y = 1;\n"
1644 			"      hitValue.x = 1;\n"
1645 			"    }\n"
1646 			"  }\n";
1647 		rayQueryTest.push_back(css.str());
1648 	}
1649 
1650 	// create all programs
1651 	if (m_data.shaderSourcePipeline == SSP_GRAPHICS_PIPELINE)
1652 	{
1653 		{
1654 			std::stringstream css;
1655 			css <<
1656 				"#version 460 core\n"
1657 				"layout (location = 0) in vec3 position;\n"
1658 				"out gl_PerVertex\n"
1659 				"{\n"
1660 				"  vec4 gl_Position;\n"
1661 				"};\n"
1662 				"void main()\n"
1663 				"{\n"
1664 				"  gl_Position = vec4(position, 1.0);\n"
1665 				"}\n";
1666 			programCollection.glslSources.add("vert") << glu::VertexSource(css.str()) << buildOptions;
1667 		}
1668 
1669 		{
1670 			std::stringstream css;
1671 			css <<
1672 				"#version 460 core\n"
1673 				"layout (location = 0) in vec3 position;\n"
1674 				"out gl_PerVertex\n"
1675 				"{\n"
1676 				"  vec4 gl_Position;\n"
1677 				"};\n"
1678 				"layout(location = 0) out int vertexIndex;\n"
1679 				"void main()\n"
1680 				"{\n"
1681 				"  gl_Position = vec4(position, 1.0);\n"
1682 				"  vertexIndex = gl_VertexIndex;\n"
1683 				"}\n";
1684 			programCollection.glslSources.add("vert_vid") << glu::VertexSource(css.str()) << buildOptions;
1685 		}
1686 
1687 		{
1688 			std::stringstream css;
1689 			css <<
1690 				"#version 460 core\n"
1691 				"#extension GL_EXT_ray_query : require\n"
1692 				"layout (location = 0) in vec3 position;\n"
1693 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1694 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1695 				"void main()\n"
1696 				"{\n"
1697 				"  vec3  origin   = vec3(float(position.x) + 0.5, float(position.y) + 0.5, 0.5);\n"
1698 				"  uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1699 				rayQueryTest[m_data.bottomTestType] <<
1700 				"  imageStore(result, ivec3(gl_VertexIndex, 0, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1701 				"  imageStore(result, ivec3(gl_VertexIndex, 0, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1702 				"  gl_Position = vec4(position,1);\n"
1703 				"}\n";
1704 			std::stringstream cssName;
1705 			cssName << "vert_" << rayQueryTestName[m_data.bottomTestType];
1706 
1707 			programCollection.glslSources.add(cssName.str()) << glu::VertexSource(css.str()) << buildOptions;
1708 		}
1709 
1710 		{
1711 			std::stringstream css;
1712 			css <<
1713 				"#version 460 core\n"
1714 				"#extension GL_EXT_tessellation_shader : require\n"
1715 				"in gl_PerVertex {\n"
1716 				"  vec4  gl_Position;\n"
1717 				"} gl_in[];\n"
1718 				"layout(vertices = 3) out;\n"
1719 				"void main (void)\n"
1720 				"{\n"
1721 				"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1722 				"  gl_TessLevelInner[0] = 1;\n"
1723 				"  gl_TessLevelOuter[0] = 1;\n"
1724 				"  gl_TessLevelOuter[1] = 1;\n"
1725 				"  gl_TessLevelOuter[2] = 1;\n"
1726 				"}\n";
1727 			programCollection.glslSources.add("tesc") << glu::TessellationControlSource(css.str()) << buildOptions;
1728 		}
1729 
1730 		{
1731 			std::stringstream css;
1732 			css <<
1733 				"#version 460 core\n"
1734 				"#extension GL_EXT_tessellation_shader : require\n"
1735 				"#extension GL_EXT_ray_query : require\n"
1736 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1737 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1738 				"in gl_PerVertex {\n"
1739 				"  vec4  gl_Position;\n"
1740 				"} gl_in[];\n"
1741 				"layout(vertices = 3) out;\n"
1742 				"void main (void)\n"
1743 				"{\n"
1744 				"  vec3  origin   = vec3(gl_in[gl_InvocationID].gl_Position.x + 0.5, gl_in[gl_InvocationID].gl_Position.y + 0.5, 0.5);\n"
1745 				"  uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1746 				rayQueryTest[m_data.bottomTestType] <<
1747 				"  imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1748 				"  imageStore(result, ivec3(gl_PrimitiveID, gl_InvocationID, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1749 				"  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
1750 				"  gl_TessLevelInner[0] = 1;\n"
1751 				"  gl_TessLevelOuter[0] = 1;\n"
1752 				"  gl_TessLevelOuter[1] = 1;\n"
1753 				"  gl_TessLevelOuter[2] = 1;\n"
1754 				"}\n";
1755 			std::stringstream cssName;
1756 			cssName << "tesc_" << rayQueryTestName[m_data.bottomTestType];
1757 
1758 			programCollection.glslSources.add(cssName.str()) << glu::TessellationControlSource(css.str()) << buildOptions;
1759 		}
1760 
1761 		{
1762 			std::stringstream css;
1763 			css <<
1764 				"#version 460 core\n"
1765 				"#extension GL_EXT_tessellation_shader : require\n"
1766 				"#extension GL_EXT_ray_query : require\n"
1767 				"layout(triangles, equal_spacing, ccw) in;\n"
1768 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1769 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1770 				"void main (void)\n"
1771 				"{\n"
1772 				"  for (int i = 0; i < 3; ++i)\n"
1773 				"  {\n"
1774 				"    vec3  origin   = vec3(gl_in[i].gl_Position.x + 0.5, gl_in[i].gl_Position.y + 0.5, 0.5);\n"
1775 				"    uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1776 				rayQueryTest[m_data.bottomTestType] <<
1777 				"    imageStore(result, ivec3(gl_PrimitiveID, i, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1778 				"    imageStore(result, ivec3(gl_PrimitiveID, i, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1779 				"  }\n"
1780 				"  gl_Position = gl_in[0].gl_Position;\n"
1781 				"}\n";
1782 			std::stringstream cssName;
1783 			cssName << "tese_" << rayQueryTestName[m_data.bottomTestType];
1784 
1785 			programCollection.glslSources.add(cssName.str()) << glu::TessellationEvaluationSource(css.str()) << buildOptions;
1786 		}
1787 
1788 		{
1789 			std::stringstream css;
1790 			css <<
1791 				"#version 460 core\n"
1792 				"#extension GL_EXT_tessellation_shader : require\n"
1793 				"layout(triangles, equal_spacing, ccw) in;\n"
1794 				"void main (void)\n"
1795 				"{\n"
1796 				"  gl_Position = gl_in[0].gl_Position;\n"
1797 				"}\n";
1798 
1799 			programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(css.str()) << buildOptions;
1800 		}
1801 
1802 		{
1803 			std::stringstream css;
1804 			css <<
1805 				"#version 460 core\n"
1806 				"#extension GL_EXT_ray_query : require\n"
1807 				"layout(triangles) in;\n"
1808 				"layout (triangle_strip, max_vertices = 4) out;\n"
1809 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1810 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1811 				"\n"
1812 				"in gl_PerVertex {\n"
1813 				"  vec4  gl_Position;\n"
1814 				"} gl_in[];\n"
1815 				"layout(location = 0) in int vertexIndex[];\n"
1816 				"out gl_PerVertex {\n"
1817 				"  vec4 gl_Position;\n"
1818 				"};\n"
1819 				"void main (void)\n"
1820 				"{\n"
1821 				"  // geometry shader may reorder the vertices, keeping only the winding of the triangles.\n"
1822 				"  // To iterate from the 'first vertex' of the triangle we need to find it first by looking for\n"
1823 				"  // smallest vertex index value.\n"
1824 				"  int minVertexIndex = 10000;"
1825 				"  int firstVertex;"
1826 				"  for (int i = 0; i < gl_in.length(); ++i)\n"
1827 				"  {\n"
1828 				"    if (minVertexIndex > vertexIndex[i])\n"
1829 				"    {\n"
1830 				"      minVertexIndex = vertexIndex[i];\n"
1831 				"      firstVertex    = i;\n"
1832 				"    }\n"
1833 				"  }\n"
1834 				"  for (int j = 0; j < gl_in.length(); ++j)\n"
1835 				"  {\n"
1836 				"    // iterate starting at firstVertex, possibly wrapping around, so the triangle is\n"
1837 				"    // always iterated starting from the smallest vertex index, as found above.\n"
1838 				"    int i = (firstVertex + j) % gl_in.length();\n"
1839 				"    vec3  origin   = vec3(gl_in[i].gl_Position.x + 0.5, gl_in[i].gl_Position.y + 0.5, 0.5);\n"
1840 				"    uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1841 				rayQueryTest[m_data.bottomTestType] <<
1842 				"    imageStore(result, ivec3(gl_PrimitiveIDIn, j, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1843 				"    imageStore(result, ivec3(gl_PrimitiveIDIn, j, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1844 				"    gl_Position      = gl_in[i].gl_Position;\n"
1845 				"    EmitVertex();\n"
1846 				"  }\n"
1847 				"  EndPrimitive();\n"
1848 				"}\n";
1849 			std::stringstream cssName;
1850 			cssName << "geom_" << rayQueryTestName[m_data.bottomTestType];
1851 
1852 			programCollection.glslSources.add(cssName.str()) << glu::GeometrySource(css.str()) << buildOptions;
1853 		}
1854 
1855 		{
1856 			std::stringstream css;
1857 			css <<
1858 				"#version 460 core\n"
1859 				"#extension GL_EXT_ray_query : require\n"
1860 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1861 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1862 				"void main()\n"
1863 				"{\n"
1864 				"  vec3  origin   = vec3(gl_FragCoord.x, gl_FragCoord.y, 0.5);\n"
1865 				"  uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1866 				rayQueryTest[m_data.bottomTestType] <<
1867 				"  imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 0), uvec4(hitValue.x, 0, 0, 0));\n"
1868 				"  imageStore(result, ivec3(gl_FragCoord.xy-vec2(0.5,0.5), 1), uvec4(hitValue.y, 0, 0, 0));\n"
1869 				"}\n";
1870 			std::stringstream cssName;
1871 			cssName << "frag_" << rayQueryTestName[m_data.bottomTestType];
1872 
1873 			programCollection.glslSources.add(cssName.str()) << glu::FragmentSource(css.str()) << buildOptions;
1874 		}
1875 	}
1876 	else if (m_data.shaderSourcePipeline == SSP_COMPUTE_PIPELINE)
1877 	{
1878 		{
1879 			std::stringstream css;
1880 			css <<
1881 				"#version 460 core\n"
1882 				"#extension GL_EXT_ray_query : require\n"
1883 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1884 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;\n"
1885 				"void main()\n"
1886 				"{\n"
1887 				"  vec3  origin   = vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + 0.5, 0.5);\n"
1888 				"  uvec4 hitValue = uvec4(0,0,0,0);\n" <<
1889 				rayQueryTest[m_data.bottomTestType] <<
1890 				"  imageStore(result, ivec3(gl_GlobalInvocationID.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1891 				"  imageStore(result, ivec3(gl_GlobalInvocationID.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1892 				"}\n";
1893 			std::stringstream cssName;
1894 			cssName << "comp_" << rayQueryTestName[m_data.bottomTestType];
1895 
1896 			programCollection.glslSources.add(cssName.str()) << glu::ComputeSource(css.str()) << buildOptions;
1897 		}
1898 	}
1899 	else if (m_data.shaderSourcePipeline == SSP_RAY_TRACING_PIPELINE)
1900 	{
1901 		{
1902 			std::stringstream css;
1903 			css <<
1904 				"#version 460 core\n"
1905 				"#extension GL_EXT_ray_tracing : require\n"
1906 				"layout(location = 0) rayPayloadEXT uvec4 hitValue;\n"
1907 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1908 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1909 				"void main()\n"
1910 				"{\n"
1911 				"  float tmin     = 0.0;\n"
1912 				"  float tmax     = 1.0;\n"
1913 				"  vec3  origin   = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1914 				"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1915 				"  hitValue       = uvec4(0,0,0,0);\n"
1916 				"  traceRayEXT(topLevelAS, 0, 0xFF, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
1917 				"  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1918 				"  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1919 				"}\n";
1920 			programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1921 		}
1922 
1923 		{
1924 			std::stringstream css;
1925 			css <<
1926 				"#version 460 core\n"
1927 				"#extension GL_EXT_ray_tracing : require\n"
1928 				"#extension GL_EXT_ray_query : require\n"
1929 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1930 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1931 				"layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1932 				"void main()\n"
1933 				"{\n"
1934 				"  vec3  origin    = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1935 				"  uvec4  hitValue = uvec4(0,0,0,0);\n" <<
1936 				rayQueryTest[m_data.bottomTestType] <<
1937 				"  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(hitValue.x, 0, 0, 0));\n"
1938 				"  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(hitValue.y, 0, 0, 0));\n"
1939 				"}\n";
1940 			std::stringstream cssName;
1941 			cssName << "rgen_" << rayQueryTestName[m_data.bottomTestType];
1942 
1943 			programCollection.glslSources.add(cssName.str()) << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1944 		}
1945 
1946 		{
1947 			std::stringstream css;
1948 			css <<
1949 				"#version 460 core\n"
1950 				"#extension GL_EXT_ray_tracing : require\n"
1951 				"struct CallValue\n{\n"
1952 				"  vec3  origin;\n"
1953 				"  uvec4 hitValue;\n"
1954 				"};\n"
1955 				"layout(location = 0) callableDataEXT CallValue param;\n"
1956 				"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
1957 				"layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
1958 				"void main()\n"
1959 				"{\n"
1960 				"  param.origin   = vec3(float(gl_LaunchIDEXT.x) + 0.5, float(gl_LaunchIDEXT.y) + 0.5, 0.5);\n"
1961 				"  param.hitValue = uvec4(0, 0, 0, 0);\n"
1962 				"  executeCallableEXT(0, 0);\n"
1963 				"  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 0), uvec4(param.hitValue.x, 0, 0, 0));\n"
1964 				"  imageStore(result, ivec3(gl_LaunchIDEXT.xy, 1), uvec4(param.hitValue.y, 0, 0, 0));\n"
1965 				"}\n";
1966 			programCollection.glslSources.add("rgen_call") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
1967 		}
1968 
1969 		{
1970 			std::stringstream css;
1971 			css <<
1972 				"#version 460 core\n"
1973 				"#extension GL_EXT_ray_tracing : require\n"
1974 				"hitAttributeEXT uvec4 hitValue;\n"
1975 				"void main()\n"
1976 				"{\n"
1977 				"  reportIntersectionEXT(0.5f, 0);\n"
1978 				"}\n";
1979 
1980 			programCollection.glslSources.add("isect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1981 		}
1982 
1983 		{
1984 			std::stringstream css;
1985 			css <<
1986 				"#version 460 core\n"
1987 				"#extension GL_EXT_ray_tracing : require\n"
1988 				"#extension GL_EXT_ray_query : require\n"
1989 				"hitAttributeEXT uvec4 hitValue;\n"
1990 				"layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
1991 				"void main()\n"
1992 				"{\n"
1993 				"  vec3 origin = gl_WorldRayOriginEXT;\n"
1994 				"  hitValue    = uvec4(0,0,0,0);\n" <<
1995 				rayQueryTest[m_data.bottomTestType] <<
1996 				"  reportIntersectionEXT(0.5f, 0);\n"
1997 				"}\n";
1998 			std::stringstream cssName;
1999 			cssName << "isect_" << rayQueryTestName[m_data.bottomTestType];
2000 
2001 			programCollection.glslSources.add(cssName.str()) << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
2002 		}
2003 
2004 		{
2005 			std::stringstream css;
2006 			css <<
2007 				"#version 460 core\n"
2008 				"#extension GL_EXT_ray_tracing : require\n"
2009 				"#extension GL_EXT_ray_query : require\n"
2010 				"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2011 				"layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2012 				"void main()\n"
2013 				"{\n"
2014 				"  vec3 origin = gl_WorldRayOriginEXT;\n" <<
2015 				rayQueryTest[m_data.bottomTestType] <<
2016 				"}\n";
2017 			std::stringstream cssName;
2018 			cssName << "ahit_" << rayQueryTestName[m_data.bottomTestType];
2019 
2020 			programCollection.glslSources.add(cssName.str()) << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2021 		}
2022 
2023 		{
2024 			std::stringstream css;
2025 			css <<
2026 				"#version 460 core\n"
2027 				"#extension GL_EXT_ray_tracing : require\n"
2028 				"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2029 				"void main()\n"
2030 				"{\n"
2031 				"  hitValue.y = 3;\n"
2032 				"}\n";
2033 
2034 			programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2035 		}
2036 
2037 		{
2038 			std::stringstream css;
2039 			css <<
2040 				"#version 460 core\n"
2041 				"#extension GL_EXT_ray_tracing : require\n"
2042 				"#extension GL_EXT_ray_query : require\n"
2043 				"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2044 				"layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2045 				"void main()\n"
2046 				"{\n"
2047 				"  vec3 origin = gl_WorldRayOriginEXT;\n" <<
2048 				rayQueryTest[m_data.bottomTestType] <<
2049 				"}\n";
2050 			std::stringstream cssName;
2051 			cssName << "chit_" << rayQueryTestName[m_data.bottomTestType];
2052 
2053 			programCollection.glslSources.add(cssName.str()) << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2054 		}
2055 
2056 		{
2057 			std::stringstream css;
2058 			css <<
2059 				"#version 460 core\n"
2060 				"#extension GL_EXT_ray_tracing : require\n"
2061 				"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2062 				"hitAttributeEXT uvec4 hitAttrib;\n"
2063 				"void main()\n"
2064 				"{\n"
2065 				"  hitValue = hitAttrib;\n"
2066 				"}\n";
2067 
2068 			programCollection.glslSources.add("chit_isect") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
2069 		}
2070 
2071 		{
2072 			std::stringstream css;
2073 			css <<
2074 				"#version 460 core\n"
2075 				"#extension GL_EXT_ray_tracing : require\n"
2076 				"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2077 				"void main()\n"
2078 				"{\n"
2079 				"  hitValue.x = 4;\n"
2080 				"}\n";
2081 
2082 			programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
2083 		}
2084 
2085 		{
2086 			std::stringstream css;
2087 			css <<
2088 				"#version 460 core\n"
2089 				"#extension GL_EXT_ray_tracing : require\n"
2090 				"#extension GL_EXT_ray_query : require\n"
2091 				"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
2092 				"layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2093 				"void main()\n"
2094 				"{\n"
2095 				"  vec3 origin = gl_WorldRayOriginEXT;\n" <<
2096 				rayQueryTest[m_data.bottomTestType] <<
2097 				"}\n";
2098 			std::stringstream cssName;
2099 			cssName << "miss_" << rayQueryTestName[m_data.bottomTestType];
2100 
2101 			programCollection.glslSources.add(cssName.str()) << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
2102 		}
2103 
2104 		{
2105 			std::stringstream css;
2106 			css <<
2107 				"#version 460 core\n"
2108 				"#extension GL_EXT_ray_tracing : require\n"
2109 				"#extension GL_EXT_ray_query : require\n"
2110 				"struct CallValue\n{\n"
2111 				"  vec3  origin;\n"
2112 				"  uvec4 hitValue;\n"
2113 				"};\n"
2114 				"layout(location = 0) callableDataInEXT CallValue result;\n"
2115 				"layout(set = 0, binding = 2) uniform accelerationStructureEXT rqTopLevelAS;\n"
2116 				"void main()\n"
2117 				"{\n"
2118 				"  vec3 origin    = result.origin;\n"
2119 				"  uvec4 hitValue = uvec4(0,0,0,0);\n" <<
2120 				rayQueryTest[m_data.bottomTestType] <<
2121 				"  result.hitValue = hitValue;\n"
2122 				"}\n";
2123 			std::stringstream cssName;
2124 			cssName << "call_" << rayQueryTestName[m_data.bottomTestType];
2125 
2126 			programCollection.glslSources.add(cssName.str()) << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
2127 		}
2128 	}
2129 }
2130 
createInstance(Context & context) const2131 TestInstance* RayQueryASBasicTestCase::createInstance (Context& context) const
2132 {
2133 	return new RayQueryASBasicTestInstance(context, m_data);
2134 }
2135 
RayQueryASFuncArgTestCase(tcu::TestContext & context,const char * name,const char * desc,const TestParams & data)2136 RayQueryASFuncArgTestCase::RayQueryASFuncArgTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams& data)
2137 	: RayQueryASBasicTestCase (context, name, desc, data)
2138 {
2139 }
2140 
initPrograms(SourceCollections & programCollection) const2141 void RayQueryASFuncArgTestCase::initPrograms (SourceCollections& programCollection) const
2142 {
2143 	const vk::SpirVAsmBuildOptions	spvBuildOptions	(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true);
2144 
2145 	DE_ASSERT(m_data.shaderSourcePipeline == SSP_COMPUTE_PIPELINE);
2146 	DE_ASSERT(m_data.bottomTestType == BTT_TRIANGLES);
2147 
2148 	// The SPIR-V assembly shader below is based on the following GLSL code.
2149 	// In it, rayQueryInitializeBottomWrapper has been modified to take a
2150 	// bare AS as the second argument, instead of a pointer.
2151 	//
2152 	//	#version 460 core
2153 	//	#extension GL_EXT_ray_query : require
2154 	//	layout(r32ui, set = 0, binding = 0) uniform uimage3D result;
2155 	//	layout(set = 0, binding = 1) uniform accelerationStructureEXT rqTopLevelAS;
2156 	//
2157 	//	void rayQueryInitializeBottomWrapper(rayQueryEXT rayQuery,
2158 	//	       accelerationStructureEXT topLevel,
2159 	//	       uint rayFlags, uint cullMask, vec3 origin,
2160 	//	       float tMin, vec3 direction, float tMax)
2161 	//	{
2162 	//	  rayQueryInitializeEXT(rayQuery, topLevel, rayFlags, cullMask, origin, tMin, direction, tMax);
2163 	//	}
2164 	//
2165 	//	void rayQueryInitializeTopWrapper(rayQueryEXT rayQuery,
2166 	//	       accelerationStructureEXT topLevel,
2167 	//	       uint rayFlags, uint cullMask, vec3 origin,
2168 	//	       float tMin, vec3 direction, float tMax)
2169 	//	{
2170 	//	  rayQueryInitializeBottomWrapper(rayQuery, topLevel, rayFlags, cullMask, origin, tMin, direction, tMax);
2171 	//	}
2172 	//
2173 	//	void main()
2174 	//	{
2175 	//	  vec3  origin   = vec3(float(gl_GlobalInvocationID.x) + 0.5, float(gl_GlobalInvocationID.y) + 0.5, 0.5);
2176 	//	  uvec4 hitValue = uvec4(0,0,0,0);
2177 	//	  float tmin     = 0.0;
2178 	//	  float tmax     = 1.0;
2179 	//	  vec3  direct   = vec3(0.0, 0.0, -1.0);
2180 	//	  rayQueryEXT rq;
2181 	//	  rayQueryInitializeTopWrapper(rq, rqTopLevelAS, 0, 0xFF, origin, tmin, direct, tmax);
2182 	//	  if(rayQueryProceedEXT(rq))
2183 	//	  {
2184 	//	    if (rayQueryGetIntersectionTypeEXT(rq, false)==gl_RayQueryCandidateIntersectionTriangleEXT)
2185 	//	    {
2186 	//	      hitValue.y = 1;
2187 	//	      hitValue.x = 1;
2188 	//	    }
2189 	//	  }
2190 	//	  imageStore(result, ivec3(gl_GlobalInvocationID.xy, 0), uvec4(hitValue.x, 0, 0, 0));
2191 	//	  imageStore(result, ivec3(gl_GlobalInvocationID.xy, 1), uvec4(hitValue.y, 0, 0, 0));
2192 	//	}
2193 
2194 	std::stringstream css;
2195 	css
2196 		<< "; SPIR-V\n"
2197 		<< "; Version: 1.4\n"
2198 		<< "; Generator: Khronos Glslang Reference Front End; 10\n"
2199 		<< "; Bound: 139\n"
2200 		<< "; Schema: 0\n"
2201 		<< "OpCapability Shader\n"
2202 		<< "OpCapability RayQueryKHR\n"
2203 		<< "OpExtension \"SPV_KHR_ray_query\"\n"
2204 		<< "%1 = OpExtInstImport \"GLSL.std.450\"\n"
2205 		<< "OpMemoryModel Logical GLSL450\n"
2206 		<< "OpEntryPoint GLCompute %4 \"main\" %60 %86 %114\n"
2207 		<< "OpExecutionMode %4 LocalSize 1 1 1\n"
2208 		<< "OpDecorate %60 BuiltIn GlobalInvocationId\n"
2209 		<< "OpDecorate %86 DescriptorSet 0\n"
2210 		<< "OpDecorate %86 Binding 1\n"
2211 		<< "OpDecorate %114 DescriptorSet 0\n"
2212 		<< "OpDecorate %114 Binding 0\n"
2213 		<< "%2 = OpTypeVoid\n"
2214 		<< "%3 = OpTypeFunction %2\n"
2215 
2216 		// Bare query type
2217 		<< "%6 = OpTypeRayQueryKHR\n"
2218 
2219 		// Pointer to query.
2220 		<< "%7 = OpTypePointer Function %6\n"
2221 
2222 		// Bare AS type.
2223 		<< "%8 = OpTypeAccelerationStructureKHR\n"
2224 
2225 		// Pointer to AS.
2226 		<< "%9 = OpTypePointer UniformConstant %8\n"
2227 
2228 		<< "%10 = OpTypeInt 32 0\n"
2229 		<< "%11 = OpTypePointer Function %10\n"
2230 		<< "%12 = OpTypeFloat 32\n"
2231 		<< "%13 = OpTypeVector %12 3\n"
2232 		<< "%14 = OpTypePointer Function %13\n"
2233 		<< "%15 = OpTypePointer Function %12\n"
2234 
2235 		// This is the function type for rayQueryInitializeTopWrapper and the old rayQueryInitializeBottomWrapper.
2236 		<< "%16 = OpTypeFunction %2 %7 %9 %11 %11 %14 %15 %14 %15\n"
2237 
2238 		// This is the new function type for the modified rayQueryInitializeBottomWrapper that uses a bare AS.
2239 		//<< "%16b = OpTypeFunction %2 %6 %8 %11 %11 %14 %15 %14 %15\n"
2240 		<< "%16b = OpTypeFunction %2 %7 %8 %11 %11 %14 %15 %14 %15\n"
2241 
2242 		<< "%58 = OpTypeVector %10 3\n"
2243 		<< "%59 = OpTypePointer Input %58\n"
2244 		<< "%60 = OpVariable %59 Input\n"
2245 		<< "%61 = OpConstant %10 0\n"
2246 		<< "%62 = OpTypePointer Input %10\n"
2247 		<< "%66 = OpConstant %12 0.5\n"
2248 		<< "%68 = OpConstant %10 1\n"
2249 		<< "%74 = OpTypeVector %10 4\n"
2250 		<< "%75 = OpTypePointer Function %74\n"
2251 		<< "%77 = OpConstantComposite %74 %61 %61 %61 %61\n"
2252 		<< "%79 = OpConstant %12 0\n"
2253 		<< "%81 = OpConstant %12 1\n"
2254 		<< "%83 = OpConstant %12 -1\n"
2255 		<< "%84 = OpConstantComposite %13 %79 %79 %83\n"
2256 		<< "%86 = OpVariable %9 UniformConstant\n"
2257 		<< "%87 = OpConstant %10 255\n"
2258 		<< "%99 = OpTypeBool\n"
2259 		<< "%103 = OpConstantFalse %99\n"
2260 		<< "%104 = OpTypeInt 32 1\n"
2261 		<< "%105 = OpConstant %104 0\n"
2262 		<< "%112 = OpTypeImage %10 3D 0 0 0 2 R32ui\n"
2263 		<< "%113 = OpTypePointer UniformConstant %112\n"
2264 		<< "%114 = OpVariable %113 UniformConstant\n"
2265 		<< "%116 = OpTypeVector %10 2\n"
2266 		<< "%119 = OpTypeVector %104 2\n"
2267 		<< "%121 = OpTypeVector %104 3\n"
2268 		<< "%132 = OpConstant %104 1\n"
2269 
2270 		// This is main().
2271 		<< "%4 = OpFunction %2 None %3\n"
2272 		<< "%5 = OpLabel\n"
2273 		<< "%57 = OpVariable %14 Function\n"
2274 		<< "%76 = OpVariable %75 Function\n"
2275 		<< "%78 = OpVariable %15 Function\n"
2276 		<< "%80 = OpVariable %15 Function\n"
2277 		<< "%82 = OpVariable %14 Function\n"
2278 		<< "%85 = OpVariable %7 Function\n"
2279 		<< "%88 = OpVariable %11 Function\n"
2280 		<< "%89 = OpVariable %11 Function\n"
2281 		<< "%90 = OpVariable %14 Function\n"
2282 		<< "%92 = OpVariable %15 Function\n"
2283 		<< "%94 = OpVariable %14 Function\n"
2284 		<< "%96 = OpVariable %15 Function\n"
2285 		<< "%63 = OpAccessChain %62 %60 %61\n"
2286 		<< "%64 = OpLoad %10 %63\n"
2287 		<< "%65 = OpConvertUToF %12 %64\n"
2288 		<< "%67 = OpFAdd %12 %65 %66\n"
2289 		<< "%69 = OpAccessChain %62 %60 %68\n"
2290 		<< "%70 = OpLoad %10 %69\n"
2291 		<< "%71 = OpConvertUToF %12 %70\n"
2292 		<< "%72 = OpFAdd %12 %71 %66\n"
2293 		<< "%73 = OpCompositeConstruct %13 %67 %72 %66\n"
2294 		<< "OpStore %57 %73\n"
2295 		<< "OpStore %76 %77\n"
2296 		<< "OpStore %78 %79\n"
2297 		<< "OpStore %80 %81\n"
2298 		<< "OpStore %82 %84\n"
2299 		<< "OpStore %88 %61\n"
2300 		<< "OpStore %89 %87\n"
2301 		<< "%91 = OpLoad %13 %57\n"
2302 		<< "OpStore %90 %91\n"
2303 		<< "%93 = OpLoad %12 %78\n"
2304 		<< "OpStore %92 %93\n"
2305 		<< "%95 = OpLoad %13 %82\n"
2306 		<< "OpStore %94 %95\n"
2307 		<< "%97 = OpLoad %12 %80\n"
2308 		<< "OpStore %96 %97\n"
2309 		<< "%98 = OpFunctionCall %2 %35 %85 %86 %88 %89 %90 %92 %94 %96\n"
2310 		<< "%100 = OpRayQueryProceedKHR %99 %85\n"
2311 		<< "OpSelectionMerge %102 None\n"
2312 		<< "OpBranchConditional %100 %101 %102\n"
2313 		<< "%101 = OpLabel\n"
2314 		<< "%106 = OpRayQueryGetIntersectionTypeKHR %10 %85 %105\n"
2315 		<< "%107 = OpIEqual %99 %106 %61\n"
2316 		<< "OpSelectionMerge %109 None\n"
2317 		<< "OpBranchConditional %107 %108 %109\n"
2318 		<< "%108 = OpLabel\n"
2319 		<< "%110 = OpAccessChain %11 %76 %68\n"
2320 		<< "OpStore %110 %68\n"
2321 		<< "%111 = OpAccessChain %11 %76 %61\n"
2322 		<< "OpStore %111 %68\n"
2323 		<< "OpBranch %109\n"
2324 		<< "%109 = OpLabel\n"
2325 		<< "OpBranch %102\n"
2326 		<< "%102 = OpLabel\n"
2327 		<< "%115 = OpLoad %112 %114\n"
2328 		<< "%117 = OpLoad %58 %60\n"
2329 		<< "%118 = OpVectorShuffle %116 %117 %117 0 1\n"
2330 		<< "%120 = OpBitcast %119 %118\n"
2331 		<< "%122 = OpCompositeExtract %104 %120 0\n"
2332 		<< "%123 = OpCompositeExtract %104 %120 1\n"
2333 		<< "%124 = OpCompositeConstruct %121 %122 %123 %105\n"
2334 		<< "%125 = OpAccessChain %11 %76 %61\n"
2335 		<< "%126 = OpLoad %10 %125\n"
2336 		<< "%127 = OpCompositeConstruct %74 %126 %61 %61 %61\n"
2337 		<< "OpImageWrite %115 %124 %127 ZeroExtend\n"
2338 		<< "%128 = OpLoad %112 %114\n"
2339 		<< "%129 = OpLoad %58 %60\n"
2340 		<< "%130 = OpVectorShuffle %116 %129 %129 0 1\n"
2341 		<< "%131 = OpBitcast %119 %130\n"
2342 		<< "%133 = OpCompositeExtract %104 %131 0\n"
2343 		<< "%134 = OpCompositeExtract %104 %131 1\n"
2344 		<< "%135 = OpCompositeConstruct %121 %133 %134 %132\n"
2345 		<< "%136 = OpAccessChain %11 %76 %68\n"
2346 		<< "%137 = OpLoad %10 %136\n"
2347 		<< "%138 = OpCompositeConstruct %74 %137 %61 %61 %61\n"
2348 		<< "OpImageWrite %128 %135 %138 ZeroExtend\n"
2349 		<< "OpReturn\n"
2350 		<< "OpFunctionEnd\n"
2351 
2352 		// This is rayQueryInitializeBottomWrapper, calling OpRayQueryInitializeKHR.
2353 		// We have modified the function type so it takes bare arguments.
2354 		//%25 = OpFunction %2 None %16
2355 		<< "%25 = OpFunction %2 None %16b\n"
2356 
2357 		// These is the modified parameter.
2358 		<< "%17 = OpFunctionParameter %7\n"
2359 		//<< "%17 = OpFunctionParameter %6\n"
2360 		//%18 = OpFunctionParameter %9
2361 		<< "%18 = OpFunctionParameter %8\n"
2362 
2363 		<< "%19 = OpFunctionParameter %11\n"
2364 		<< "%20 = OpFunctionParameter %11\n"
2365 		<< "%21 = OpFunctionParameter %14\n"
2366 		<< "%22 = OpFunctionParameter %15\n"
2367 		<< "%23 = OpFunctionParameter %14\n"
2368 		<< "%24 = OpFunctionParameter %15\n"
2369 		<< "%26 = OpLabel\n"
2370 
2371 		// We no longer need to load this parameter.
2372 		//%37 = OpLoad %8 %18
2373 
2374 		<< "%38 = OpLoad %10 %19\n"
2375 		<< "%39 = OpLoad %10 %20\n"
2376 		<< "%40 = OpLoad %13 %21\n"
2377 		<< "%41 = OpLoad %12 %22\n"
2378 		<< "%42 = OpLoad %13 %23\n"
2379 		<< "%43 = OpLoad %12 %24\n"
2380 
2381 		// We call OpRayQueryInitializeKHR with bare arguments.
2382 		// Note: some experimental lines to pass a bare rayQuery as the first argument have been commented out.
2383 		//OpRayQueryInitializeKHR %17 %37 %38 %39 %40 %41 %42 %43
2384 		<< "OpRayQueryInitializeKHR %17 %18 %38 %39 %40 %41 %42 %43\n"
2385 
2386 		<< "OpReturn\n"
2387 		<< "OpFunctionEnd\n"
2388 
2389 		// This is rayQueryInitializeTopWrapper, calling rayQueryInitializeBottomWrapper.
2390 		<< "%35 = OpFunction %2 None %16\n"
2391 		<< "%27 = OpFunctionParameter %7\n"
2392 		<< "%28 = OpFunctionParameter %9\n"
2393 		<< "%29 = OpFunctionParameter %11\n"
2394 		<< "%30 = OpFunctionParameter %11\n"
2395 		<< "%31 = OpFunctionParameter %14\n"
2396 		<< "%32 = OpFunctionParameter %15\n"
2397 		<< "%33 = OpFunctionParameter %14\n"
2398 		<< "%34 = OpFunctionParameter %15\n"
2399 		<< "%36 = OpLabel\n"
2400 		<< "%44 = OpVariable %11 Function\n"
2401 		<< "%46 = OpVariable %11 Function\n"
2402 		<< "%48 = OpVariable %14 Function\n"
2403 		<< "%50 = OpVariable %15 Function\n"
2404 		<< "%52 = OpVariable %14 Function\n"
2405 		<< "%54 = OpVariable %15 Function\n"
2406 
2407 		// We need to load the second argument.
2408 		//<< "%27b = OpLoad %6 %27\n"
2409 		<< "%28b = OpLoad %8 %28\n"
2410 
2411 		<< "%45 = OpLoad %10 %29\n"
2412 		<< "OpStore %44 %45\n"
2413 		<< "%47 = OpLoad %10 %30\n"
2414 		<< "OpStore %46 %47\n"
2415 		<< "%49 = OpLoad %13 %31\n"
2416 		<< "OpStore %48 %49\n"
2417 		<< "%51 = OpLoad %12 %32\n"
2418 		<< "OpStore %50 %51\n"
2419 		<< "%53 = OpLoad %13 %33\n"
2420 		<< "OpStore %52 %53\n"
2421 		<< "%55 = OpLoad %12 %34\n"
2422 		<< "OpStore %54 %55\n"
2423 
2424 		// We call rayQueryInitializeBottomWrapper with the loaded argument.
2425 		//%56 = OpFunctionCall %2 %25 %27 %28 %44 %46 %48 %50 %52 %54
2426 		//<< "%56 = OpFunctionCall %2 %25 %27b %28b %44 %46 %48 %50 %52 %54\n"
2427 		<< "%56 = OpFunctionCall %2 %25 %27 %28b %44 %46 %48 %50 %52 %54\n"
2428 
2429 		<< "OpReturn\n"
2430 		<< "OpFunctionEnd\n"
2431 		;
2432 
2433 	programCollection.spirvAsmSources.add("comp_as_triangle") << spvBuildOptions << css.str();
2434 }
2435 
RayQueryASBasicTestInstance(Context & context,const TestParams & data)2436 RayQueryASBasicTestInstance::RayQueryASBasicTestInstance (Context& context, const TestParams& data)
2437 	: vkt::TestInstance		(context)
2438 	, m_data				(data)
2439 {
2440 }
2441 
~RayQueryASBasicTestInstance(void)2442 RayQueryASBasicTestInstance::~RayQueryASBasicTestInstance (void)
2443 {
2444 }
2445 
runTest(TestConfiguration * testConfiguration,SceneBuilder * sceneBuilder,const deUint32 workerThreadsCount)2446 de::MovePtr<BufferWithMemory> RayQueryASBasicTestInstance::runTest (TestConfiguration* testConfiguration,
2447 																	SceneBuilder* sceneBuilder,
2448 																	const deUint32 workerThreadsCount)
2449 {
2450 	testConfiguration->initConfiguration(m_context, m_data);
2451 
2452 	const DeviceInterface&				vkd									= m_context.getDeviceInterface();
2453 	const VkDevice						device								= m_context.getDevice();
2454 	const VkQueue						queue								= m_context.getUniversalQueue();
2455 	Allocator&							allocator							= m_context.getDefaultAllocator();
2456 	const deUint32						queueFamilyIndex					= m_context.getUniversalQueueFamilyIndex();
2457 
2458 	const bool							htCopy								= (workerThreadsCount != 0) && (m_data.operationType == OP_COPY);
2459 	const bool							htSerialize							= (workerThreadsCount != 0) && (m_data.operationType == OP_SERIALIZE);
2460 
2461 
2462 	const VkFormat						imageFormat							= testConfiguration->getResultImageFormat();
2463 	const VkImageCreateInfo				imageCreateInfo						= makeImageCreateInfo(m_data.width, m_data.height, 2, imageFormat);
2464 	const VkImageSubresourceRange		imageSubresourceRange				= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2465 	const de::MovePtr<ImageWithMemory>	image								= de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
2466 	const Move<VkImageView>				imageView							= makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, imageFormat, imageSubresourceRange);
2467 
2468 	const VkBufferCreateInfo			resultBufferCreateInfo				= makeBufferCreateInfo(m_data.width * m_data.height * 2 * testConfiguration->getResultImageFormatSize(), VK_BUFFER_USAGE_TRANSFER_DST_BIT);
2469 	const VkImageSubresourceLayers		resultBufferImageSubresourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
2470 	const VkBufferImageCopy				resultBufferImageRegion				= makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, 2), resultBufferImageSubresourceLayers);
2471 	de::MovePtr<BufferWithMemory>		resultBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
2472 
2473 	const VkDescriptorImageInfo			resultImageInfo						= makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
2474 
2475 	const Move<VkCommandPool>			cmdPool								= createCommandPool(vkd, device, 0, queueFamilyIndex);
2476 	const Move<VkCommandBuffer>			cmdBuffer							= allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2477 
2478 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	bottomLevelAccelerationStructures;
2479 	de::MovePtr<TopLevelAccelerationStructure>						topLevelAccelerationStructure;
2480 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	bottomLevelAccelerationStructureCopies;
2481 	de::MovePtr<TopLevelAccelerationStructure>						topLevelAccelerationStructureCopy;
2482 	std::vector<de::SharedPtr<SerialStorage>>						bottomSerialized;
2483 	std::vector<de::SharedPtr<SerialStorage>>						topSerialized;
2484 	std::vector<VkDeviceSize>			accelerationCompactedSizes;
2485 	std::vector<VkDeviceSize>			accelerationSerialSizes;
2486 	Move<VkQueryPool>					m_queryPoolCompact;
2487 	Move<VkQueryPool>					m_queryPoolSerial;
2488 
2489 	beginCommandBuffer(vkd, *cmdBuffer, 0u);
2490 	{
2491 		const VkImageMemoryBarrier			preImageBarrier					= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
2492 																					VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
2493 																					**image, imageSubresourceRange);
2494 		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
2495 
2496 		const VkClearValue					clearValue						= testConfiguration->getClearValue();
2497 		vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
2498 
2499 		const VkImageMemoryBarrier			postImageBarrier				= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
2500 																				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
2501 																				**image, imageSubresourceRange);
2502 		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
2503 
2504 		// build bottom level acceleration structures and their copies ( only when we are testing copying bottom level acceleration structures )
2505 		bool									bottomCompact		= m_data.operationType == OP_COMPACT && m_data.operationTarget == OT_BOTTOM_ACCELERATION;
2506 		bool									bottomSerial		= m_data.operationType == OP_SERIALIZE && m_data.operationTarget == OT_BOTTOM_ACCELERATION;
2507 		const bool								buildWithoutGeom	= (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_GEOMETRIES_BOTTOM);
2508 		const bool								bottomNoPrimitives	= (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_PRIMITIVES_BOTTOM);
2509 		const bool								topNoPrimitives		= (m_data.emptyASCase == EmptyAccelerationStructureCase::NO_PRIMITIVES_TOP);
2510 		const bool								inactiveInstances	= (m_data.emptyASCase == EmptyAccelerationStructureCase::INACTIVE_INSTANCES);
2511 		bottomLevelAccelerationStructures							= sceneBuilder->initBottomAccelerationStructures(m_context, m_data);
2512 		VkBuildAccelerationStructureFlagsKHR	allowCompactionFlag	= VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR;
2513 		VkBuildAccelerationStructureFlagsKHR	emptyCompactionFlag	= VkBuildAccelerationStructureFlagsKHR(0);
2514 		VkBuildAccelerationStructureFlagsKHR	bottomCompactFlags	= (bottomCompact ? allowCompactionFlag : emptyCompactionFlag);
2515 		VkBuildAccelerationStructureFlagsKHR	bottomBuildFlags	= m_data.buildFlags | bottomCompactFlags;
2516 		std::vector<VkAccelerationStructureKHR>	accelerationStructureHandles;
2517 		std::vector<VkDeviceSize>				bottomBlasCompactSize;
2518 		std::vector<VkDeviceSize>				bottomBlasSerialSize;
2519 
2520 		for (auto& blas : bottomLevelAccelerationStructures)
2521 		{
2522 			blas->setBuildType						(m_data.buildType);
2523 			blas->setBuildFlags						(bottomBuildFlags);
2524 			blas->setUseArrayOfPointers				(m_data.bottomUsesAOP);
2525 			blas->setCreateGeneric					(m_data.bottomGeneric);
2526 			blas->setBuildWithoutGeometries			(buildWithoutGeom);
2527 			blas->setBuildWithoutPrimitives			(bottomNoPrimitives);
2528 			blas->createAndBuild					(vkd, device, *cmdBuffer, allocator);
2529 			accelerationStructureHandles.push_back	(*(blas->getPtr()));
2530 		}
2531 
2532 		if (m_data.operationType == OP_COMPACT)
2533 		{
2534 			deUint32 queryCount	= (m_data.operationTarget == OT_BOTTOM_ACCELERATION) ? deUint32(bottomLevelAccelerationStructures.size()) : 1u;
2535 			if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2536 				m_queryPoolCompact = makeQueryPool(vkd, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, queryCount);
2537 			if (m_data.operationTarget == OT_BOTTOM_ACCELERATION)
2538 				queryAccelerationStructureSize(vkd, device, *cmdBuffer, accelerationStructureHandles, m_data.buildType, m_queryPoolCompact.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, 0u, bottomBlasCompactSize);
2539 		}
2540 		if (m_data.operationType == OP_SERIALIZE)
2541 		{
2542 			deUint32 queryCount	= (m_data.operationTarget == OT_BOTTOM_ACCELERATION) ? deUint32(bottomLevelAccelerationStructures.size()) : 1u;
2543 			if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2544 				m_queryPoolSerial = makeQueryPool(vkd, device, VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, queryCount);
2545 			if (m_data.operationTarget == OT_BOTTOM_ACCELERATION)
2546 				queryAccelerationStructureSize(vkd, device, *cmdBuffer, accelerationStructureHandles, m_data.buildType, m_queryPoolSerial.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, bottomBlasSerialSize);
2547 		}
2548 
2549 		// if AS is built on GPU and we are planning to make a compact copy of it or serialize / deserialize it - we have to have download query results to CPU
2550 		if ((m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) && (bottomCompact || bottomSerial))
2551 		{
2552 			endCommandBuffer(vkd, *cmdBuffer);
2553 
2554 			submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2555 
2556 			if (bottomCompact)
2557 				VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolCompact, 0u, deUint32(bottomBlasCompactSize.size()), sizeof(VkDeviceSize) * bottomBlasCompactSize.size(), bottomBlasCompactSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
2558 			if (bottomSerial)
2559 				VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolSerial, 0u, deUint32(bottomBlasSerialSize.size()), sizeof(VkDeviceSize) * bottomBlasSerialSize.size(), bottomBlasSerialSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
2560 
2561 			vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2562 			beginCommandBuffer(vkd, *cmdBuffer, 0u);
2563 		}
2564 
2565 		auto bottomLevelAccelerationStructuresPtr								= &bottomLevelAccelerationStructures;
2566 		if (m_data.operationType != OP_NONE && m_data.operationTarget == OT_BOTTOM_ACCELERATION)
2567 		{
2568 			switch (m_data.operationType)
2569 			{
2570 			case OP_COPY:
2571 			{
2572 				for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i)
2573 				{
2574 					de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
2575 					asCopy->setDeferredOperation(htCopy, workerThreadsCount);
2576 					asCopy->setBuildType(m_data.buildType);
2577 					asCopy->setBuildFlags(m_data.buildFlags);
2578 					asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP);
2579 					asCopy->setCreateGeneric(m_data.bottomGeneric);
2580 					asCopy->setBuildWithoutGeometries(buildWithoutGeom);
2581 					asCopy->setBuildWithoutPrimitives(bottomNoPrimitives);
2582 					asCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, bottomLevelAccelerationStructures[i].get(), 0u, 0u);
2583 					bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
2584 				}
2585 				break;
2586 			}
2587 			case OP_COMPACT:
2588 			{
2589 				for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i)
2590 				{
2591 					de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
2592 					asCopy->setBuildType(m_data.buildType);
2593 					asCopy->setBuildFlags(m_data.buildFlags);
2594 					asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP);
2595 					asCopy->setCreateGeneric(m_data.bottomGeneric);
2596 					asCopy->setBuildWithoutGeometries(buildWithoutGeom);
2597 					asCopy->setBuildWithoutPrimitives(bottomNoPrimitives);
2598 					asCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, bottomLevelAccelerationStructures[i].get(), bottomBlasCompactSize[i], 0u);
2599 					bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
2600 				}
2601 				break;
2602 			}
2603 			case OP_SERIALIZE:
2604 			{
2605 				for (size_t i = 0; i < bottomLevelAccelerationStructures.size(); ++i)
2606 				{
2607 					de::SharedPtr<SerialStorage> storage(new SerialStorage(vkd, device, allocator, m_data.buildType, bottomBlasSerialSize[i]));
2608 
2609 					bottomLevelAccelerationStructures[i]->setDeferredOperation(htSerialize, workerThreadsCount);
2610 					bottomLevelAccelerationStructures[i]->serialize(vkd, device, *cmdBuffer, storage.get());
2611 					bottomSerialized.push_back(storage);
2612 
2613 					if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2614 					{
2615 						endCommandBuffer(vkd, *cmdBuffer);
2616 
2617 						submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2618 
2619 						vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2620 						beginCommandBuffer(vkd, *cmdBuffer, 0u);
2621 					}
2622 
2623 					de::MovePtr<BottomLevelAccelerationStructure> asCopy = makeBottomLevelAccelerationStructure();
2624 					asCopy->setBuildType(m_data.buildType);
2625 					asCopy->setBuildFlags(m_data.buildFlags);
2626 					asCopy->setUseArrayOfPointers(m_data.bottomUsesAOP);
2627 					asCopy->setCreateGeneric(m_data.bottomGeneric);
2628 					asCopy->setBuildWithoutGeometries(buildWithoutGeom);
2629 					asCopy->setBuildWithoutPrimitives(bottomNoPrimitives);
2630 					asCopy->setDeferredOperation(htSerialize, workerThreadsCount);
2631 					asCopy->createAndDeserializeFrom(vkd, device, *cmdBuffer, allocator, storage.get(), 0u);
2632 					bottomLevelAccelerationStructureCopies.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(asCopy.release()));
2633 				}
2634 				break;
2635 			}
2636 			default:
2637 				DE_ASSERT(DE_FALSE);
2638 			}
2639 			bottomLevelAccelerationStructuresPtr = &bottomLevelAccelerationStructureCopies;
2640 		}
2641 
2642 		// build top level acceleration structures and their copies ( only when we are testing copying top level acceleration structures )
2643 		bool									topCompact			= m_data.operationType == OP_COMPACT && m_data.operationTarget == OT_TOP_ACCELERATION;
2644 		bool									topSerial			= m_data.operationType == OP_SERIALIZE && m_data.operationTarget == OT_TOP_ACCELERATION;
2645 		VkBuildAccelerationStructureFlagsKHR	topCompactFlags		= (topCompact ? allowCompactionFlag : emptyCompactionFlag);
2646 		VkBuildAccelerationStructureFlagsKHR	topBuildFlags		= m_data.buildFlags | topCompactFlags;
2647 		std::vector<VkAccelerationStructureKHR> topLevelStructureHandles;
2648 		std::vector<VkDeviceSize>				topBlasCompactSize;
2649 		std::vector<VkDeviceSize>				topBlasSerialSize;
2650 
2651 		topLevelAccelerationStructure								= sceneBuilder->initTopAccelerationStructure(m_context, m_data, *bottomLevelAccelerationStructuresPtr);
2652 		topLevelAccelerationStructure->setBuildType					(m_data.buildType);
2653 		topLevelAccelerationStructure->setBuildFlags				(topBuildFlags);
2654 		topLevelAccelerationStructure->setBuildWithoutPrimitives	(topNoPrimitives);
2655 		topLevelAccelerationStructure->setUseArrayOfPointers		(m_data.topUsesAOP);
2656 		topLevelAccelerationStructure->setCreateGeneric				(m_data.topGeneric);
2657 		topLevelAccelerationStructure->setInactiveInstances			(inactiveInstances);
2658 		topLevelAccelerationStructure->createAndBuild				(vkd, device, *cmdBuffer, allocator);
2659 		topLevelStructureHandles.push_back							(*(topLevelAccelerationStructure->getPtr()));
2660 
2661 		if (topCompact)
2662 			queryAccelerationStructureSize(vkd, device, *cmdBuffer, topLevelStructureHandles, m_data.buildType, m_queryPoolCompact.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_COMPACTED_SIZE_KHR, 0u, topBlasCompactSize);
2663 		if (topSerial)
2664 			queryAccelerationStructureSize(vkd, device, *cmdBuffer, topLevelStructureHandles, m_data.buildType, m_queryPoolSerial.get(), VK_QUERY_TYPE_ACCELERATION_STRUCTURE_SERIALIZATION_SIZE_KHR, 0u, topBlasSerialSize);
2665 
2666 		// if AS is built on GPU and we are planning to make a compact copy of it or serialize / deserialize it - we have to have download query results to CPU
2667 		if ((m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR) && (topCompact || topSerial))
2668 		{
2669 			endCommandBuffer(vkd, *cmdBuffer);
2670 
2671 			submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2672 
2673 			if (topCompact)
2674 				VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolCompact, 0u, deUint32(topBlasCompactSize.size()), sizeof(VkDeviceSize) * topBlasCompactSize.size(), topBlasCompactSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
2675 			if (topSerial)
2676 				VK_CHECK(vkd.getQueryPoolResults(device, *m_queryPoolSerial, 0u, deUint32(topBlasSerialSize.size()), sizeof(VkDeviceSize) * topBlasSerialSize.size(), topBlasSerialSize.data(), sizeof(VkDeviceSize), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT));
2677 
2678 			vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2679 			beginCommandBuffer(vkd, *cmdBuffer, 0u);
2680 		}
2681 
2682 		const TopLevelAccelerationStructure*			topLevelRayTracedPtr	= topLevelAccelerationStructure.get();
2683 		if (m_data.operationType != OP_NONE && m_data.operationTarget == OT_TOP_ACCELERATION)
2684 		{
2685 			switch (m_data.operationType)
2686 			{
2687 				case OP_COPY:
2688 				{
2689 					topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2690 					topLevelAccelerationStructureCopy->setDeferredOperation(htCopy, workerThreadsCount);
2691 					topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
2692 					topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags);
2693 					topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives);
2694 					topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances);
2695 					topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP);
2696 					topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric);
2697 					topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, topLevelAccelerationStructure.get(), 0u, 0u);
2698 					break;
2699 				}
2700 				case OP_COMPACT:
2701 				{
2702 					topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2703 					topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
2704 					topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags);
2705 					topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives);
2706 					topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances);
2707 					topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP);
2708 					topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric);
2709 					topLevelAccelerationStructureCopy->createAndCopyFrom(vkd, device, *cmdBuffer, allocator, topLevelAccelerationStructure.get(), topBlasCompactSize[0], 0u);
2710 					break;
2711 				}
2712 				case OP_SERIALIZE:
2713 				{
2714 					de::SharedPtr<SerialStorage> storage(new SerialStorage(vkd, device, allocator, m_data.buildType, topBlasSerialSize[0]));
2715 
2716 					topLevelAccelerationStructure->setDeferredOperation(htSerialize, workerThreadsCount);
2717 					topLevelAccelerationStructure->serialize(vkd, device, *cmdBuffer, storage.get());
2718 					topSerialized.push_back(storage);
2719 
2720 					if (m_data.buildType == VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR)
2721 					{
2722 						endCommandBuffer(vkd, *cmdBuffer);
2723 
2724 						submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2725 
2726 						vkd.resetCommandPool(device, *cmdPool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
2727 						beginCommandBuffer(vkd, *cmdBuffer, 0u);
2728 					}
2729 
2730 					topLevelAccelerationStructureCopy = makeTopLevelAccelerationStructure();
2731 					topLevelAccelerationStructureCopy->setBuildType(m_data.buildType);
2732 					topLevelAccelerationStructureCopy->setBuildFlags(m_data.buildFlags);
2733 					topLevelAccelerationStructureCopy->setBuildWithoutPrimitives(topNoPrimitives);
2734 					topLevelAccelerationStructureCopy->setInactiveInstances(inactiveInstances);
2735 					topLevelAccelerationStructureCopy->setUseArrayOfPointers(m_data.topUsesAOP);
2736 					topLevelAccelerationStructureCopy->setCreateGeneric(m_data.topGeneric);
2737 					topLevelAccelerationStructureCopy->setDeferredOperation(htSerialize, workerThreadsCount);
2738 					topLevelAccelerationStructureCopy->createAndDeserializeFrom(vkd, device, *cmdBuffer, allocator, storage.get(), 0u);
2739 					break;
2740 				}
2741 				default:
2742 					DE_ASSERT(DE_FALSE);
2743 			}
2744 			topLevelRayTracedPtr = topLevelAccelerationStructureCopy.get();
2745 		}
2746 
2747 		const VkMemoryBarrier				preTraceMemoryBarrier				= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
2748 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, &preTraceMemoryBarrier);
2749 
2750 		VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet	=
2751 		{
2752 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
2753 			DE_NULL,															//  const void*							pNext;
2754 			1u,																	//  deUint32							accelerationStructureCount;
2755 			topLevelRayTracedPtr->getPtr(),										//  const VkAccelerationStructureKHR*	pAccelerationStructures;
2756 		};
2757 
2758 		testConfiguration->fillCommandBuffer(m_context, m_data, *cmdBuffer, accelerationStructureWriteDescriptorSet, resultImageInfo);
2759 
2760 		const VkMemoryBarrier							postTestMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
2761 		const VkMemoryBarrier							postCopyMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
2762 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTestMemoryBarrier);
2763 
2764 		vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
2765 
2766 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
2767 	}
2768 	endCommandBuffer(vkd, *cmdBuffer);
2769 
2770 	submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
2771 
2772 	invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
2773 
2774 	return resultBuffer;
2775 }
2776 
iterateNoWorkers(void)2777 bool RayQueryASBasicTestInstance::iterateNoWorkers (void)
2778 {
2779 	de::SharedPtr<TestConfiguration> testConfiguration	= createTestConfiguration(m_data.shaderSourcePipeline);
2780 	de::SharedPtr<SceneBuilder> sceneBuilder			= de::SharedPtr<SceneBuilder>(new CheckerboardSceneBuilder());
2781 
2782 	const de::MovePtr<BufferWithMemory>	buffer		= runTest(testConfiguration.get(), sceneBuilder.get(), 0);
2783 
2784 	return testConfiguration->verifyImage(buffer.get(), m_context, m_data);
2785 }
2786 
iterateWithWorkers(void)2787 bool RayQueryASBasicTestInstance::iterateWithWorkers (void)
2788 {
2789 	de::SharedPtr<SceneBuilder> sceneBuilder = de::SharedPtr<SceneBuilder>(new CheckerboardSceneBuilder());
2790 
2791 	de::SharedPtr<TestConfiguration> testConfigurationS		= createTestConfiguration(m_data.shaderSourcePipeline);
2792 	de::MovePtr<BufferWithMemory>	singleThreadBufferCPU	= runTest(testConfigurationS.get(), sceneBuilder.get(), 0);
2793 	const bool						singleThreadValidation	= testConfigurationS->verifyImage(singleThreadBufferCPU.get(), m_context, m_data);
2794 	testConfigurationS.clear();
2795 
2796 	de::SharedPtr<TestConfiguration> testConfigurationM		= createTestConfiguration(m_data.shaderSourcePipeline);
2797 	de::MovePtr<BufferWithMemory>	multiThreadBufferCPU	= runTest(testConfigurationM.get(), sceneBuilder.get(), m_data.workerThreadsCount);
2798 	const bool						multiThreadValidation	= testConfigurationM->verifyImage(multiThreadBufferCPU.get(), m_context, m_data);
2799 	testConfigurationM.clear();
2800 
2801 	const deUint32					result					= singleThreadValidation && multiThreadValidation;
2802 
2803 	return result;
2804 }
2805 
iterate(void)2806 tcu::TestStatus RayQueryASBasicTestInstance::iterate(void)
2807 {
2808 	bool result;
2809 	if (m_data.workerThreadsCount != 0)
2810 		result = iterateWithWorkers();
2811 	else
2812 		result = iterateNoWorkers();
2813 
2814 	if (result)
2815 		return tcu::TestStatus::pass("Pass");
2816 	else
2817 		return tcu::TestStatus::fail("Fail");
2818 }
2819 
2820 // Tests dynamic indexing of acceleration structures
2821 class RayQueryASDynamicIndexingTestCase : public TestCase
2822 {
2823 public:
2824 						RayQueryASDynamicIndexingTestCase		(tcu::TestContext& context, const char* name);
2825 						~RayQueryASDynamicIndexingTestCase		(void) = default;
2826 
2827 	void				checkSupport							(Context& context) const override;
2828 	void				initPrograms							(SourceCollections& programCollection) const override;
2829 	TestInstance*		createInstance							(Context& context) const override;
2830 };
2831 
2832 class RayQueryASDynamicIndexingTestInstance : public TestInstance
2833 {
2834 public:
2835 						RayQueryASDynamicIndexingTestInstance	(Context& context);
2836 						~RayQueryASDynamicIndexingTestInstance	(void) = default;
2837 	tcu::TestStatus		iterate									(void) override;
2838 };
2839 
RayQueryASDynamicIndexingTestCase(tcu::TestContext & context,const char * name)2840 RayQueryASDynamicIndexingTestCase::RayQueryASDynamicIndexingTestCase(tcu::TestContext& context, const char* name)
2841 	: TestCase(context, name, "")
2842 {
2843 }
2844 
checkSupport(Context & context) const2845 void RayQueryASDynamicIndexingTestCase::checkSupport(Context& context) const
2846 {
2847 	commonASTestsCheckSupport(context);
2848 	context.requireDeviceFunctionality("VK_EXT_descriptor_indexing");
2849 }
2850 
initPrograms(SourceCollections & programCollection) const2851 void RayQueryASDynamicIndexingTestCase::initPrograms(SourceCollections& programCollection) const
2852 {
2853 	const vk::SpirVAsmBuildOptions spvBuildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true);
2854 
2855 	// compute shader is defined in spir-v as it requires possing pointer to TLAS that was read from ssbo;
2856 	// original spir-v code was generated using following glsl code but resulting spir-v code was modiifed
2857 
2858 	// #version 460 core
2859 	// #extension GL_EXT_ray_query : require
2860 	// #extension GL_EXT_nonuniform_qualifier : enable
2861 
2862 	// #define ARRAY_SIZE 500
2863 	// layout(set = 0, binding = 0) uniform accelerationStructureEXT tlasArray[ARRAY_SIZE];
2864 	// layout(set = 0, binding = 1) readonly buffer topLevelASPointers {
2865 	//     uvec2 ptr[];
2866 	// } tlasPointers;
2867 	// layout(set = 0, binding = 2) readonly buffer topLevelASIndices {
2868 	//     uint idx[];
2869 	// } tlasIndices;
2870 	// layout(set = 0, binding = 3, std430) writeonly buffer Result {
2871 	//     uint value[];
2872 	// } result;
2873 
2874 	// void main()
2875 	// {
2876 	//   float tmin      = 0.0;
2877 	//   float tmax      = 2.0;
2878 	//   vec3  origin    = vec3(0.25f, 0.5f, 1.0);
2879 	//   vec3  direction = vec3(0.0,0.0,-1.0);
2880 	//   uint  tlasIndex = tlasIndices.idx[nonuniformEXT(gl_GlobalInvocationID.x)];
2881 
2882 	//   rayQueryEXT rq;
2883 	//   rayQueryInitializeEXT(rq, tlasArray[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax);
2884 	//   atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x)], 2);
2885 
2886 	//   if (rayQueryProceedEXT(rq))
2887 	//   {
2888 	//     if (rayQueryGetIntersectionTypeEXT(rq, false) == gl_RayQueryCandidateIntersectionTriangleEXT)
2889 	//       atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x)], 3);
2890 	//   }
2891 
2892 	//   //rayQueryInitializeEXT(rq, tlasArray[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax);
2893 	//   rayQueryInitializeEXT(rq, *tlasPointers.ptr[nonuniformEXT(tlasIndex)], gl_RayFlagsCullBackFacingTrianglesEXT, 0xFF, origin, tmin, direction, tmax);
2894 	//   atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x * 2)], 5);
2895 
2896 	//   if (rayQueryProceedEXT(rq))
2897 	//   {
2898 	//     if (rayQueryGetIntersectionTypeEXT(rq, false) == gl_RayQueryCandidateIntersectionTriangleEXT)
2899 	//       atomicAdd(result.value[nonuniformEXT(gl_GlobalInvocationID.x + gl_NumWorkGroups.x * 3)], 7);
2900 	//   }
2901 	// }
2902 
2903 	const std::string compSource =
2904 		"OpCapability Shader\n"
2905 		"OpCapability RayQueryKHR\n"
2906 		"OpCapability ShaderNonUniform\n"
2907 		"OpExtension \"SPV_EXT_descriptor_indexing\"\n"
2908 		"OpExtension \"SPV_KHR_ray_query\"\n"
2909 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
2910 		"OpMemoryModel Logical GLSL450\n"
2911 		"OpEntryPoint GLCompute %4 \"main\" %var_index_ssbo %33 %var_as_arr_uni_ptr %64 %83 %var_as_pointers_ssbo\n"
2912 		"OpExecutionMode %4 LocalSize 1 1 1\n"
2913 		"OpDecorate %25 ArrayStride 4\n"
2914 		"OpMemberDecorate %26 0 NonWritable\n"
2915 		"OpMemberDecorate %26 0 Offset 0\n"
2916 		"OpDecorate %26 Block\n"
2917 		"OpDecorate %var_index_ssbo DescriptorSet 0\n"
2918 		"OpDecorate %var_index_ssbo Binding 2\n"
2919 		"OpDecorate %33 BuiltIn GlobalInvocationId\n"
2920 		"OpDecorate %38 NonUniform\n"
2921 		"OpDecorate %40 NonUniform\n"
2922 		"OpDecorate %41 NonUniform\n"
2923 		"OpDecorate %var_as_arr_uni_ptr DescriptorSet 0\n"
2924 		"OpDecorate %var_as_arr_uni_ptr Binding 0\n"
2925 		"OpDecorate %51 NonUniform\n"
2926 		"OpDecorate %53 NonUniform\n"
2927 		"OpDecorate %54 NonUniform\n"
2928 		"OpDecorate %61 ArrayStride 4\n"
2929 		"OpMemberDecorate %62 0 NonReadable\n"
2930 		"OpMemberDecorate %62 0 Offset 0\n"
2931 		"OpDecorate %62 Block\n"
2932 		"OpDecorate %64 DescriptorSet 0\n"
2933 		"OpDecorate %64 Binding 3\n"
2934 		"OpDecorate %67 NonUniform\n"
2935 		"OpDecorate %83 BuiltIn NumWorkgroups\n"
2936 		"OpDecorate %87 NonUniform\n"
2937 		"OpDecorate %as_index NonUniform\n"
2938 		"OpDecorate %as_device_addres NonUniform\n"
2939 		"OpDecorate %105 NonUniform\n"
2940 		"OpDecorate %122 NonUniform\n"
2941 		"OpDecorate %127 ArrayStride 8\n"
2942 		"OpMemberDecorate %128 0 NonWritable\n"
2943 		"OpMemberDecorate %128 0 Offset 0\n"
2944 		"OpDecorate %128 Block\n"
2945 		"OpDecorate %var_as_pointers_ssbo DescriptorSet 0\n"
2946 		"OpDecorate %var_as_pointers_ssbo Binding 1\n"
2947 		"%2							= OpTypeVoid\n"
2948 		"%3							= OpTypeFunction %2\n"
2949 		"%6							= OpTypeFloat 32\n"
2950 		"%7							= OpTypePointer Function %6\n"
2951 		"%9							= OpConstant %6 0\n"
2952 		"%11						= OpConstant %6 2\n"
2953 		"%12						= OpTypeVector %6 3\n"
2954 		"%13						= OpTypePointer Function %12\n"
2955 		"%15						= OpConstant %6 0.25\n"
2956 		"%16						= OpConstant %6 0.5\n"
2957 		"%17						= OpConstant %6 1\n"
2958 		"%18						= OpConstantComposite %12 %15 %16 %17\n"
2959 		"%20						= OpConstant %6 -1\n"
2960 		"%21						= OpConstantComposite %12 %9 %9 %20\n"
2961 		"%type_uint32				= OpTypeInt 32 0\n"
2962 		"%23						= OpTypePointer Function %type_uint32\n"
2963 		"%25						= OpTypeRuntimeArray %type_uint32\n"
2964 		"%26						= OpTypeStruct %25\n"
2965 		"%27						= OpTypePointer StorageBuffer %26\n"
2966 		"%var_index_ssbo			= OpVariable %27 StorageBuffer\n"
2967 		"%29						= OpTypeInt 32 1\n"
2968 		"%c_int32_0					= OpConstant %29 0\n"
2969 		"%31						= OpTypeVector %type_uint32 3\n"
2970 		"%32						= OpTypePointer Input %31\n"
2971 		"%33						= OpVariable %32 Input\n"
2972 		"%34						= OpConstant %type_uint32 0\n"
2973 		"%35						= OpTypePointer Input %type_uint32\n"
2974 		"%type_uint32_ssbo_ptr		= OpTypePointer StorageBuffer %type_uint32\n"
2975 		"%42						= OpTypeRayQueryKHR\n"
2976 		"%43						= OpTypePointer Function %42\n"
2977 		"%type_as					= OpTypeAccelerationStructureKHR\n"
2978 		"%46						= OpConstant %type_uint32 500\n"
2979 		"%type_as_arr				= OpTypeArray %type_as %46\n"
2980 		"%type_as_arr_uni_ptr		= OpTypePointer UniformConstant %type_as_arr\n"
2981 		"%var_as_arr_uni_ptr		= OpVariable %type_as_arr_uni_ptr UniformConstant\n"
2982 		"%type_as_uni_ptr			= OpTypePointer UniformConstant %type_as\n"
2983 		"%55						= OpConstant %type_uint32 16\n"
2984 		"%56						= OpConstant %type_uint32 255\n"
2985 		"%61						= OpTypeRuntimeArray %type_uint32\n"
2986 		"%62						= OpTypeStruct %61\n"
2987 		"%63						= OpTypePointer StorageBuffer %62\n"
2988 		"%64						= OpVariable %63 StorageBuffer\n"
2989 		"%69						= OpConstant %type_uint32 2\n"
2990 		"%70						= OpConstant %type_uint32 1\n"
2991 		"%72						= OpTypeBool\n"
2992 		"%76						= OpConstantFalse %72\n"
2993 		"%83						= OpVariable %32 Input\n"
2994 		"%89						= OpConstant %type_uint32 3\n"
2995 		"%107						= OpConstant %type_uint32 5\n"
2996 		"%124						= OpConstant %type_uint32 7\n"
2997 
2998 		// <changed_section>
2999 		"%v2uint					= OpTypeVector %type_uint32 2\n"
3000 		"%127						= OpTypeRuntimeArray %v2uint\n"
3001 		"%128						= OpTypeStruct %127\n"
3002 		"%129						= OpTypePointer StorageBuffer %128\n"
3003 		"%var_as_pointers_ssbo		= OpVariable %129 StorageBuffer\n"
3004 		"%type_uint64_ssbo_ptr		= OpTypePointer StorageBuffer %v2uint\n"
3005 		// </changed_section>
3006 
3007 		// void main()
3008 		"%4							= OpFunction %2 None %3\n"
3009 		"%5							= OpLabel\n"
3010 		"%8							= OpVariable %7 Function\n"
3011 		"%10						= OpVariable %7 Function\n"
3012 		"%14						= OpVariable %13 Function\n"
3013 		"%19						= OpVariable %13 Function\n"
3014 		"%24						= OpVariable %23 Function\n"
3015 		"%var_ray_query				= OpVariable %43 Function\n"
3016 		"OpStore %8 %9\n"
3017 		"OpStore %10 %11\n"
3018 		"OpStore %14 %18\n"
3019 		"OpStore %19 %21\n"
3020 		"%36						= OpAccessChain %35 %33 %34\n"
3021 		"%37						= OpLoad %type_uint32 %36\n"
3022 		"%38						= OpCopyObject %type_uint32 %37\n"
3023 		"%40						= OpAccessChain %type_uint32_ssbo_ptr %var_index_ssbo %c_int32_0 %38\n"
3024 		"%41						= OpLoad %type_uint32 %40\n"
3025 		"OpStore %24 %41\n"
3026 
3027 		// rayQueryInitializeEXT using AS that was read from array
3028 		"%50						= OpLoad %type_uint32 %24\n"
3029 		"%51						= OpCopyObject %type_uint32 %50\n"
3030 		"%53						= OpAccessChain %type_as_uni_ptr %var_as_arr_uni_ptr %51\n"
3031 		"%54						= OpLoad %type_as %53\n"
3032 		"%57						= OpLoad %12 %14\n"
3033 		"%58						= OpLoad %6 %8\n"
3034 		"%59						= OpLoad %12 %19\n"
3035 		"%60						= OpLoad %6 %10\n"
3036 		"OpRayQueryInitializeKHR %var_ray_query %54 %55 %56 %57 %58 %59 %60\n"
3037 
3038 		"%65						= OpAccessChain %35 %33 %34\n"
3039 		"%66						= OpLoad %type_uint32 %65\n"
3040 		"%67						= OpCopyObject %type_uint32 %66\n"
3041 		"%68						= OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %67\n"
3042 		"%71						= OpAtomicIAdd %type_uint32 %68 %70 %34 %69\n"
3043 
3044 		"%73						= OpRayQueryProceedKHR %72 %var_ray_query\n"
3045 		"OpSelectionMerge %75 None\n"
3046 		"OpBranchConditional %73 %74 %75\n"
3047 		"%74						= OpLabel\n"
3048 
3049 		"%77						= OpRayQueryGetIntersectionTypeKHR %type_uint32 %var_ray_query %c_int32_0\n"
3050 		"%78						= OpIEqual %72 %77 %34\n"
3051 		"OpSelectionMerge %80 None\n"
3052 		"OpBranchConditional %78 %79 %80\n"
3053 		"%79						= OpLabel\n"
3054 		"%81						= OpAccessChain %35 %33 %34\n"
3055 		"%82						= OpLoad %type_uint32 %81\n"
3056 		"%84						= OpAccessChain %35 %83 %34\n"
3057 		"%85						= OpLoad %type_uint32 %84\n"
3058 		"%86						= OpIAdd %type_uint32 %82 %85\n"
3059 		"%87						= OpCopyObject %type_uint32 %86\n"
3060 		"%88						= OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %87\n"
3061 		"%90						= OpAtomicIAdd %type_uint32 %88 %70 %34 %89\n"
3062 		"OpBranch %80\n"
3063 		"%80						= OpLabel\n"
3064 		"OpBranch %75\n"
3065 		"%75						= OpLabel\n"
3066 
3067 		// rayQueryInitializeEXT using pointer to AS
3068 		"%91						= OpLoad %type_uint32 %24\n"
3069 		"%as_index					= OpCopyObject %type_uint32 %91\n"
3070 
3071 		// <changed_section>
3072 		"%as_device_addres_ptr		= OpAccessChain %type_uint64_ssbo_ptr %var_as_pointers_ssbo %c_int32_0 %as_index\n"
3073 		"%as_device_addres			= OpLoad %v2uint %as_device_addres_ptr\n"
3074 		"%as_to_use					= OpConvertUToAccelerationStructureKHR %type_as %as_device_addres\n"
3075 		// </changed_section>
3076 
3077 		"%95						= OpLoad %12 %14\n"
3078 		"%96						= OpLoad %6 %8\n"
3079 		"%97						= OpLoad %12 %19\n"
3080 		"%98						= OpLoad %6 %10\n"
3081 		"OpRayQueryInitializeKHR %var_ray_query %as_to_use %55 %56 %95 %96 %97 %98\n"
3082 
3083 		"%99						= OpAccessChain %35 %33 %34\n"
3084 		"%100						= OpLoad %type_uint32 %99\n"
3085 		"%101						= OpAccessChain %35 %83 %34\n"
3086 		"%102						= OpLoad %type_uint32 %101\n"
3087 		"%103						= OpIMul %type_uint32 %102 %69\n"
3088 		"%104						= OpIAdd %type_uint32 %100 %103\n"
3089 		"%105						= OpCopyObject %type_uint32 %104\n"
3090 		"%106						= OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %105\n"
3091 		"%108						= OpAtomicIAdd %type_uint32 %106 %70 %34 %107\n"
3092 
3093 		"%109						= OpRayQueryProceedKHR %72 %var_ray_query\n"
3094 		"OpSelectionMerge %111 None\n"
3095 		"OpBranchConditional %109 %110 %111\n"
3096 		"%110						= OpLabel\n"
3097 
3098 		"%112						= OpRayQueryGetIntersectionTypeKHR %type_uint32 %var_ray_query %c_int32_0\n"
3099 		"%113						= OpIEqual %72 %112 %34\n"
3100 		"OpSelectionMerge %115 None\n"
3101 		"OpBranchConditional %113 %114 %115\n"
3102 		"%114						= OpLabel\n"
3103 		"%116						= OpAccessChain %35 %33 %34\n"
3104 		"%117						= OpLoad %type_uint32 %116\n"
3105 		"%118						= OpAccessChain %35 %83 %34\n"
3106 		"%119						= OpLoad %type_uint32 %118\n"
3107 		"%120						= OpIMul %type_uint32 %119 %89\n"
3108 		"%121						= OpIAdd %type_uint32 %117 %120\n"
3109 		"%122						= OpCopyObject %type_uint32 %121\n"
3110 		"%123						= OpAccessChain %type_uint32_ssbo_ptr %64 %c_int32_0 %122\n"
3111 		"%125						= OpAtomicIAdd %type_uint32 %123 %70 %34 %124\n"
3112 		"OpBranch %115\n"
3113 		"%115						= OpLabel\n"
3114 		"OpBranch %111\n"
3115 		"%111						= OpLabel\n"
3116 		"OpReturn\n"
3117 		"OpFunctionEnd\n";
3118 
3119 	programCollection.spirvAsmSources.add("comp") << compSource << spvBuildOptions;
3120 }
3121 
createInstance(Context & context) const3122 TestInstance* RayQueryASDynamicIndexingTestCase::createInstance(Context& context) const
3123 {
3124 	return new RayQueryASDynamicIndexingTestInstance(context);
3125 }
3126 
3127 
RayQueryASDynamicIndexingTestInstance(Context & context)3128 RayQueryASDynamicIndexingTestInstance::RayQueryASDynamicIndexingTestInstance(Context& context)
3129 	: vkt::TestInstance(context)
3130 {
3131 }
3132 
iterate(void)3133 tcu::TestStatus RayQueryASDynamicIndexingTestInstance::iterate(void)
3134 {
3135 	const DeviceInterface&		vkd							= m_context.getDeviceInterface();
3136 	const VkDevice				device						= m_context.getDevice();
3137 	const deUint32				queueFamilyIndex			= m_context.getUniversalQueueFamilyIndex();
3138 	const VkQueue				queue						= m_context.getUniversalQueue();
3139 	Allocator&					allocator					= m_context.getDefaultAllocator();
3140 	const deUint32				tlasCount					= 500;	// changing this will require also changing shaders
3141 	const deUint32				activeTlasCount				= 32;	// number of tlas out of <tlasCount> that will be active
3142 
3143 	const Move<VkDescriptorSetLayout> descriptorSetLayout = DescriptorSetLayoutBuilder()
3144 		.addArrayBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount, VK_SHADER_STAGE_COMPUTE_BIT)
3145 		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)			// pointers to all acceleration structures
3146 		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)			// ssbo with indices of all acceleration structures
3147 		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)			// ssbo with result values
3148 		.build(vkd, device);
3149 
3150 	const Move<VkDescriptorPool> descriptorPool = DescriptorPoolBuilder()
3151 		.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount)
3152 		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3153 		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3154 		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3155 		.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
3156 	const Move<VkDescriptorSet> descriptorSet = makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
3157 
3158 	const Move<VkPipelineLayout>		pipelineLayout		= makePipelineLayout(vkd, device, descriptorSetLayout.get());
3159 	Move<VkShaderModule>				shaderModule		= createShaderModule(vkd, device, m_context.getBinaryCollection().get("comp"), 0u);
3160 	const VkComputePipelineCreateInfo	pipelineCreateInfo
3161 	{
3162 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,			// VkStructureType						sType
3163 		DE_NULL,												// const void*							pNext
3164 		0u,														// VkPipelineCreateFlags				flags
3165 		{														// VkPipelineShaderStageCreateInfo		stage
3166 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
3167 			DE_NULL,
3168 			(VkPipelineShaderStageCreateFlags)0,
3169 			VK_SHADER_STAGE_COMPUTE_BIT,
3170 			*shaderModule,
3171 			"main",
3172 			DE_NULL
3173 		},
3174 		*pipelineLayout,										// VkPipelineLayout						layout
3175 		DE_NULL,												// VkPipeline							basePipelineHandle
3176 		0,														// deInt32								basePipelineIndex
3177 	};
3178 
3179 	Move<VkPipeline>				pipeline				= createComputePipeline(vkd, device, DE_NULL, &pipelineCreateInfo);
3180 
3181 	const VkDeviceSize				pointerBufferSize		= tlasCount * sizeof(VkDeviceAddress);
3182 	const VkBufferCreateInfo		pointerBufferCreateInfo = makeBufferCreateInfo(pointerBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
3183 	de::MovePtr<BufferWithMemory>	pointerBuffer			= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, pointerBufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::DeviceAddress));
3184 
3185 	const VkDeviceSize				indicesBufferSize		= activeTlasCount * sizeof(deUint32);
3186 	const VkBufferCreateInfo		indicesBufferCreateInfo = makeBufferCreateInfo(indicesBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
3187 	de::MovePtr<BufferWithMemory>	indicesBuffer			= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, indicesBufferCreateInfo, MemoryRequirement::HostVisible));
3188 
3189 	const VkDeviceSize				resultBufferSize		= activeTlasCount * sizeof(deUint32) * 4;
3190 	const VkBufferCreateInfo		resultBufferCreateInfo	= makeBufferCreateInfo(resultBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
3191 	de::MovePtr<BufferWithMemory>	resultBuffer			= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
3192 
3193 	const Move<VkCommandPool>		cmdPool					= createCommandPool(vkd, device, 0, queueFamilyIndex);
3194 	const Move<VkCommandBuffer>		cmdBuffer				= allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3195 
3196 	de::SharedPtr<BottomLevelAccelerationStructure>				blas = de::SharedPtr<BottomLevelAccelerationStructure>(makeBottomLevelAccelerationStructure().release());
3197 	std::vector<de::MovePtr<TopLevelAccelerationStructure>>		tlasVect(tlasCount);
3198 	std::vector<VkDeviceAddress>								tlasPtrVect(tlasCount);
3199 	std::vector<VkAccelerationStructureKHR>						tlasVkVect;
3200 
3201 	// randomly scatter AS indices across the range (number of them should be equal to the max subgroup size)
3202 	deRandom rnd;
3203 	deRandom_init(&rnd, 123);
3204 	std::set<deUint32> asIndicesSet;
3205 	while (asIndicesSet.size() < activeTlasCount)
3206 		asIndicesSet.insert(deRandom_getUint32(&rnd) % tlasCount);
3207 
3208 	// fill indices buffer
3209 	deUint32 helperIndex = 0;
3210 	auto& indicesBufferAlloc = indicesBuffer->getAllocation();
3211 	deUint32* indicesBufferPtr = reinterpret_cast<deUint32*>(indicesBufferAlloc.getHostPtr());
3212 	std::for_each(asIndicesSet.begin(), asIndicesSet.end(),
3213 		[&helperIndex, indicesBufferPtr](const deUint32& index)
3214 		{
3215 			indicesBufferPtr[helperIndex++] = index;
3216 		});
3217 	vk::flushAlloc(vkd, device, indicesBufferAlloc);
3218 
3219 	// clear result buffer
3220 	auto& resultBufferAlloc = resultBuffer->getAllocation();
3221 	void* resultBufferPtr = resultBufferAlloc.getHostPtr();
3222 	deMemset(resultBufferPtr, 0, static_cast<size_t>(resultBufferSize));
3223 	vk::flushAlloc(vkd, device, resultBufferAlloc);
3224 
3225 	beginCommandBuffer(vkd, *cmdBuffer, 0u);
3226 	{
3227 		// build bottom level acceleration structure
3228 		blas->setGeometryData(
3229 			{
3230 				{ 0.0, 0.0, 0.0 },
3231 				{ 1.0, 0.0, 0.0 },
3232 				{ 0.0, 1.0, 0.0 },
3233 			},
3234 			true,
3235 			0u
3236 			);
3237 
3238 		blas->createAndBuild(vkd, device, *cmdBuffer, allocator);
3239 
3240 		// build top level acceleration structures
3241 		for (deUint32 tlasIndex = 0; tlasIndex < tlasCount; ++tlasIndex)
3242 		{
3243 			auto& tlas = tlasVect[tlasIndex];
3244 			tlas = makeTopLevelAccelerationStructure();
3245 			tlas->setInstanceCount(1);
3246 			tlas->addInstance(blas);
3247 			if (!asIndicesSet.count(tlasIndex))
3248 			{
3249 				// tlas that are not in asIndicesSet should be empty but it is hard to do
3250 				// that with current cts utils so we are marking them as inactive instead
3251 				tlas->setInactiveInstances(true);
3252 			}
3253 			tlas->createAndBuild(vkd, device, *cmdBuffer, allocator);
3254 
3255 			// get acceleration structure device address
3256 			const VkAccelerationStructureDeviceAddressInfoKHR addressInfo =
3257 			{
3258 				VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_DEVICE_ADDRESS_INFO_KHR,	// VkStructureType				sType
3259 				DE_NULL,															// const void*					pNext
3260 				*tlas->getPtr()														// VkAccelerationStructureKHR	accelerationStructure
3261 			};
3262 			VkDeviceAddress vkda = vkd.getAccelerationStructureDeviceAddressKHR(device, &addressInfo);
3263 			tlasPtrVect[tlasIndex] = vkda;
3264 		}
3265 
3266 		// fill pointer buffer
3267 		vkd.cmdUpdateBuffer(*cmdBuffer, **pointerBuffer, 0, pointerBufferSize, tlasPtrVect.data());
3268 
3269 		// wait for data transfers
3270 		const VkMemoryBarrier uploadBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
3271 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, &uploadBarrier, 1u);
3272 
3273 		// wait for as build
3274 		const VkMemoryBarrier asBuildBarrier = makeMemoryBarrier(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR);
3275 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, &asBuildBarrier, 1u);
3276 
3277 		tlasVkVect.reserve(tlasCount);
3278 		for (auto& tlas : tlasVect)
3279 			tlasVkVect.push_back(*tlas->getPtr());
3280 
3281 		VkWriteDescriptorSetAccelerationStructureKHR accelerationStructureWriteDescriptorSet =
3282 		{
3283 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	// VkStructureType						sType;
3284 			DE_NULL,															// const void*							pNext;
3285 			tlasCount,															// deUint32								accelerationStructureCount;
3286 			tlasVkVect.data(),													// const VkAccelerationStructureKHR*	pAccelerationStructures;
3287 		};
3288 
3289 		const vk::VkDescriptorBufferInfo pointerBufferInfo	= makeDescriptorBufferInfo(**pointerBuffer, 0u, VK_WHOLE_SIZE);
3290 		const vk::VkDescriptorBufferInfo indicesBufferInfo	= makeDescriptorBufferInfo(**indicesBuffer, 0u, VK_WHOLE_SIZE);
3291 		const vk::VkDescriptorBufferInfo resultInfo			= makeDescriptorBufferInfo(**resultBuffer,  0u, VK_WHOLE_SIZE);
3292 
3293 		DescriptorSetUpdateBuilder()
3294 			.writeArray (*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, tlasCount, &accelerationStructureWriteDescriptorSet)
3295 			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &pointerBufferInfo)
3296 			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &indicesBufferInfo)
3297 			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(3u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo)
3298 			.update(vkd, device);
3299 
3300 		vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
3301 
3302 		vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
3303 
3304 		vkd.cmdDispatch(*cmdBuffer, activeTlasCount, 1, 1);
3305 
3306 		const VkMemoryBarrier postTraceMemoryBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
3307 		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier);
3308 	}
3309 	endCommandBuffer(vkd, *cmdBuffer);
3310 
3311 	submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
3312 
3313 	invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), resultBufferSize);
3314 
3315 	// verify result buffer
3316 	deUint32		failures = 0;
3317 	const deUint32*	resultPtr = reinterpret_cast<deUint32*>(resultBuffer->getAllocation().getHostPtr());
3318 	for (deUint32 index = 0; index < activeTlasCount; ++index)
3319 	{
3320 		failures += (resultPtr[0 * activeTlasCount + index] != 2) +
3321 					(resultPtr[1 * activeTlasCount + index] != 3) +
3322 					(resultPtr[2 * activeTlasCount + index] != 5) +
3323 					(resultPtr[3 * activeTlasCount + index] != 7);
3324 	}
3325 
3326 	if (failures)
3327 		return tcu::TestStatus::fail(de::toString(failures) + " failures, " + de::toString(4 * activeTlasCount - failures) + " are ok");
3328 	return tcu::TestStatus::pass("Pass");
3329 }
3330 
3331 }	// anonymous
3332 
3333 /********************/
3334 
addBasicBuildingTests(tcu::TestCaseGroup * group)3335 void addBasicBuildingTests(tcu::TestCaseGroup* group)
3336 {
3337 	struct ShaderSourceTypeData
3338 	{
3339 		ShaderSourceType						shaderSourceType;
3340 		ShaderSourcePipeline					shaderSourcePipeline;
3341 		const char*								name;
3342 	} shaderSourceTypes[] =
3343 	{
3344 		{ SST_FRAGMENT_SHADER,					SSP_GRAPHICS_PIPELINE,		"fragment_shader",			},
3345 		{ SST_COMPUTE_SHADER,					SSP_COMPUTE_PIPELINE,		"compute_shader",			},
3346 		{ SST_CLOSEST_HIT_SHADER,				SSP_RAY_TRACING_PIPELINE,	"chit_shader",				},
3347 	};
3348 
3349 	struct
3350 	{
3351 		vk::VkAccelerationStructureBuildTypeKHR	buildType;
3352 		const char*								name;
3353 	} buildTypes[] =
3354 	{
3355 		{ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR,				"cpu_built"	},
3356 		{ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,				"gpu_built"	},
3357 	};
3358 
3359 	struct
3360 	{
3361 		BottomTestType							testType;
3362 		bool									usesAOP;
3363 		const char*								name;
3364 	} bottomTestTypes[] =
3365 	{
3366 		{ BTT_TRIANGLES,	false,										"triangles" },
3367 		{ BTT_TRIANGLES,	true,										"triangles_aop" },
3368 		{ BTT_AABBS,		false,										"aabbs" },
3369 		{ BTT_AABBS,		true,										"aabbs_aop" },
3370 	};
3371 
3372 	struct
3373 	{
3374 		TopTestType								testType;
3375 		bool									usesAOP;
3376 		const char*								name;
3377 	} topTestTypes[] =
3378 	{
3379 		{ TTT_IDENTICAL_INSTANCES,	false,								"identical_instances" },
3380 		{ TTT_IDENTICAL_INSTANCES,	true,								"identical_instances_aop" },
3381 		{ TTT_DIFFERENT_INSTANCES,	false,								"different_instances" },
3382 		{ TTT_DIFFERENT_INSTANCES,	true,								"different_instances_aop" },
3383 	};
3384 
3385 	struct BuildFlagsData
3386 	{
3387 		VkBuildAccelerationStructureFlagsKHR	flags;
3388 		const char*								name;
3389 	};
3390 
3391 	BuildFlagsData optimizationTypes[] =
3392 	{
3393 		{ VkBuildAccelerationStructureFlagsKHR(0u),						"0" },
3394 		{ VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR,	"fasttrace" },
3395 		{ VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_KHR,	"fastbuild" },
3396 	};
3397 
3398 	BuildFlagsData updateTypes[] =
3399 	{
3400 		{ VkBuildAccelerationStructureFlagsKHR(0u),						"0" },
3401 		{ VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_UPDATE_BIT_KHR,			"update" },
3402 	};
3403 
3404 	BuildFlagsData compactionTypes[] =
3405 	{
3406 		{ VkBuildAccelerationStructureFlagsKHR(0u),						"0" },
3407 		{ VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_COMPACTION_BIT_KHR,		"compaction" },
3408 	};
3409 
3410 	BuildFlagsData lowMemoryTypes[] =
3411 	{
3412 		{ VkBuildAccelerationStructureFlagsKHR(0u),						"0" },
3413 		{ VK_BUILD_ACCELERATION_STRUCTURE_LOW_MEMORY_BIT_KHR,			"lowmemory" },
3414 	};
3415 
3416 	struct
3417 	{
3418 		bool		padVertices;
3419 		const char*	name;
3420 	} paddingType[] =
3421 	{
3422 		{ false,	"nopadding"	},
3423 		{ true,		"padded"	},
3424 	};
3425 
3426 	struct
3427 	{
3428 		bool		topGeneric;
3429 		bool		bottomGeneric;
3430 		const char*	suffix;
3431 	} createGenericParams[] =
3432 	{
3433 		{	false,	false,	""					},
3434 		{	false,	true,	"_bottomgeneric"	},
3435 		{	true,	false,	"_topgeneric"		},
3436 		{	true,	true,	"_bothgeneric"		},
3437 	};
3438 
3439 	for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
3440 	{
3441 		de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name, ""));
3442 
3443 		for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3444 		{
3445 			de::MovePtr<tcu::TestCaseGroup> buildGroup(new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name, ""));
3446 
3447 			for (size_t bottomNdx = 0; bottomNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++bottomNdx)
3448 			{
3449 				de::MovePtr<tcu::TestCaseGroup> bottomGroup(new tcu::TestCaseGroup(group->getTestContext(), bottomTestTypes[bottomNdx].name, ""));
3450 
3451 				for (size_t topNdx = 0; topNdx < DE_LENGTH_OF_ARRAY(topTestTypes); ++topNdx)
3452 				{
3453 					de::MovePtr<tcu::TestCaseGroup> topGroup(new tcu::TestCaseGroup(group->getTestContext(), topTestTypes[topNdx].name, ""));
3454 
3455 					for (int paddingTypeIdx = 0; paddingTypeIdx < DE_LENGTH_OF_ARRAY(paddingType); ++paddingTypeIdx)
3456 					{
3457 						de::MovePtr<tcu::TestCaseGroup> paddingTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), paddingType[paddingTypeIdx].name, ""));
3458 
3459 						for (size_t optimizationNdx = 0; optimizationNdx < DE_LENGTH_OF_ARRAY(optimizationTypes); ++optimizationNdx)
3460 						{
3461 							for (size_t updateNdx = 0; updateNdx < DE_LENGTH_OF_ARRAY(updateTypes); ++updateNdx)
3462 							{
3463 								for (size_t compactionNdx = 0; compactionNdx < DE_LENGTH_OF_ARRAY(compactionTypes); ++compactionNdx)
3464 								{
3465 									for (size_t lowMemoryNdx = 0; lowMemoryNdx < DE_LENGTH_OF_ARRAY(lowMemoryTypes); ++lowMemoryNdx)
3466 									{
3467 										for (int createGenericIdx = 0; createGenericIdx < DE_LENGTH_OF_ARRAY(createGenericParams); ++createGenericIdx)
3468 										{
3469 											std::string testName =
3470 												std::string(optimizationTypes[optimizationNdx].name) + "_" +
3471 												std::string(updateTypes[updateNdx].name) + "_" +
3472 												std::string(compactionTypes[compactionNdx].name) + "_" +
3473 												std::string(lowMemoryTypes[lowMemoryNdx].name) +
3474 												std::string(createGenericParams[createGenericIdx].suffix);
3475 
3476 											TestParams testParams
3477 											{
3478 												shaderSourceTypes[shaderSourceNdx].shaderSourceType,
3479 												shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
3480 												buildTypes[buildTypeNdx].buildType,
3481 												VK_FORMAT_R32G32B32_SFLOAT,
3482 												paddingType[paddingTypeIdx].padVertices,
3483 												VK_INDEX_TYPE_NONE_KHR,
3484 												bottomTestTypes[bottomNdx].testType,
3485 												InstanceCullFlags::NONE,
3486 												bottomTestTypes[bottomNdx].usesAOP,
3487 												createGenericParams[createGenericIdx].bottomGeneric,
3488 												topTestTypes[topNdx].testType,
3489 												topTestTypes[topNdx].usesAOP,
3490 												createGenericParams[createGenericIdx].topGeneric,
3491 												optimizationTypes[optimizationNdx].flags | updateTypes[updateNdx].flags | compactionTypes[compactionNdx].flags | lowMemoryTypes[lowMemoryNdx].flags,
3492 												OT_NONE,
3493 												OP_NONE,
3494 												TEST_WIDTH,
3495 												TEST_HEIGHT,
3496 												0u,
3497 												EmptyAccelerationStructureCase::NOT_EMPTY,
3498 											};
3499 											paddingTypeGroup->addChild(new RayQueryASBasicTestCase(group->getTestContext(), testName.c_str(), "", testParams));
3500 										}
3501 									}
3502 								}
3503 							}
3504 						}
3505 						topGroup->addChild(paddingTypeGroup.release());
3506 					}
3507 					bottomGroup->addChild(topGroup.release());
3508 				}
3509 				buildGroup->addChild(bottomGroup.release());
3510 			}
3511 			sourceTypeGroup->addChild(buildGroup.release());
3512 		}
3513 		group->addChild(sourceTypeGroup.release());
3514 	}
3515 }
3516 
addVertexIndexFormatsTests(tcu::TestCaseGroup * group)3517 void addVertexIndexFormatsTests(tcu::TestCaseGroup* group)
3518 {
3519 	struct ShaderSourceTypeData
3520 	{
3521 		ShaderSourceType						shaderSourceType;
3522 		ShaderSourcePipeline					shaderSourcePipeline;
3523 		const char*								name;
3524 	} shaderSourceTypes[] =
3525 	{
3526 		{ SST_VERTEX_SHADER,					SSP_GRAPHICS_PIPELINE,		"vertex_shader"				},
3527 		{ SST_TESSELATION_CONTROL_SHADER,		SSP_GRAPHICS_PIPELINE,		"tess_control_shader"		},
3528 		{ SST_TESSELATION_EVALUATION_SHADER,	SSP_GRAPHICS_PIPELINE,		"tess_evaluation_shader"	},
3529 		{ SST_GEOMETRY_SHADER,					SSP_GRAPHICS_PIPELINE,		"geometry_shader",			},
3530 		{ SST_FRAGMENT_SHADER,					SSP_GRAPHICS_PIPELINE,		"fragment_shader",			},
3531 		{ SST_COMPUTE_SHADER,					SSP_COMPUTE_PIPELINE,		"compute_shader",			},
3532 		{ SST_RAY_GENERATION_SHADER,			SSP_RAY_TRACING_PIPELINE,	"rgen_shader",				},
3533 		{ SST_INTERSECTION_SHADER,				SSP_RAY_TRACING_PIPELINE,	"isect_shader",				},
3534 		{ SST_ANY_HIT_SHADER,					SSP_RAY_TRACING_PIPELINE,	"ahit_shader",				},
3535 		{ SST_CLOSEST_HIT_SHADER,				SSP_RAY_TRACING_PIPELINE,	"chit_shader",				},
3536 		{ SST_MISS_SHADER,						SSP_RAY_TRACING_PIPELINE,	"miss_shader",				},
3537 		{ SST_CALLABLE_SHADER,					SSP_RAY_TRACING_PIPELINE,	"call_shader",				},
3538 	};
3539 
3540 	struct
3541 	{
3542 		vk::VkAccelerationStructureBuildTypeKHR				buildType;
3543 		const char*											name;
3544 	} buildTypes[] =
3545 	{
3546 		{ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR,	"cpu_built"	},
3547 		{ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,	"gpu_built"	},
3548 	};
3549 
3550 	const VkFormat vertexFormats[] =
3551 	{
3552 		// Mandatory formats.
3553 		VK_FORMAT_R32G32_SFLOAT,
3554 		VK_FORMAT_R32G32B32_SFLOAT,
3555 		VK_FORMAT_R16G16_SFLOAT,
3556 		VK_FORMAT_R16G16B16A16_SFLOAT,
3557 		VK_FORMAT_R16G16_SNORM,
3558 		VK_FORMAT_R16G16B16A16_SNORM,
3559 
3560 		// Additional formats.
3561 		VK_FORMAT_R8G8_SNORM,
3562 		VK_FORMAT_R8G8B8_SNORM,
3563 		VK_FORMAT_R8G8B8A8_SNORM,
3564 		VK_FORMAT_R16G16B16_SNORM,
3565 		VK_FORMAT_R16G16B16_SFLOAT,
3566 		VK_FORMAT_R32G32B32A32_SFLOAT,
3567 		VK_FORMAT_R64G64_SFLOAT,
3568 		VK_FORMAT_R64G64B64_SFLOAT,
3569 		VK_FORMAT_R64G64B64A64_SFLOAT,
3570 	};
3571 
3572 	struct
3573 	{
3574 		VkIndexType								indexType;
3575 		const char*								name;
3576 	} indexFormats[] =
3577 	{
3578 		{ VK_INDEX_TYPE_NONE_KHR ,				"index_none"	},
3579 		{ VK_INDEX_TYPE_UINT16 ,				"index_uint16"	},
3580 		{ VK_INDEX_TYPE_UINT32 ,				"index_uint32"	},
3581 	};
3582 
3583 	struct
3584 	{
3585 		bool		padVertices;
3586 		const char*	name;
3587 	} paddingType[] =
3588 	{
3589 		{ false,	"nopadding"	},
3590 		{ true,		"padded"	},
3591 	};
3592 
3593 	for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
3594 	{
3595 		de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name, ""));
3596 
3597 		for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3598 		{
3599 			de::MovePtr<tcu::TestCaseGroup> buildGroup(new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name, ""));
3600 
3601 			for (size_t vertexFormatNdx = 0; vertexFormatNdx < DE_LENGTH_OF_ARRAY(vertexFormats); ++vertexFormatNdx)
3602 			{
3603 				const auto format		= vertexFormats[vertexFormatNdx];
3604 				const auto formatName	= getFormatSimpleName(format);
3605 
3606 				de::MovePtr<tcu::TestCaseGroup> vertexFormatGroup(new tcu::TestCaseGroup(group->getTestContext(), formatName.c_str(), ""));
3607 
3608 				for (int paddingIdx = 0; paddingIdx < DE_LENGTH_OF_ARRAY(paddingType); ++paddingIdx)
3609 				{
3610 					de::MovePtr<tcu::TestCaseGroup> paddingGroup(new tcu::TestCaseGroup(group->getTestContext(), paddingType[paddingIdx].name, ""));
3611 
3612 					for (size_t indexFormatNdx = 0; indexFormatNdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatNdx)
3613 					{
3614 						TestParams testParams
3615 						{
3616 							shaderSourceTypes[shaderSourceNdx].shaderSourceType,
3617 							shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
3618 							buildTypes[buildTypeNdx].buildType,
3619 							format,
3620 							paddingType[paddingIdx].padVertices,
3621 							indexFormats[indexFormatNdx].indexType,
3622 							BTT_TRIANGLES,
3623 							InstanceCullFlags::NONE,
3624 							false,
3625 							false,
3626 							TTT_IDENTICAL_INSTANCES,
3627 							false,
3628 							false,
3629 							VkBuildAccelerationStructureFlagsKHR(0u),
3630 							OT_NONE,
3631 							OP_NONE,
3632 							TEST_WIDTH,
3633 							TEST_HEIGHT,
3634 							0u,
3635 							EmptyAccelerationStructureCase::NOT_EMPTY,
3636 						};
3637 						paddingGroup->addChild(new RayQueryASBasicTestCase(group->getTestContext(), indexFormats[indexFormatNdx].name, "", testParams));
3638 					}
3639 					vertexFormatGroup->addChild(paddingGroup.release());
3640 				}
3641 				buildGroup->addChild(vertexFormatGroup.release());
3642 			}
3643 			sourceTypeGroup->addChild(buildGroup.release());
3644 		}
3645 		group->addChild(sourceTypeGroup.release());
3646 	}
3647 }
3648 
addOperationTestsImpl(tcu::TestCaseGroup * group,const deUint32 workerThreads)3649 void addOperationTestsImpl (tcu::TestCaseGroup* group, const deUint32 workerThreads)
3650 {
3651 	struct ShaderSourceTypeData
3652 	{
3653 		ShaderSourceType						shaderSourceType;
3654 		ShaderSourcePipeline					shaderSourcePipeline;
3655 		const char*								name;
3656 	} shaderSourceTypes[] =
3657 	{
3658 		{ SST_VERTEX_SHADER,					SSP_GRAPHICS_PIPELINE,		"vertex_shader"				},
3659 		{ SST_TESSELATION_CONTROL_SHADER,		SSP_GRAPHICS_PIPELINE,		"tess_control_shader"		},
3660 		{ SST_TESSELATION_EVALUATION_SHADER,	SSP_GRAPHICS_PIPELINE,		"tess_evaluation_shader"	},
3661 		{ SST_GEOMETRY_SHADER,					SSP_GRAPHICS_PIPELINE,		"geometry_shader",			},
3662 		{ SST_FRAGMENT_SHADER,					SSP_GRAPHICS_PIPELINE,		"fragment_shader",			},
3663 		{ SST_COMPUTE_SHADER,					SSP_COMPUTE_PIPELINE,		"compute_shader",			},
3664 		{ SST_RAY_GENERATION_SHADER,			SSP_RAY_TRACING_PIPELINE,	"rgen_shader",				},
3665 		{ SST_INTERSECTION_SHADER,				SSP_RAY_TRACING_PIPELINE,	"isect_shader",				},
3666 		{ SST_ANY_HIT_SHADER,					SSP_RAY_TRACING_PIPELINE,	"ahit_shader",				},
3667 		{ SST_CLOSEST_HIT_SHADER,				SSP_RAY_TRACING_PIPELINE,	"chit_shader",				},
3668 		{ SST_MISS_SHADER,						SSP_RAY_TRACING_PIPELINE,	"miss_shader",				},
3669 		{ SST_CALLABLE_SHADER,					SSP_RAY_TRACING_PIPELINE,	"call_shader",				},
3670 	};
3671 
3672 	struct
3673 	{
3674 		OperationType										operationType;
3675 		const char*											name;
3676 	} operationTypes[] =
3677 	{
3678 		{ OP_COPY,											"copy"			},
3679 		{ OP_COMPACT,										"compaction"	},
3680 		{ OP_SERIALIZE,										"serialization"	},
3681 	};
3682 
3683 	struct
3684 	{
3685 		vk::VkAccelerationStructureBuildTypeKHR				buildType;
3686 		const char*											name;
3687 	} buildTypes[] =
3688 	{
3689 		{ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR,	"cpu_built"	},
3690 		{ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,	"gpu_built"	},
3691 	};
3692 
3693 	struct
3694 	{
3695 		OperationTarget										operationTarget;
3696 		const char*											name;
3697 	} operationTargets[] =
3698 	{
3699 		{ OT_TOP_ACCELERATION,								"top_acceleration_structure"		},
3700 		{ OT_BOTTOM_ACCELERATION,							"bottom_acceleration_structure"	},
3701 	};
3702 
3703 	struct
3704 	{
3705 		BottomTestType										testType;
3706 		const char*											name;
3707 	} bottomTestTypes[] =
3708 	{
3709 		{ BTT_TRIANGLES,									"triangles" },
3710 		{ BTT_AABBS,										"aabbs" },
3711 	};
3712 
3713 	for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
3714 	{
3715 		de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderSourceTypes[shaderSourceNdx].name, ""));
3716 
3717 		for (size_t operationTypeNdx = 0; operationTypeNdx < DE_LENGTH_OF_ARRAY(operationTypes); ++operationTypeNdx)
3718 		{
3719 			if (workerThreads > 0)
3720 				if (operationTypes[operationTypeNdx].operationType != OP_COPY && operationTypes[operationTypeNdx].operationType != OP_SERIALIZE)
3721 					continue;
3722 
3723 			de::MovePtr<tcu::TestCaseGroup> operationTypeGroup(new tcu::TestCaseGroup(group->getTestContext(), operationTypes[operationTypeNdx].name, ""));
3724 
3725 			for (size_t buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3726 			{
3727 				if (workerThreads > 0 && buildTypes[buildTypeNdx].buildType != VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR)
3728 					continue;
3729 
3730 				de::MovePtr<tcu::TestCaseGroup> buildGroup(new tcu::TestCaseGroup(group->getTestContext(), buildTypes[buildTypeNdx].name, ""));
3731 
3732 				for (size_t operationTargetNdx = 0; operationTargetNdx < DE_LENGTH_OF_ARRAY(operationTargets); ++operationTargetNdx)
3733 				{
3734 					de::MovePtr<tcu::TestCaseGroup> operationTargetGroup(new tcu::TestCaseGroup(group->getTestContext(), operationTargets[operationTargetNdx].name, ""));
3735 
3736 					for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(bottomTestTypes); ++testTypeNdx)
3737 					{
3738 						TopTestType topTest = (operationTargets[operationTargetNdx].operationTarget == OT_TOP_ACCELERATION) ? TTT_DIFFERENT_INSTANCES : TTT_IDENTICAL_INSTANCES;
3739 
3740 						TestParams testParams
3741 						{
3742 							shaderSourceTypes[shaderSourceNdx].shaderSourceType,
3743 							shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
3744 							buildTypes[buildTypeNdx].buildType,
3745 							VK_FORMAT_R32G32B32_SFLOAT,
3746 							false,
3747 							VK_INDEX_TYPE_NONE_KHR,
3748 							bottomTestTypes[testTypeNdx].testType,
3749 							InstanceCullFlags::NONE,
3750 							false,
3751 							false,
3752 							topTest,
3753 							false,
3754 							false,
3755 							VkBuildAccelerationStructureFlagsKHR(0u),
3756 							operationTargets[operationTargetNdx].operationTarget,
3757 							operationTypes[operationTypeNdx].operationType,
3758 							TEST_WIDTH,
3759 							TEST_HEIGHT,
3760 							workerThreads,
3761 							EmptyAccelerationStructureCase::NOT_EMPTY,
3762 						};
3763 						operationTargetGroup->addChild(new RayQueryASBasicTestCase(group->getTestContext(), bottomTestTypes[testTypeNdx].name, "", testParams));
3764 					}
3765 					buildGroup->addChild(operationTargetGroup.release());
3766 				}
3767 				operationTypeGroup->addChild(buildGroup.release());
3768 			}
3769 			sourceTypeGroup->addChild(operationTypeGroup.release());
3770 		}
3771 		group->addChild(sourceTypeGroup.release());
3772 	}
3773 }
3774 
addOperationTests(tcu::TestCaseGroup * group)3775 void addOperationTests (tcu::TestCaseGroup* group)
3776 {
3777 	addOperationTestsImpl(group, 0);
3778 }
3779 
addHostThreadingOperationTests(tcu::TestCaseGroup * group)3780 void addHostThreadingOperationTests (tcu::TestCaseGroup* group)
3781 {
3782 	const deUint32	threads[]	= { 1, 2, 3, 4, 8, std::numeric_limits<deUint32>::max() };
3783 
3784 	for (size_t threadsNdx = 0; threadsNdx < DE_LENGTH_OF_ARRAY(threads); ++threadsNdx)
3785 	{
3786 		const std::string groupName = threads[threadsNdx] != std::numeric_limits<deUint32>::max()
3787 									? de::toString(threads[threadsNdx])
3788 									: "max";
3789 
3790 		de::MovePtr<tcu::TestCaseGroup> threadGroup(new tcu::TestCaseGroup(group->getTestContext(), groupName.c_str(), ""));
3791 
3792 		addOperationTestsImpl(threadGroup.get(), threads[threadsNdx]);
3793 
3794 		group->addChild(threadGroup.release());
3795 	}
3796 }
3797 
addFuncArgTests(tcu::TestCaseGroup * group)3798 void addFuncArgTests (tcu::TestCaseGroup* group)
3799 {
3800 	const struct
3801 	{
3802 		vk::VkAccelerationStructureBuildTypeKHR				buildType;
3803 		const char*											name;
3804 	} buildTypes[] =
3805 	{
3806 		{ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR,	"cpu_built"	},
3807 		{ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,	"gpu_built"	},
3808 	};
3809 
3810 	auto& ctx = group->getTestContext();
3811 
3812 	for (int buildTypeNdx = 0; buildTypeNdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeNdx)
3813 	{
3814 		TestParams testParams
3815 		{
3816 			SST_COMPUTE_SHADER,
3817 			SSP_COMPUTE_PIPELINE,
3818 			buildTypes[buildTypeNdx].buildType,
3819 			VK_FORMAT_R32G32B32_SFLOAT,
3820 			false,
3821 			VK_INDEX_TYPE_NONE_KHR,
3822 			BTT_TRIANGLES,
3823 			InstanceCullFlags::NONE,
3824 			false,
3825 			false,
3826 			TTT_IDENTICAL_INSTANCES,
3827 			false,
3828 			false,
3829 			VkBuildAccelerationStructureFlagsKHR(0u),
3830 			OT_NONE,
3831 			OP_NONE,
3832 			TEST_WIDTH,
3833 			TEST_HEIGHT,
3834 			0u,
3835 			EmptyAccelerationStructureCase::NOT_EMPTY,
3836 		};
3837 
3838 		group->addChild(new RayQueryASFuncArgTestCase(ctx, buildTypes[buildTypeNdx].name, "", testParams));
3839 	}
3840 }
3841 
addInstanceTriangleCullingTests(tcu::TestCaseGroup * group)3842 void addInstanceTriangleCullingTests (tcu::TestCaseGroup* group)
3843 {
3844 	const struct
3845 	{
3846 		ShaderSourceType						shaderSourceType;
3847 		ShaderSourcePipeline					shaderSourcePipeline;
3848 		std::string								name;
3849 	} shaderSourceTypes[] =
3850 	{
3851 		{ SST_VERTEX_SHADER,					SSP_GRAPHICS_PIPELINE,		"vertex_shader"				},
3852 		{ SST_TESSELATION_CONTROL_SHADER,		SSP_GRAPHICS_PIPELINE,		"tess_control_shader"		},
3853 		{ SST_TESSELATION_EVALUATION_SHADER,	SSP_GRAPHICS_PIPELINE,		"tess_evaluation_shader"	},
3854 		{ SST_GEOMETRY_SHADER,					SSP_GRAPHICS_PIPELINE,		"geometry_shader",			},
3855 		{ SST_FRAGMENT_SHADER,					SSP_GRAPHICS_PIPELINE,		"fragment_shader",			},
3856 		{ SST_COMPUTE_SHADER,					SSP_COMPUTE_PIPELINE,		"compute_shader",			},
3857 		{ SST_RAY_GENERATION_SHADER,			SSP_RAY_TRACING_PIPELINE,	"rgen_shader",				},
3858 		{ SST_INTERSECTION_SHADER,				SSP_RAY_TRACING_PIPELINE,	"isect_shader",				},
3859 		{ SST_ANY_HIT_SHADER,					SSP_RAY_TRACING_PIPELINE,	"ahit_shader",				},
3860 		{ SST_CLOSEST_HIT_SHADER,				SSP_RAY_TRACING_PIPELINE,	"chit_shader",				},
3861 		{ SST_MISS_SHADER,						SSP_RAY_TRACING_PIPELINE,	"miss_shader",				},
3862 		{ SST_CALLABLE_SHADER,					SSP_RAY_TRACING_PIPELINE,	"call_shader",				},
3863 	};
3864 
3865 	const struct
3866 	{
3867 		InstanceCullFlags	cullFlags;
3868 		std::string			name;
3869 	} cullFlags[] =
3870 	{
3871 		{ InstanceCullFlags::NONE,				"noflags"		},
3872 		{ InstanceCullFlags::COUNTERCLOCKWISE,	"ccw"			},
3873 		{ InstanceCullFlags::CULL_DISABLE,		"nocull"		},
3874 		{ InstanceCullFlags::ALL,				"ccw_nocull"	},
3875 	};
3876 
3877 	const struct
3878 	{
3879 		TopTestType	topType;
3880 		std::string	name;
3881 	} topType[] =
3882 	{
3883 		{ TTT_DIFFERENT_INSTANCES, "transformed"	},	// Each instance has its own transformation matrix.
3884 		{ TTT_IDENTICAL_INSTANCES, "notransform"	},	// "Identical" instances, different geometries.
3885 	};
3886 
3887 	const struct
3888 	{
3889 		vk::VkAccelerationStructureBuildTypeKHR	buildType;
3890 		std::string								name;
3891 	} buildTypes[] =
3892 	{
3893 		{ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR,	"cpu_built"	},
3894 		{ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,	"gpu_built"	},
3895 	};
3896 
3897 	const struct
3898 	{
3899 		VkIndexType	indexType;
3900 		std::string	name;
3901 	} indexFormats[] =
3902 	{
3903 		{ VK_INDEX_TYPE_NONE_KHR ,	"index_none"	},
3904 		{ VK_INDEX_TYPE_UINT16 ,	"index_uint16"	},
3905 		{ VK_INDEX_TYPE_UINT32 ,	"index_uint32"	},
3906 	};
3907 
3908 	auto& ctx = group->getTestContext();
3909 
3910 	for (int shaderSourceIdx = 0; shaderSourceIdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceIdx)
3911 	{
3912 		de::MovePtr<tcu::TestCaseGroup> shaderSourceGroup(new tcu::TestCaseGroup(ctx, shaderSourceTypes[shaderSourceIdx].name.c_str(), ""));
3913 
3914 		for (int buildTypeIdx = 0; buildTypeIdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeIdx)
3915 		{
3916 			de::MovePtr<tcu::TestCaseGroup> buildTypeGroup(new tcu::TestCaseGroup(ctx, buildTypes[buildTypeIdx].name.c_str(), ""));
3917 
3918 			for (int indexFormatIdx = 0; indexFormatIdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatIdx)
3919 			{
3920 				de::MovePtr<tcu::TestCaseGroup> indexTypeGroup(new tcu::TestCaseGroup(ctx, indexFormats[indexFormatIdx].name.c_str(), ""));
3921 
3922 				for (int topTypeIdx = 0; topTypeIdx < DE_LENGTH_OF_ARRAY(topType); ++topTypeIdx)
3923 				{
3924 					for (int cullFlagsIdx = 0; cullFlagsIdx < DE_LENGTH_OF_ARRAY(cullFlags); ++cullFlagsIdx)
3925 					{
3926 						const std::string testName = topType[topTypeIdx].name + "_" + cullFlags[cullFlagsIdx].name;
3927 
3928 						TestParams testParams
3929 						{
3930 							shaderSourceTypes[shaderSourceIdx].shaderSourceType,
3931 							shaderSourceTypes[shaderSourceIdx].shaderSourcePipeline,
3932 							buildTypes[buildTypeIdx].buildType,
3933 							VK_FORMAT_R32G32B32_SFLOAT,
3934 							false,
3935 							indexFormats[indexFormatIdx].indexType,
3936 							BTT_TRIANGLES,
3937 							cullFlags[cullFlagsIdx].cullFlags,
3938 							false,
3939 							false,
3940 							topType[topTypeIdx].topType,
3941 							false,
3942 							false,
3943 							VkBuildAccelerationStructureFlagsKHR(0u),
3944 							OT_NONE,
3945 							OP_NONE,
3946 							TEST_WIDTH,
3947 							TEST_HEIGHT,
3948 							0u,
3949 							EmptyAccelerationStructureCase::NOT_EMPTY,
3950 						};
3951 						indexTypeGroup->addChild(new RayQueryASBasicTestCase(ctx, testName.c_str(), "", testParams));
3952 					}
3953 				}
3954 				buildTypeGroup->addChild(indexTypeGroup.release());
3955 			}
3956 			shaderSourceGroup->addChild(buildTypeGroup.release());
3957 		}
3958 		group->addChild(shaderSourceGroup.release());
3959 	}
3960 }
3961 
addDynamicIndexingTests(tcu::TestCaseGroup * group)3962 void addDynamicIndexingTests(tcu::TestCaseGroup* group)
3963 {
3964 	auto& ctx = group->getTestContext();
3965 	group->addChild(new RayQueryASDynamicIndexingTestCase(ctx, "dynamic_indexing"));
3966 }
3967 
addEmptyAccelerationStructureTests(tcu::TestCaseGroup * group)3968 void addEmptyAccelerationStructureTests (tcu::TestCaseGroup* group)
3969 {
3970 	const struct
3971 	{
3972 		ShaderSourceType						shaderSourceType;
3973 		ShaderSourcePipeline					shaderSourcePipeline;
3974 		std::string								name;
3975 	} shaderSourceTypes[] =
3976 	{
3977 		{ SST_VERTEX_SHADER,					SSP_GRAPHICS_PIPELINE,		"vertex_shader"				},
3978 		{ SST_TESSELATION_CONTROL_SHADER,		SSP_GRAPHICS_PIPELINE,		"tess_control_shader"		},
3979 		{ SST_TESSELATION_EVALUATION_SHADER,	SSP_GRAPHICS_PIPELINE,		"tess_evaluation_shader"	},
3980 		{ SST_GEOMETRY_SHADER,					SSP_GRAPHICS_PIPELINE,		"geometry_shader",			},
3981 		{ SST_FRAGMENT_SHADER,					SSP_GRAPHICS_PIPELINE,		"fragment_shader",			},
3982 		{ SST_COMPUTE_SHADER,					SSP_COMPUTE_PIPELINE,		"compute_shader",			},
3983 		{ SST_RAY_GENERATION_SHADER,			SSP_RAY_TRACING_PIPELINE,	"rgen_shader",				},
3984 		{ SST_INTERSECTION_SHADER,				SSP_RAY_TRACING_PIPELINE,	"isect_shader",				},
3985 		{ SST_ANY_HIT_SHADER,					SSP_RAY_TRACING_PIPELINE,	"ahit_shader",				},
3986 		{ SST_CLOSEST_HIT_SHADER,				SSP_RAY_TRACING_PIPELINE,	"chit_shader",				},
3987 		{ SST_MISS_SHADER,						SSP_RAY_TRACING_PIPELINE,	"miss_shader",				},
3988 		{ SST_CALLABLE_SHADER,					SSP_RAY_TRACING_PIPELINE,	"call_shader",				},
3989 	};
3990 
3991 	const struct
3992 	{
3993 		vk::VkAccelerationStructureBuildTypeKHR				buildType;
3994 		std::string											name;
3995 	} buildTypes[] =
3996 	{
3997 		{ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR,	"cpu_built"	},
3998 		{ VK_ACCELERATION_STRUCTURE_BUILD_TYPE_DEVICE_KHR,	"gpu_built"	},
3999 	};
4000 
4001 	const struct
4002 	{
4003 		VkIndexType								indexType;
4004 		std::string								name;
4005 	} indexFormats[] =
4006 	{
4007 		{ VK_INDEX_TYPE_NONE_KHR ,				"index_none"		},
4008 		{ VK_INDEX_TYPE_UINT16 ,				"index_uint16"	},
4009 		{ VK_INDEX_TYPE_UINT32 ,				"index_uint32"	},
4010 	};
4011 
4012 	const struct
4013 	{
4014 		EmptyAccelerationStructureCase	emptyASCase;
4015 		std::string						name;
4016 	} emptyCases[] =
4017 	{
4018 		{ EmptyAccelerationStructureCase::INACTIVE_TRIANGLES,	"inactive_triangles"	},
4019 		{ EmptyAccelerationStructureCase::INACTIVE_INSTANCES,	"inactive_instances"	},
4020 		{ EmptyAccelerationStructureCase::NO_GEOMETRIES_BOTTOM,	"no_geometries_bottom"	},
4021 		{ EmptyAccelerationStructureCase::NO_PRIMITIVES_TOP,	"no_primitives_top"		},
4022 		{ EmptyAccelerationStructureCase::NO_PRIMITIVES_BOTTOM,	"no_primitives_bottom"	},
4023 	};
4024 
4025 	auto& ctx = group->getTestContext();
4026 
4027 	for (size_t shaderSourceNdx = 0; shaderSourceNdx < DE_LENGTH_OF_ARRAY(shaderSourceTypes); ++shaderSourceNdx)
4028 	{
4029 		de::MovePtr<tcu::TestCaseGroup> sourceTypeGroup(new tcu::TestCaseGroup(ctx, shaderSourceTypes[shaderSourceNdx].name.c_str(), ""));
4030 
4031 		for (int buildTypeIdx = 0; buildTypeIdx < DE_LENGTH_OF_ARRAY(buildTypes); ++buildTypeIdx)
4032 		{
4033 			de::MovePtr<tcu::TestCaseGroup> buildTypeGroup(new tcu::TestCaseGroup(ctx, buildTypes[buildTypeIdx].name.c_str(), ""));
4034 
4035 			for (int indexFormatIdx = 0; indexFormatIdx < DE_LENGTH_OF_ARRAY(indexFormats); ++indexFormatIdx)
4036 			{
4037 				de::MovePtr<tcu::TestCaseGroup> indexTypeGroup(new tcu::TestCaseGroup(ctx, indexFormats[indexFormatIdx].name.c_str(), ""));
4038 
4039 				for (int emptyCaseIdx = 0; emptyCaseIdx < DE_LENGTH_OF_ARRAY(emptyCases); ++emptyCaseIdx)
4040 				{
4041 							TestParams testParams
4042 							{
4043 								shaderSourceTypes[shaderSourceNdx].shaderSourceType,
4044 								shaderSourceTypes[shaderSourceNdx].shaderSourcePipeline,
4045 								buildTypes[buildTypeIdx].buildType,
4046 								VK_FORMAT_R32G32B32_SFLOAT,
4047 								false,
4048 								indexFormats[indexFormatIdx].indexType,
4049 								BTT_TRIANGLES,
4050 								InstanceCullFlags::NONE,
4051 								false,
4052 								false,
4053 								TTT_IDENTICAL_INSTANCES,
4054 								false,
4055 								false,
4056 								VkBuildAccelerationStructureFlagsKHR(0u),
4057 								OT_NONE,
4058 								OP_NONE,
4059 								TEST_WIDTH,
4060 								TEST_HEIGHT,
4061 								0u,
4062 								emptyCases[emptyCaseIdx].emptyASCase,
4063 							};
4064 					indexTypeGroup->addChild(new RayQueryASBasicTestCase(ctx, emptyCases[emptyCaseIdx].name.c_str(), "", testParams));
4065 				}
4066 				buildTypeGroup->addChild(indexTypeGroup.release());
4067 			}
4068 			sourceTypeGroup->addChild(buildTypeGroup.release());
4069 		}
4070 		group->addChild(sourceTypeGroup.release());
4071 	}
4072 }
4073 
createAccelerationStructuresTests(tcu::TestContext & testCtx)4074 tcu::TestCaseGroup*	createAccelerationStructuresTests(tcu::TestContext& testCtx)
4075 {
4076 	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "acceleration_structures", "Acceleration structure tests using rayQuery feature"));
4077 
4078 	addTestGroup(group.get(), "flags", "Test building AS with different build types, build flags and geometries/instances using arrays or arrays of pointers", addBasicBuildingTests);
4079 	addTestGroup(group.get(), "format", "Test building AS with different vertex and index formats", addVertexIndexFormatsTests);
4080 	addTestGroup(group.get(), "operations", "Test copying, compaction and serialization of AS", addOperationTests);
4081 	addTestGroup(group.get(), "host_threading", "Test host threading operations", addHostThreadingOperationTests);
4082 	addTestGroup(group.get(), "function_argument", "Test using AS as function argument using both pointers and bare values", addFuncArgTests);
4083 	addTestGroup(group.get(), "instance_triangle_culling", "Test building AS with counterclockwise triangles and/or disabling face culling", addInstanceTriangleCullingTests);
4084 	addTestGroup(group.get(), "dynamic_indexing", "Exercise dynamic indexing of acceleration structures", addDynamicIndexingTests);
4085 	addTestGroup(group.get(), "empty", "Test building empty acceleration structures using different methods", addEmptyAccelerationStructureTests);
4086 
4087 	return group.release();
4088 }
4089 
4090 }	// RayQuery
4091 
4092 }	// vkt
4093