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