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