• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2021 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 Acceleration Structure binding tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktBindingDescriptorUpdateASTests.hpp"
25 
26 #include "vkDefs.hpp"
27 
28 #include "vktTestCase.hpp"
29 #include "vktTestGroupUtil.hpp"
30 #include "vkCmdUtil.hpp"
31 #include "vkObjUtil.hpp"
32 #include "vkBuilderUtil.hpp"
33 #include "vkBarrierUtil.hpp"
34 #include "vkBufferWithMemory.hpp"
35 #include "vkImageWithMemory.hpp"
36 #include "vkTypeUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "deRandom.hpp"
39 #include "tcuTexture.hpp"
40 #include "tcuTextureUtil.hpp"
41 #include "tcuTestLog.hpp"
42 #include "tcuImageCompare.hpp"
43 #include "tcuCommandLine.hpp"
44 
45 #include "vkRayTracingUtil.hpp"
46 
47 namespace vkt
48 {
49 namespace BindingModel
50 {
51 namespace
52 {
53 using namespace vk;
54 using namespace vkt;
55 
56 static const VkFlags	ALL_RAY_TRACING_STAGES	= VK_SHADER_STAGE_RAYGEN_BIT_KHR
57 												| VK_SHADER_STAGE_ANY_HIT_BIT_KHR
58 												| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
59 												| VK_SHADER_STAGE_MISS_BIT_KHR
60 												| VK_SHADER_STAGE_INTERSECTION_BIT_KHR
61 												| VK_SHADER_STAGE_CALLABLE_BIT_KHR;
62 
63 enum TestType
64 {
65 	TEST_TYPE_USING_RAY_QUERY		= 0,
66 	TEST_TYPE_USING_RAY_TRACING,
67 };
68 
69 enum UpdateMethod
70 {
71 	UPDATE_METHOD_NORMAL = 0,			//!< use vkUpdateDescriptorSets				vkUpdateDescriptorSets
72 	UPDATE_METHOD_WITH_TEMPLATE,		//!< use descriptor update templates		vkUpdateDescriptorSetWithTemplate
73 	UPDATE_METHOD_WITH_PUSH,			//!< use push descriptor updates			vkCmdPushDescriptorSetKHR
74 	UPDATE_METHOD_WITH_PUSH_TEMPLATE,	//!< use push descriptor update templates	vkCmdPushDescriptorSetWithTemplateKHR
75 
76 	UPDATE_METHOD_LAST
77 };
78 
79 const deUint32	TEST_WIDTH			= 16u;
80 const deUint32	TEST_HEIGHT			= 16u;
81 const deUint32	FIXED_POINT_DIVISOR	= 1024 * 1024;
82 const float		PLAIN_Z0			= 2.0f;
83 const float		PLAIN_Z1			= 4.0f;
84 
85 struct TestParams;
86 
87 typedef void (*CheckSupportFunc)(Context& context, const TestParams& testParams);
88 typedef void (*InitProgramsFunc)(SourceCollections& programCollection, const TestParams& testParams);
89 typedef const std::string (*ShaderBodyTextFunc)(const TestParams& testParams);
90 
91 struct TestParams
92 {
93 	deUint32				width;
94 	deUint32				height;
95 	deUint32				depth;
96 	TestType				testType;
97 	UpdateMethod			updateMethod;
98 	VkShaderStageFlagBits	stage;
99 	VkFormat				format;
100 	CheckSupportFunc		pipelineCheckSupport;
101 	InitProgramsFunc		pipelineInitPrograms;
102 	ShaderBodyTextFunc		testConfigShaderBodyText;
103 };
104 
105 
getShaderGroupHandleSize(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)106 static deUint32 getShaderGroupHandleSize (const InstanceInterface&	vki,
107 										  const VkPhysicalDevice	physicalDevice)
108 {
109 	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
110 
111 	rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physicalDevice);
112 
113 	return rayTracingPropertiesKHR->getShaderGroupHandleSize();
114 }
115 
getShaderGroupBaseAlignment(const InstanceInterface & vki,const VkPhysicalDevice physicalDevice)116 static deUint32 getShaderGroupBaseAlignment (const InstanceInterface&	vki,
117 											 const VkPhysicalDevice		physicalDevice)
118 {
119 	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
120 
121 	rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
122 
123 	return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
124 }
125 
getVkBuffer(const de::MovePtr<BufferWithMemory> & buffer)126 static VkBuffer getVkBuffer (const de::MovePtr<BufferWithMemory>& buffer)
127 {
128 	VkBuffer result = (buffer.get() == DE_NULL) ? DE_NULL : buffer->get();
129 
130 	return result;
131 }
132 
makeStridedDeviceAddressRegion(const DeviceInterface & vkd,const VkDevice device,VkBuffer buffer,deUint32 stride,deUint32 count)133 static VkStridedDeviceAddressRegionKHR makeStridedDeviceAddressRegion (const DeviceInterface& vkd, const VkDevice device, VkBuffer buffer, deUint32 stride, deUint32 count)
134 {
135 	if (buffer == DE_NULL)
136 	{
137 		return makeStridedDeviceAddressRegionKHR(0, 0, 0);
138 	}
139 	else
140 	{
141 		return makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, buffer, 0), stride, stride * count);
142 	}
143 }
144 
makePipelineLayout(const DeviceInterface & vk,const VkDevice device,const VkDescriptorSetLayout descriptorSetLayout0,const VkDescriptorSetLayout descriptorSetLayout1,const VkDescriptorSetLayout descriptorSetLayoutOpt=DE_NULL)145 static Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&		vk,
146 												  const VkDevice				device,
147 												  const VkDescriptorSetLayout	descriptorSetLayout0,
148 												  const VkDescriptorSetLayout	descriptorSetLayout1,
149 												  const VkDescriptorSetLayout	descriptorSetLayoutOpt = DE_NULL)
150 {
151 	std::vector<VkDescriptorSetLayout> descriptorSetLayouts;
152 
153 	descriptorSetLayouts.push_back(descriptorSetLayout0);
154 	descriptorSetLayouts.push_back(descriptorSetLayout1);
155 
156 	if (descriptorSetLayoutOpt != DE_NULL)
157 		descriptorSetLayouts.push_back(descriptorSetLayoutOpt);
158 
159 	return makePipelineLayout(vk, device, (deUint32)descriptorSetLayouts.size(), descriptorSetLayouts.data());
160 }
161 
makeWriteDescriptorSetAccelerationStructureKHR(const VkAccelerationStructureKHR * accelerationStructureKHR)162 static VkWriteDescriptorSetAccelerationStructureKHR makeWriteDescriptorSetAccelerationStructureKHR (const VkAccelerationStructureKHR* accelerationStructureKHR)
163 {
164 	const VkWriteDescriptorSetAccelerationStructureKHR	result	=
165 	{
166 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
167 		DE_NULL,															//  const void*							pNext;
168 		1u,																	//  deUint32							accelerationStructureCount;
169 		accelerationStructureKHR											//  const VkAccelerationStructureKHR*	pAccelerationStructures;
170 	};
171 
172 	return result;
173 }
174 
isPushUpdateMethod(const UpdateMethod updateMethod)175 static bool isPushUpdateMethod (const UpdateMethod	updateMethod)
176 {
177 	switch (updateMethod)
178 	{
179 		case UPDATE_METHOD_NORMAL:				return false;
180 		case UPDATE_METHOD_WITH_TEMPLATE:		return false;
181 		case UPDATE_METHOD_WITH_PUSH:			return true;
182 		case UPDATE_METHOD_WITH_PUSH_TEMPLATE:	return true;
183 		default: TCU_THROW(InternalError, "Unknown update method");
184 	}
185 }
186 
isTemplateUpdateMethod(const UpdateMethod updateMethod)187 static bool isTemplateUpdateMethod (const UpdateMethod	updateMethod)
188 {
189 	switch (updateMethod)
190 	{
191 		case UPDATE_METHOD_NORMAL:				return false;
192 		case UPDATE_METHOD_WITH_TEMPLATE:		return true;
193 		case UPDATE_METHOD_WITH_PUSH:			return false;
194 		case UPDATE_METHOD_WITH_PUSH_TEMPLATE:	return true;
195 		default: TCU_THROW(InternalError, "Unknown update method");
196 	}
197 }
198 
makeDescriptorSet(const DeviceInterface & vki,const VkDevice device,const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout,UpdateMethod updateMethod)199 static Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&		vki,
200 												const VkDevice				device,
201 												const VkDescriptorPool		descriptorPool,
202 												const VkDescriptorSetLayout	setLayout,
203 												UpdateMethod				updateMethod)
204 {
205 	const bool				pushUpdateMethod	= isPushUpdateMethod(updateMethod);
206 	Move<VkDescriptorSet>	descriptorSet		= pushUpdateMethod
207 												? vk::Move<vk::VkDescriptorSet>()
208 												: vk::makeDescriptorSet(vki, device, descriptorPool, setLayout, DE_NULL);
209 
210 	return descriptorSet;
211 }
212 
makeImageCreateInfo(VkFormat format,deUint32 width,deUint32 height,deUint32 depth,VkImageType imageType=VK_IMAGE_TYPE_3D,VkImageUsageFlags usageFlags=VK_IMAGE_USAGE_STORAGE_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT)213 static VkImageCreateInfo makeImageCreateInfo (VkFormat			format,
214 											  deUint32			width,
215 											  deUint32			height,
216 											  deUint32			depth,
217 											  VkImageType		imageType	= VK_IMAGE_TYPE_3D,
218 											  VkImageUsageFlags	usageFlags	= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
219 {
220 	const VkImageCreateInfo	imageCreateInfo	=
221 	{
222 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType;
223 		DE_NULL,								// const void*				pNext;
224 		(VkImageCreateFlags)0u,					// VkImageCreateFlags		flags;
225 		imageType,								// VkImageType				imageType;
226 		format,									// VkFormat					format;
227 		makeExtent3D(width, height, depth),		// VkExtent3D				extent;
228 		1u,										// deUint32					mipLevels;
229 		1u,										// deUint32					arrayLayers;
230 		VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples;
231 		VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling;
232 		usageFlags,								// VkImageUsageFlags		usage;
233 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode;
234 		0u,										// deUint32					queueFamilyIndexCount;
235 		DE_NULL,								// const deUint32*			pQueueFamilyIndices;
236 		VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout;
237 	};
238 
239 	return imageCreateInfo;
240 }
241 
makeComputePipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkShaderModule shaderModule)242 static Move<VkPipeline> makeComputePipeline (const DeviceInterface&		vk,
243 											 const VkDevice				device,
244 											 const VkPipelineLayout		pipelineLayout,
245 											 const VkShaderModule		shaderModule)
246 {
247 	const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
248 	{
249 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
250 		DE_NULL,												// const void*							pNext;
251 		0u,														// VkPipelineShaderStageCreateFlags		flags;
252 		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
253 		shaderModule,											// VkShaderModule						module;
254 		"main",													// const char*							pName;
255 		DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
256 	};
257 	const VkComputePipelineCreateInfo pipelineCreateInfo =
258 	{
259 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
260 		DE_NULL,											// const void*						pNext;
261 		0u,													// VkPipelineCreateFlags			flags;
262 		pipelineShaderStageParams,							// VkPipelineShaderStageCreateInfo	stage;
263 		pipelineLayout,										// VkPipelineLayout					layout;
264 		DE_NULL,											// VkPipeline						basePipelineHandle;
265 		0,													// deInt32							basePipelineIndex;
266 	};
267 
268 	return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo);
269 }
270 
getMissPassthrough(void)271 static const std::string getMissPassthrough (void)
272 {
273 	std::ostringstream src;
274 
275 	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
276 		<< "#extension GL_EXT_ray_tracing : require\n"
277 		<< "\n"
278 		<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
279 		<< "\n"
280 		<< "void main()\n"
281 		<< "{\n"
282 		<< "}\n";
283 
284 	return src.str();
285 }
286 
getHitPassthrough(void)287 static const std::string getHitPassthrough (void)
288 {
289 	std::ostringstream src;
290 
291 	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
292 		<< "#extension GL_EXT_ray_tracing : require\n"
293 		<< "hitAttributeEXT vec3 attribs;\n"
294 		<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
295 		<< "\n"
296 		<< "void main()\n"
297 		<< "{\n"
298 		<< "}\n";
299 
300 	return src.str();
301 }
302 
getGraphicsPassthrough(void)303 static const std::string getGraphicsPassthrough (void)
304 {
305 	std::ostringstream src;
306 
307 	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
308 		<< "\n"
309 		<< "void main(void)\n"
310 		<< "{\n"
311 		<< "}\n";
312 
313 	return src.str();
314 }
315 
getVertexPassthrough(void)316 static const std::string getVertexPassthrough (void)
317 {
318 	std::ostringstream src;
319 
320 	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
321 		<< "\n"
322 		<< "layout(location = 0) in vec4 in_position;\n"
323 		<< "\n"
324 		<< "void main(void)\n"
325 		<< "{\n"
326 		<< "  gl_Position = in_position;\n"
327 		<< "}\n";
328 
329 	return src.str();
330 }
331 
getDescriptorSetLayoutCreateFlags(const UpdateMethod updateMethod)332 static VkDescriptorSetLayoutCreateFlags getDescriptorSetLayoutCreateFlags(const UpdateMethod updateMethod)
333 {
334 	vk::VkDescriptorSetLayoutCreateFlags	extraFlags	= 0;
335 
336 	if (updateMethod == UPDATE_METHOD_WITH_PUSH_TEMPLATE || updateMethod == UPDATE_METHOD_WITH_PUSH)
337 	{
338 		extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
339 	}
340 
341 	return extraFlags;
342 }
343 
344 class BindingAcceleratioStructureTestInstance : public TestInstance
345 {
346 public:
347 																	BindingAcceleratioStructureTestInstance		(Context&			context,
348 																												 const TestParams&	testParams);
~BindingAcceleratioStructureTestInstance()349 	virtual															~BindingAcceleratioStructureTestInstance	() {}
350 	virtual tcu::TestStatus											iterate										(void);
351 
352 protected:
353 	virtual void													initPipeline								(void) = 0;
354 	virtual deUint32												getExtraAccelerationDescriptorCount			(void) = 0;
355 	virtual VkShaderStageFlags										getShaderStageFlags							(void) = 0;
356 	virtual VkPipelineBindPoint										getPipelineBindPoint						(void) = 0;
357 
358 	virtual void													fillCommandBuffer							(VkCommandBuffer	commandBuffer) = 0;
359 
360 	virtual const	VkAccelerationStructureKHR*						createAccelerationStructures				(Context&			context,
361 																												 TestParams&		testParams);
362 	virtual void													buildAccelerationStructures					(Context&			context,
363 																												 TestParams&		testParams,
364 																												 VkCommandBuffer	commandBuffer);
365 	virtual bool													verify										(BufferWithMemory*	resultBuffer,
366 																												 Context&			context,
367 																												 TestParams&		testParams);
368 
369 	TestParams														m_testParams;
370 
371 	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	m_bottomAccelerationStructures;
372 	de::SharedPtr<TopLevelAccelerationStructure>					m_topAccelerationStructure;
373 
374 	Move<VkDescriptorPool>											m_descriptorPool;
375 
376 	Move<VkDescriptorSetLayout>										m_descriptorSetLayoutImg;
377 	Move<VkDescriptorSet>											m_descriptorSetImg;
378 
379 	Move<VkDescriptorSetLayout>										m_descriptorSetLayoutAS;
380 	Move<VkDescriptorSet>											m_descriptorSetAS;
381 
382 	Move<VkPipelineLayout>											m_pipelineLayout;
383 	Move<VkPipeline>												m_pipeline;
384 
385 	Move<VkDescriptorUpdateTemplate>								m_updateTemplate;
386 };
387 
BindingAcceleratioStructureTestInstance(Context & context,const TestParams & testParams)388 BindingAcceleratioStructureTestInstance::BindingAcceleratioStructureTestInstance (Context& context, const TestParams& testParams)
389 	: TestInstance						(context)
390 	, m_testParams						(testParams)
391 	, m_bottomAccelerationStructures	()
392 	, m_topAccelerationStructure		()
393 	, m_descriptorPool					()
394 	, m_descriptorSetLayoutImg			()
395 	, m_descriptorSetImg				()
396 	, m_descriptorSetLayoutAS			()
397 	, m_descriptorSetAS					()
398 	, m_pipelineLayout					()
399 	, m_pipeline						()
400 	, m_updateTemplate					()
401 {
402 }
403 
iterate(void)404 tcu::TestStatus BindingAcceleratioStructureTestInstance::iterate (void)
405 {
406 	const DeviceInterface&								vkd										= m_context.getDeviceInterface();
407 	const VkDevice										device									= m_context.getDevice();
408 	const VkQueue										queue									= m_context.getUniversalQueue();
409 	Allocator&											allocator								= m_context.getDefaultAllocator();
410 	const deUint32										queueFamilyIndex						= m_context.getUniversalQueueFamilyIndex();
411 	const bool											templateUpdateMethod					= isTemplateUpdateMethod(m_testParams.updateMethod);
412 	const bool											pushUpdateMethod						= isPushUpdateMethod(m_testParams.updateMethod);
413 
414 	const deUint32										width									= m_testParams.width;
415 	const deUint32										height									= m_testParams.height;
416 	const deUint32										depth									= m_testParams.depth;
417 	const VkImageCreateInfo								imageCreateInfo							= makeImageCreateInfo(m_testParams.format, width, height, depth);
418 	const VkImageSubresourceRange						imageSubresourceRange					= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
419 	const de::MovePtr<ImageWithMemory>					image									= de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
420 	const Move<VkImageView>								imageView								= makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, m_testParams.format, imageSubresourceRange);
421 
422 	const deUint32										pixelSize								= mapVkFormat(m_testParams.format).getPixelSize();
423 	const VkBufferCreateInfo							resultBufferCreateInfo					= makeBufferCreateInfo(width * height * depth * pixelSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
424 	const VkImageSubresourceLayers						resultBufferImageSubresourceLayers		= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
425 	const VkBufferImageCopy								resultBufferImageRegion					= makeBufferImageCopy(makeExtent3D(width, height, depth), resultBufferImageSubresourceLayers);
426 	de::MovePtr<BufferWithMemory>						resultBuffer							= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
427 	const VkDescriptorImageInfo							resultImageInfo							= makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
428 
429 	const Move<VkCommandPool>							commandPool								= createCommandPool(vkd, device, 0, queueFamilyIndex);
430 	const Move<VkCommandBuffer>							commandBuffer							= allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
431 	const VkAccelerationStructureKHR*					topAccelerationStructurePtr				= createAccelerationStructures(m_context, m_testParams);
432 	const VkWriteDescriptorSetAccelerationStructureKHR	writeDescriptorSetAccelerationStructure	= makeWriteDescriptorSetAccelerationStructureKHR(topAccelerationStructurePtr);
433 	const deUint32										accelerationStructureDescriptorCount	= 1 + getExtraAccelerationDescriptorCount();
434 	deUint32											updateCount								= 0;
435 
436 	m_descriptorPool			= DescriptorPoolBuilder()
437 									.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
438 									.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, accelerationStructureDescriptorCount)
439 									.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u + accelerationStructureDescriptorCount);
440 
441 	m_descriptorSetLayoutImg	= DescriptorSetLayoutBuilder()
442 									.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, getShaderStageFlags())
443 									.build(vkd, device);
444 	m_descriptorSetImg			= makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutImg);
445 
446 	DescriptorSetUpdateBuilder()
447 		.writeSingle(*m_descriptorSetImg, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
448 		.update(vkd, device);
449 
450 	m_descriptorSetLayoutAS		= DescriptorSetLayoutBuilder()
451 									.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, getShaderStageFlags())
452 									.build(vkd, device, getDescriptorSetLayoutCreateFlags(m_testParams.updateMethod));
453 	m_descriptorSetAS			= makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutAS, m_testParams.updateMethod);
454 
455 	initPipeline();
456 
457 	if (m_testParams.updateMethod == UPDATE_METHOD_NORMAL)
458 	{
459 		DescriptorSetUpdateBuilder()
460 			.writeSingle(*m_descriptorSetAS, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &writeDescriptorSetAccelerationStructure)
461 			.update(vkd, device);
462 
463 		updateCount++;
464 	}
465 
466 	if (templateUpdateMethod)
467 	{
468 		const VkDescriptorUpdateTemplateType		updateTemplateType		= isPushUpdateMethod(m_testParams.updateMethod)
469 																			? VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR
470 																			: VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET;
471 		const VkDescriptorUpdateTemplateEntry		updateTemplateEntry		=
472 		{
473 			0,												//  deUint32			dstBinding;
474 			0,												//  deUint32			dstArrayElement;
475 			1,												//  deUint32			descriptorCount;
476 			VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,	//  VkDescriptorType	descriptorType;
477 			0,												//  deUintptr			offset;
478 			0,												//  deUintptr			stride;
479 		};
480 		const VkDescriptorUpdateTemplateCreateInfo	templateCreateInfo	=
481 		{
482 			VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,	//  VkStructureType							sType;
483 			DE_NULL,														//  const void*								pNext;
484 			0,																//  VkDescriptorUpdateTemplateCreateFlags	flags;
485 			1,																//  deUint32								descriptorUpdateEntryCount;
486 			&updateTemplateEntry,											//  const VkDescriptorUpdateTemplateEntry*	pDescriptorUpdateEntries;
487 			updateTemplateType,												//  VkDescriptorUpdateTemplateType			templateType;
488 			*m_descriptorSetLayoutAS,										//  VkDescriptorSetLayout					descriptorSetLayout;
489 			getPipelineBindPoint(),											//  VkPipelineBindPoint						pipelineBindPoint;
490 			*m_pipelineLayout,												//  VkPipelineLayout						pipelineLayout;
491 			0,																//  deUint32								set;
492 		};
493 
494 		m_updateTemplate = vk::createDescriptorUpdateTemplate(vkd, device, &templateCreateInfo);
495 
496 		if (!pushUpdateMethod)
497 		{
498 			vkd.updateDescriptorSetWithTemplate(device, *m_descriptorSetAS, *m_updateTemplate, topAccelerationStructurePtr);
499 
500 			updateCount++;
501 		}
502 	}
503 
504 	beginCommandBuffer(vkd, *commandBuffer, 0u);
505 	{
506 		{
507 			const VkClearValue			clearValue				= makeClearValueColorU32(0u, 0u, 0u, 0u);
508 			const VkImageMemoryBarrier	preImageBarrier			= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, **image, imageSubresourceRange);
509 			const VkImageMemoryBarrier	postImageBarrier		= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, **image, imageSubresourceRange);
510 
511 			cmdPipelineImageMemoryBarrier(vkd, *commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
512 			vkd.cmdClearColorImage(*commandBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
513 			cmdPipelineImageMemoryBarrier(vkd, *commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
514 
515 			vkd.cmdBindDescriptorSets(*commandBuffer, getPipelineBindPoint(), *m_pipelineLayout, 1, 1, &m_descriptorSetImg.get(), 0, DE_NULL);
516 		}
517 
518 		switch (m_testParams.updateMethod)
519 		{
520 			case UPDATE_METHOD_NORMAL:			// fallthrough
521 			case UPDATE_METHOD_WITH_TEMPLATE:
522 			{
523 				vkd.cmdBindDescriptorSets(*commandBuffer, getPipelineBindPoint(), *m_pipelineLayout, 0, 1, &m_descriptorSetAS.get(), 0, DE_NULL);
524 
525 				break;
526 			}
527 
528 			case UPDATE_METHOD_WITH_PUSH:
529 			{
530 				DescriptorSetUpdateBuilder()
531 					.writeSingle(*m_descriptorSetAS, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &writeDescriptorSetAccelerationStructure)
532 					.updateWithPush(vkd, *commandBuffer, getPipelineBindPoint(), *m_pipelineLayout, 0, 0, 1);
533 
534 				updateCount++;
535 
536 				break;
537 			}
538 
539 			case UPDATE_METHOD_WITH_PUSH_TEMPLATE:
540 			{
541 				vkd.cmdPushDescriptorSetWithTemplateKHR(*commandBuffer, *m_updateTemplate, *m_pipelineLayout, 0, topAccelerationStructurePtr);
542 
543 				updateCount++;
544 
545 				break;
546 			}
547 
548 			default: TCU_THROW(InternalError, "Unknown update method");
549 		}
550 
551 		{
552 			const VkMemoryBarrier		preTraceMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR);
553 			const VkPipelineStageFlags	dstStageFlags			= VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR;
554 
555 			buildAccelerationStructures(m_context, m_testParams, *commandBuffer);
556 
557 			cmdPipelineMemoryBarrier(vkd, *commandBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, dstStageFlags, &preTraceMemoryBarrier);
558 		}
559 
560 		fillCommandBuffer(*commandBuffer);
561 
562 		{
563 			const VkMemoryBarrier		postTestMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
564 
565 			cmdPipelineMemoryBarrier(vkd, *commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTestMemoryBarrier);
566 		}
567 
568 		vkd.cmdCopyImageToBuffer(*commandBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
569 	}
570 	endCommandBuffer(vkd, *commandBuffer);
571 
572 	if (updateCount != 1)
573 		TCU_THROW(InternalError, "Invalid descriptor update");
574 
575 	submitCommandsAndWait(vkd, device, queue, commandBuffer.get());
576 
577 	invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
578 
579 	if (verify(resultBuffer.get(), m_context, m_testParams))
580 		return tcu::TestStatus::pass("Pass");
581 	else
582 		return tcu::TestStatus::fail("Fail");
583 }
584 
createAccelerationStructures(Context & context,TestParams & testParams)585 const VkAccelerationStructureKHR* BindingAcceleratioStructureTestInstance::createAccelerationStructures (Context&		context,
586 																										 TestParams&	testParams)
587 {
588 	DE_UNREF(testParams);
589 
590 	const DeviceInterface&							vkd											= context.getDeviceInterface();
591 	const VkDevice									device										= context.getDevice();
592 	Allocator&										allocator									= context.getDefaultAllocator();
593 	de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure	= makeBottomLevelAccelerationStructure();
594 	de::MovePtr<TopLevelAccelerationStructure>		rayQueryTopLevelAccelerationStructure		= makeTopLevelAccelerationStructure();
595 	std::vector<tcu::Vec3>							geometryData;
596 
597 	// Generate in-plain square starting at (0,0,PLAIN_Z0) and ending at (1,1,PLAIN_Z1).
598 	// Vertices 1,0 and 0,1 by Z axis are in the middle between PLAIN_Z0 and PLAIN_Z1
599 	geometryData.push_back(tcu::Vec3(0.0f, 0.0f, PLAIN_Z0));
600 	geometryData.push_back(tcu::Vec3(1.0f, 0.0f, (PLAIN_Z0 + PLAIN_Z1) / 2.0f));
601 	geometryData.push_back(tcu::Vec3(0.0f, 1.0f, (PLAIN_Z0 + PLAIN_Z1) / 2.0f));
602 	geometryData.push_back(tcu::Vec3(1.0f, 1.0f, PLAIN_Z1));
603 	geometryData.push_back(tcu::Vec3(0.0f, 1.0f, (PLAIN_Z0 + PLAIN_Z1) / 2.0f));
604 	geometryData.push_back(tcu::Vec3(1.0f, 0.0f, (PLAIN_Z0 + PLAIN_Z1) / 2.0f));
605 
606 	rayQueryBottomLevelAccelerationStructure->setGeometryCount(1u);
607 	rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, true);
608 	rayQueryBottomLevelAccelerationStructure->create(vkd, device, allocator, 0);
609 	m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
610 
611 	m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
612 	m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back());
613 	m_topAccelerationStructure->create(vkd, device, allocator);
614 
615 	return m_topAccelerationStructure.get()->getPtr();
616 }
617 
buildAccelerationStructures(Context & context,TestParams & testParams,VkCommandBuffer commandBuffer)618 void BindingAcceleratioStructureTestInstance::buildAccelerationStructures	(Context&			context,
619 																			 TestParams&		testParams,
620 																			 VkCommandBuffer	commandBuffer)
621 {
622 	DE_UNREF(testParams);
623 
624 	const DeviceInterface&	vkd		= context.getDeviceInterface();
625 	const VkDevice			device	= context.getDevice();
626 
627 	for (size_t blStructNdx = 0; blStructNdx < m_bottomAccelerationStructures.size(); ++blStructNdx)
628 		m_bottomAccelerationStructures[blStructNdx]->build(vkd, device, commandBuffer);
629 
630 	m_topAccelerationStructure->build(vkd, device, commandBuffer);
631 }
632 
verify(BufferWithMemory * resultBuffer,Context & context,TestParams & testParams)633 bool BindingAcceleratioStructureTestInstance::verify (BufferWithMemory*	resultBuffer,
634 													  Context&			context,
635 													  TestParams&		testParams)
636 {
637 	tcu::TestLog&			log			= context.getTestContext().getLog();
638 	const deUint32			width		= testParams.width;
639 	const deUint32			height		= testParams.height;
640 	const deInt32*			retrieved	= (deInt32*)resultBuffer->getAllocation().getHostPtr();
641 	deUint32				failures	= 0;
642 	deUint32				pos			= 0;
643 	std::vector<deInt32>	expected;
644 
645 	expected.reserve(width * height);
646 
647 	for (deUint32 y = 0; y < height; ++y)
648 	{
649 		const float	expectedY	= deFloatMix(PLAIN_Z0, PLAIN_Z1, (0.5f + float(y)) / float(height));
650 
651 		for (deUint32 x = 0; x < width; ++x)
652 		{
653 			const float		expectedX	= deFloatMix(PLAIN_Z0, PLAIN_Z1, (0.5f + float(x)) / float(width));
654 			const deInt32	expectedV	= deInt32(float(FIXED_POINT_DIVISOR / 2) * (expectedX + expectedY));
655 
656 			expected.push_back(expectedV);
657 		}
658 	}
659 
660 	for (deUint32 y = 0; y < height; ++y)
661 	for (deUint32 x = 0; x < width; ++x)
662 	{
663 		if (retrieved[pos] != expected[pos])
664 		{
665 			failures++;
666 
667 			if (failures < 10)
668 			{
669 				const deInt32	expectedValue	= expected[pos];
670 				const deInt32	retrievedValue	= retrieved[pos];
671 
672 				log << tcu::TestLog::Message
673 					<< "At (" << x <<"," << y << ") "
674 					<< "expected " << std::fixed << std::setprecision(6) << std::setw(8) << float(expectedValue) / float(FIXED_POINT_DIVISOR) << " (" << expectedValue << ") "
675 					<< "retrieved " << std::fixed << std::setprecision(6) << std::setw(8) << float(retrievedValue) / float(FIXED_POINT_DIVISOR) << " (" << retrievedValue << ") "
676 					<< tcu::TestLog::EndMessage;
677 			}
678 		}
679 
680 		pos++;
681 	}
682 
683 	if (failures != 0)
684 	{
685 		for (deUint32 dumpNdx = 0; dumpNdx < 2; ++dumpNdx)
686 		{
687 			const deInt32*		data		= (dumpNdx == 0) ? expected.data() : retrieved;
688 			const char*			dataName	= (dumpNdx == 0) ? "Expected" : "Retrieved";
689 			std::ostringstream	css;
690 
691 			pos = 0;
692 
693 			for (deUint32 y = 0; y < height; ++y)
694 			{
695 				for (deUint32 x = 0; x < width; ++x)
696 				{
697 					if (expected[pos] != retrieved[pos])
698 						css << std::fixed << std::setprecision(6) << std::setw(8) << float(data[pos]) / float(FIXED_POINT_DIVISOR) << ",";
699 					else
700 						css << "________,";
701 
702 					pos++;
703 				}
704 
705 				css << std::endl;
706 			}
707 
708 			log << tcu::TestLog::Message << dataName << ":" << tcu::TestLog::EndMessage;
709 			log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
710 		}
711 	}
712 
713 	return (failures == 0);
714 }
715 
716 
717 class BindingAcceleratioStructureGraphicsTestInstance : public BindingAcceleratioStructureTestInstance
718 {
719 public:
720 	static void							checkSupport										(Context&			context,
721 																							 const TestParams&	testParams);
722 	static void							initPrograms										(SourceCollections&	programCollection,
723 																							 const TestParams&	testParams);
724 
725 										BindingAcceleratioStructureGraphicsTestInstance		(Context&			context,
726 																							 const TestParams&	testParams);
~BindingAcceleratioStructureGraphicsTestInstance()727 	virtual								~BindingAcceleratioStructureGraphicsTestInstance	() {}
728 
729 protected:
730 	virtual void						initPipeline										(void) override;
731 	virtual void						fillCommandBuffer									(VkCommandBuffer	commandBuffer) override;
732 
733 	void								initVertexBuffer									(void);
734 	Move<VkPipeline>					makeGraphicsPipeline								(void);
735 
getExtraAccelerationDescriptorCount(void)736 	virtual deUint32					getExtraAccelerationDescriptorCount					(void) override									{ return 0; }
getShaderStageFlags(void)737 	virtual VkShaderStageFlags			getShaderStageFlags									(void) override									{ return VK_SHADER_STAGE_ALL_GRAPHICS; }
getPipelineBindPoint(void)738 	virtual VkPipelineBindPoint			getPipelineBindPoint								(void) override									{ return VK_PIPELINE_BIND_POINT_GRAPHICS; }
739 
740 	VkFormat							m_framebufferFormat;
741 	Move<VkImage>						m_framebufferImage;
742 	de::MovePtr<Allocation>				m_framebufferImageAlloc;
743 	Move<VkImageView>					m_framebufferAttachment;
744 
745 	Move<VkShaderModule>				m_vertShaderModule;
746 	Move<VkShaderModule>				m_geomShaderModule;
747 	Move<VkShaderModule>				m_tescShaderModule;
748 	Move<VkShaderModule>				m_teseShaderModule;
749 	Move<VkShaderModule>				m_fragShaderModule;
750 
751 	Move<VkRenderPass>					m_renderPass;
752 	Move<VkFramebuffer>					m_framebuffer;
753 
754 	deUint32							m_vertexCount;
755 	Move<VkBuffer>						m_vertexBuffer;
756 	de::MovePtr<Allocation>				m_vertexBufferAlloc;
757 };
758 
BindingAcceleratioStructureGraphicsTestInstance(Context & context,const TestParams & testParams)759 BindingAcceleratioStructureGraphicsTestInstance::BindingAcceleratioStructureGraphicsTestInstance (Context&			context,
760 																								  const TestParams&	testParams)
761 	: BindingAcceleratioStructureTestInstance	(context, testParams)
762 	, m_framebufferFormat						(VK_FORMAT_R8G8B8A8_UNORM)
763 	, m_framebufferImage						()
764 	, m_framebufferImageAlloc					()
765 	, m_framebufferAttachment					()
766 	, m_vertShaderModule						()
767 	, m_geomShaderModule						()
768 	, m_tescShaderModule						()
769 	, m_teseShaderModule						()
770 	, m_fragShaderModule						()
771 	, m_renderPass								()
772 	, m_framebuffer								()
773 	, m_vertexCount								(0)
774 	, m_vertexBuffer							()
775 	, m_vertexBufferAlloc						()
776 {
777 }
778 
checkSupport(Context & context,const TestParams & testParams)779 void BindingAcceleratioStructureGraphicsTestInstance::checkSupport (Context&			context,
780 																	const TestParams&	testParams)
781 {
782 	switch (testParams.stage)
783 	{
784 	case VK_SHADER_STAGE_VERTEX_BIT:
785 	case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
786 	case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
787 	case VK_SHADER_STAGE_GEOMETRY_BIT:
788 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
789 		break;
790 	default:
791 		break;
792 	}
793 
794 	switch (testParams.stage)
795 	{
796 	case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
797 	case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
798 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
799 		break;
800 	case VK_SHADER_STAGE_GEOMETRY_BIT:
801 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
802 		break;
803 	default:
804 		break;
805 	}
806 }
807 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)808 void BindingAcceleratioStructureGraphicsTestInstance::initPrograms (SourceCollections&	programCollection,
809 																	const TestParams&	testParams)
810 {
811 	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
812 	const std::string				testShaderBody	= testParams.testConfigShaderBodyText(testParams);
813 
814 	switch (testParams.stage)
815 	{
816 		case VK_SHADER_STAGE_VERTEX_BIT:
817 		{
818 			{
819 				std::ostringstream src;
820 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
821 					<< "#extension GL_EXT_ray_query : require\n"
822 					<< "#extension GL_EXT_ray_tracing : require\n"
823 					<< "\n"
824 					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
825 					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
826 					<< "\n"
827 					<< "void testFunc(ivec3 pos, ivec3 size)\n"
828 					<< "{\n"
829 					<< testShaderBody
830 					<< "}\n"
831 					<< "\n"
832 					<< "void main(void)\n"
833 					<< "{\n"
834 					<< "  const int   posId    = int(gl_VertexIndex / 3);\n"
835 					<< "  const int   vertId   = int(gl_VertexIndex % 3);\n"
836 					<< "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
837 					<< "  const ivec3 pos      = ivec3(posId % size.x, posId / size.x, 0);\n"
838 					<< "\n"
839 					<< "  if (vertId == 0)\n"
840 					<< "  {\n"
841 					<< "    testFunc(pos, size);\n"
842 					<< "  }\n"
843 					<< "}\n";
844 
845 				programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
846 			}
847 
848 			programCollection.glslSources.add("frag") << glu::FragmentSource(getGraphicsPassthrough()) << buildOptions;
849 
850 			break;
851 		}
852 
853 		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
854 		{
855 			{
856 				std::ostringstream src;
857 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
858 					<< "\n"
859 					<< "layout(location = 0) in vec4 in_position;\n"
860 					<< "out gl_PerVertex\n"
861 					<< "{\n"
862 					<< "  vec4 gl_Position;\n"
863 					<< "};\n"
864 					<< "\n"
865 					<< "void main(void)\n"
866 					<< "{\n"
867 					<< "  gl_Position = in_position;\n"
868 					<< "}\n";
869 
870 				programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
871 			}
872 
873 			{
874 				std::ostringstream src;
875 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
876 					<< "#extension GL_EXT_tessellation_shader : require\n"
877 					<< "#extension GL_EXT_ray_query : require\n"
878 					<< "\n"
879 					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
880 					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
881 					<< "\n"
882 					<< "in gl_PerVertex\n"
883 					<< "{\n"
884 					<< "  vec4 gl_Position;\n"
885 					<< "} gl_in[];\n"
886 					<< "layout(vertices = 3) out;\n"
887 					<< "out gl_PerVertex\n"
888 					<< "{\n"
889 					<< "  vec4 gl_Position;\n"
890 					<< "} gl_out[];\n"
891 					<< "\n"
892 					<< "void testFunc(ivec3 pos, ivec3 size)\n"
893 					<< "{\n"
894 					<< testShaderBody
895 					<< "}\n"
896 					<< "\n"
897 					<< "void main(void)\n"
898 					<< "{\n"
899 					<< "\n"
900 					<< "  if (gl_InvocationID == 0)\n"
901 					<< "  {\n"
902 					<< "    const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
903 					<< "    int index = int(gl_in[gl_InvocationID].gl_Position.z);\n"
904 					<< "    int x = index % size.x;\n"
905 					<< "    int y = index / size.y;\n"
906 					<< "    const ivec3 pos = ivec3(x, y, 0);\n"
907 					<< "    testFunc(pos, size);\n"
908 					<< "  }\n"
909 					<< "\n"
910 					<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
911 					<< "  gl_TessLevelInner[0] = 1;\n"
912 					<< "  gl_TessLevelInner[1] = 1;\n"
913 					<< "  gl_TessLevelOuter[gl_InvocationID] = 1;\n"
914 					<< "}\n";
915 
916 				programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions;
917 			}
918 
919 			{
920 				std::ostringstream src;
921 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
922 					<< "#extension GL_EXT_tessellation_shader : require\n"
923 					<< "layout(triangles, equal_spacing, ccw) in;\n"
924 					<< "\n"
925 					<< "in gl_PerVertex\n"
926 					<< "{\n"
927 					<< "  vec4 gl_Position;\n"
928 					<< "} gl_in[];\n"
929 					<< "\n"
930 					<< "void main(void)\n"
931 					<< "{\n"
932 					<< "  gl_Position = gl_in[0].gl_Position;\n"
933 					<< "}\n";
934 
935 				programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions;
936 			}
937 
938 			break;
939 		}
940 
941 		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
942 		{
943 			{
944 				std::ostringstream src;
945 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
946 					<< "\n"
947 					<< "layout(location = 0) in vec4 in_position;\n"
948 					<< "out gl_PerVertex"
949 					<< "{\n"
950 					<< "  vec4 gl_Position;\n"
951 					<< "};\n"
952 					<< "\n"
953 					<< "void main(void)\n"
954 					<< "{\n"
955 					<< "  gl_Position = in_position;\n"
956 					<< "}\n";
957 
958 				programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
959 			}
960 
961 			{
962 				std::ostringstream src;
963 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
964 					<< "#extension GL_EXT_tessellation_shader : require\n"
965 					<< "\n"
966 					<< "in gl_PerVertex\n"
967 					<< "{\n"
968 					<< "  vec4 gl_Position;\n"
969 					<< "} gl_in[];\n"
970 					<< "layout(vertices = 3) out;\n"
971 					<< "out gl_PerVertex\n"
972 					<< "{\n"
973 					<< "  vec4 gl_Position;\n"
974 					<< "} gl_out[];\n"
975 					<< "\n"
976 					<< "void main(void)\n"
977 					<< "{\n"
978 					<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
979 					<< "  gl_TessLevelInner[0] = 1;\n"
980 					<< "  gl_TessLevelInner[1] = 1;\n"
981 					<< "  gl_TessLevelOuter[gl_InvocationID] = 1;\n"
982 					<< "}\n";
983 
984 				programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions;
985 			}
986 
987 			{
988 				std::ostringstream src;
989 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
990 					<< "#extension GL_EXT_tessellation_shader : require\n"
991 					<< "#extension GL_EXT_ray_query : require\n"
992 					<< "\n"
993 					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
994 					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
995 					<< "\n"
996 					<< "layout(triangles, equal_spacing, ccw) in;\n"
997 					<< "in gl_PerVertex\n"
998 					<< "{\n"
999 					<< "  vec4 gl_Position;\n"
1000 					<< "} gl_in[];\n"
1001 					<< "\n"
1002 					<< "void testFunc(ivec3 pos, ivec3 size)\n"
1003 					<< "{\n"
1004 					<< testShaderBody
1005 					<< "}\n"
1006 					<< "\n"
1007 					<< "void main(void)\n"
1008 					<< "{\n"
1009 					<< "	const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
1010 					<< "	int index = int(gl_in[0].gl_Position.z);\n"
1011 					<< "	int x = index % size.x;\n"
1012 					<< "	int y = index / size.y;\n"
1013 					<< "	const ivec3 pos = ivec3(x, y, 0);\n"
1014 					<< "	testFunc(pos, size);\n"
1015 					<< "	gl_Position = gl_in[0].gl_Position;\n"
1016 					<< "}\n";
1017 
1018 				programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions;
1019 			}
1020 
1021 			break;
1022 		}
1023 
1024 		case VK_SHADER_STAGE_GEOMETRY_BIT:
1025 		{
1026 			programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions;
1027 
1028 			{
1029 				std::ostringstream src;
1030 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1031 					<< "#extension GL_EXT_ray_query : require\n"
1032 					<< "\n"
1033 					<< "layout(triangles) in;\n"
1034 					<< "layout(points, max_vertices = 1) out;\n"
1035 					<< "\n"
1036 					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1037 					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1038 					<< "\n"
1039 					<< "void testFunc(ivec3 pos, ivec3 size)\n"
1040 					<< "{\n"
1041 					<< testShaderBody
1042 					<< "}\n"
1043 					<< "\n"
1044 					<< "void main(void)\n"
1045 					<< "{\n"
1046 					<< "  const int   posId    = int(gl_PrimitiveIDIn);\n"
1047 					<< "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
1048 					<< "  const ivec3 pos      = ivec3(posId % size.x, posId / size.x, 0);\n"
1049 					<< "\n"
1050 					<< "  testFunc(pos, size);\n"
1051 					<< "  gl_PointSize = 1.0;\n"
1052 					<< "}\n";
1053 
1054 				programCollection.glslSources.add("geom") << glu::GeometrySource(src.str()) << buildOptions;
1055 			}
1056 
1057 			break;
1058 		}
1059 
1060 		case VK_SHADER_STAGE_FRAGMENT_BIT:
1061 		{
1062 			programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions;
1063 
1064 			{
1065 				std::ostringstream src;
1066 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1067 					<< "#extension GL_EXT_ray_query : require\n"
1068 					<< "\n"
1069 					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1070 					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1071 					<< "\n"
1072 					<< "void testFunc(ivec3 pos, ivec3 size)\n"
1073 					<< "{\n"
1074 					<< testShaderBody
1075 					<< "}\n"
1076 					<< "\n"
1077 					<< "void main(void)\n"
1078 					<< "{\n"
1079 					<< "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
1080 					<< "  const ivec3 pos      = ivec3(int(gl_FragCoord.x - 0.5f), int(gl_FragCoord.y - 0.5f), 0);\n"
1081 					<< "\n"
1082 					<< "  testFunc(pos, size);\n"
1083 					<< "}\n";
1084 
1085 				programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()) << buildOptions;
1086 			}
1087 
1088 			break;
1089 		}
1090 
1091 		default:
1092 			TCU_THROW(InternalError, "Unknown stage");
1093 	}
1094 }
1095 
initVertexBuffer(void)1096 void BindingAcceleratioStructureGraphicsTestInstance::initVertexBuffer (void)
1097 {
1098 	const DeviceInterface&	vkd			= m_context.getDeviceInterface();
1099 	const VkDevice			device		= m_context.getDevice();
1100 	const deUint32			width		= m_testParams.width;
1101 	const deUint32			height		= m_testParams.height;
1102 	Allocator&				allocator	= m_context.getDefaultAllocator();
1103 	std::vector<tcu::Vec4>	vertices;
1104 
1105 	switch (m_testParams.stage)
1106 	{
1107 		case VK_SHADER_STAGE_VERTEX_BIT:
1108 		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
1109 		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
1110 		case VK_SHADER_STAGE_GEOMETRY_BIT:
1111 		{
1112 			float z = 0.0f;
1113 
1114 			vertices.reserve(3 * height * width);
1115 
1116 			for (deUint32 y = 0; y < height; ++y)
1117 			for (deUint32 x = 0; x < width; ++x)
1118 			{
1119 				const float	x0	= float(x + 0) / float(width);
1120 				const float	y0	= float(y + 0) / float(height);
1121 				const float	x1	= float(x + 1) / float(width);
1122 				const float	y1	= float(y + 1) / float(height);
1123 				const float	xm	= (x0 + x1) / 2.0f;
1124 				const float	ym	= (y0 + y1) / 2.0f;
1125 
1126 				vertices.push_back(tcu::Vec4(x0, y0, z, 1.0f));
1127 				vertices.push_back(tcu::Vec4(xm, y1, z, 1.0f));
1128 				vertices.push_back(tcu::Vec4(x1, ym, z, 1.0f));
1129 
1130 				z += 1.f;
1131 			}
1132 
1133 			break;
1134 		}
1135 
1136 		case VK_SHADER_STAGE_FRAGMENT_BIT:
1137 		{
1138 			const float		z = 1.0f;
1139 			const tcu::Vec4	a = tcu::Vec4(-1.0f, -1.0f, z, 1.0f);
1140 			const tcu::Vec4	b = tcu::Vec4(+1.0f, -1.0f, z, 1.0f);
1141 			const tcu::Vec4	c = tcu::Vec4(-1.0f, +1.0f, z, 1.0f);
1142 			const tcu::Vec4	d = tcu::Vec4(+1.0f, +1.0f, z, 1.0f);
1143 
1144 			vertices.push_back(a);
1145 			vertices.push_back(b);
1146 			vertices.push_back(c);
1147 
1148 			vertices.push_back(b);
1149 			vertices.push_back(c);
1150 			vertices.push_back(d);
1151 
1152 			break;
1153 		}
1154 
1155 		default:
1156 			TCU_THROW(InternalError, "Unknown stage");
1157 
1158 	}
1159 
1160 	// Initialize vertex buffer
1161 	{
1162 		const VkDeviceSize			vertexBufferSize		= sizeof(vertices[0][0]) * vertices[0].SIZE * vertices.size();
1163 		const VkBufferCreateInfo	vertexBufferCreateInfo	= makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
1164 
1165 		m_vertexCount		= static_cast<deUint32>(vertices.size());
1166 		m_vertexBuffer		= createBuffer(vkd, device, &vertexBufferCreateInfo);
1167 		m_vertexBufferAlloc	= bindBuffer(vkd, device, allocator, *m_vertexBuffer, vk::MemoryRequirement::HostVisible);
1168 
1169 		deMemcpy(m_vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexBufferSize);
1170 		flushAlloc(vkd, device, *m_vertexBufferAlloc);
1171 	}
1172 }
1173 
makeGraphicsPipeline(void)1174 Move<VkPipeline> BindingAcceleratioStructureGraphicsTestInstance::makeGraphicsPipeline (void)
1175 {
1176 	const DeviceInterface&			vkd					= m_context.getDeviceInterface();
1177 	const VkDevice					device				= m_context.getDevice();
1178 	const bool						tessStageTest		= (m_testParams.stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || m_testParams.stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
1179 	const VkPrimitiveTopology		topology			= tessStageTest ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1180 	const deUint32					patchControlPoints	= tessStageTest ? 3 : 0;
1181 	const std::vector<VkViewport>	viewports			(1, makeViewport(m_testParams.width, m_testParams.height));
1182 	const std::vector<VkRect2D>		scissors			(1, makeRect2D(m_testParams.width, m_testParams.height));
1183 
1184 	return vk::makeGraphicsPipeline	(vkd,
1185 									 device,
1186 									 *m_pipelineLayout,
1187 									 *m_vertShaderModule,
1188 									 *m_tescShaderModule,
1189 									 *m_teseShaderModule,
1190 									 *m_geomShaderModule,
1191 									 *m_fragShaderModule,
1192 									 *m_renderPass,
1193 									 viewports,
1194 									 scissors,
1195 									 topology,
1196 									 0,
1197 									 patchControlPoints);
1198 }
1199 
initPipeline(void)1200 void BindingAcceleratioStructureGraphicsTestInstance::initPipeline (void)
1201 {
1202 	const DeviceInterface&	vkd			= m_context.getDeviceInterface();
1203 	const VkDevice			device		= m_context.getDevice();
1204 	Allocator&				allocator	= m_context.getDefaultAllocator();
1205 	vk::BinaryCollection&	collection	= m_context.getBinaryCollection();
1206 	VkShaderStageFlags		shaders		= static_cast<VkShaderStageFlags>(0);
1207 	deUint32				shaderCount	= 0;
1208 
1209 	if (collection.contains("vert")) shaders |= VK_SHADER_STAGE_VERTEX_BIT;
1210 	if (collection.contains("geom")) shaders |= VK_SHADER_STAGE_GEOMETRY_BIT;
1211 	if (collection.contains("tesc")) shaders |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
1212 	if (collection.contains("tese")) shaders |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
1213 	if (collection.contains("frag")) shaders |= VK_SHADER_STAGE_FRAGMENT_BIT;
1214 
1215 	for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
1216 		shaderCount++;
1217 
1218 	if (shaderCount != (deUint32)dePop32(shaders))
1219 		TCU_THROW(InternalError, "Unused shaders detected in the collection");
1220 
1221 	if (0 != (shaders & VK_SHADER_STAGE_VERTEX_BIT))					m_vertShaderModule = createShaderModule(vkd, device, collection.get("vert"), 0);
1222 	if (0 != (shaders & VK_SHADER_STAGE_GEOMETRY_BIT))					m_geomShaderModule = createShaderModule(vkd, device, collection.get("geom"), 0);
1223 	if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT))		m_tescShaderModule = createShaderModule(vkd, device, collection.get("tesc"), 0);
1224 	if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))	m_teseShaderModule = createShaderModule(vkd, device, collection.get("tese"), 0);
1225 	if (0 != (shaders & VK_SHADER_STAGE_FRAGMENT_BIT))					m_fragShaderModule = createShaderModule(vkd, device, collection.get("frag"), 0);
1226 
1227 	m_framebufferImage		= makeImage				(vkd, device, makeImageCreateInfo(m_framebufferFormat, m_testParams.width, m_testParams.height, 1u, VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
1228 	m_framebufferImageAlloc	= bindImage				(vkd, device, allocator, *m_framebufferImage, MemoryRequirement::Any);
1229 	m_framebufferAttachment	= makeImageView			(vkd, device, *m_framebufferImage, VK_IMAGE_VIEW_TYPE_2D, m_framebufferFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
1230 	m_renderPass			= makeRenderPass		(vkd, device, m_framebufferFormat);
1231 	m_framebuffer			= makeFramebuffer		(vkd, device, *m_renderPass, *m_framebufferAttachment, m_testParams.width, m_testParams.height);
1232 	m_pipelineLayout		= makePipelineLayout	(vkd, device, m_descriptorSetLayoutAS.get(), m_descriptorSetLayoutImg.get());
1233 	m_pipeline				= makeGraphicsPipeline	();
1234 
1235 	initVertexBuffer();
1236 }
1237 
fillCommandBuffer(VkCommandBuffer commandBuffer)1238 void BindingAcceleratioStructureGraphicsTestInstance::fillCommandBuffer (VkCommandBuffer	commandBuffer)
1239 {
1240 	const DeviceInterface&	vkd					= m_context.getDeviceInterface();
1241 	const VkDeviceSize		vertexBufferOffset	= 0;
1242 
1243 	vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1244 	vkd.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);
1245 
1246 	beginRenderPass(vkd, commandBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_testParams.width, m_testParams.height), tcu::UVec4());
1247 
1248 	vkd.cmdDraw(commandBuffer, m_vertexCount, 1u, 0u, 0u);
1249 
1250 	endRenderPass(vkd, commandBuffer);
1251 }
1252 
1253 class BindingAcceleratioStructureComputeTestInstance : public BindingAcceleratioStructureTestInstance
1254 {
1255 public:
1256 									BindingAcceleratioStructureComputeTestInstance	(Context&			context,
1257 																					 const TestParams&	testParams);
1258 
~BindingAcceleratioStructureComputeTestInstance()1259 	virtual							~BindingAcceleratioStructureComputeTestInstance	() {}
1260 
1261 	static void						checkSupport									(Context&			context,
1262 																					 const TestParams&	testParams);
1263 	static void						initPrograms									(SourceCollections&	programCollection,
1264 																					 const TestParams&	testParams);
1265 
1266 protected:
1267 	virtual void					initPipeline									(void) override;
1268 	virtual void					fillCommandBuffer								(VkCommandBuffer	commandBuffer) override;
1269 
getExtraAccelerationDescriptorCount(void)1270 	virtual deUint32				getExtraAccelerationDescriptorCount				(void) override									{ return 0; }
getShaderStageFlags(void)1271 	virtual VkShaderStageFlags		getShaderStageFlags								(void) override									{ return VK_SHADER_STAGE_COMPUTE_BIT; }
getPipelineBindPoint(void)1272 	virtual VkPipelineBindPoint		getPipelineBindPoint							(void) override									{ return VK_PIPELINE_BIND_POINT_COMPUTE; }
1273 
1274 	Move<VkShaderModule>			m_shaderModule;
1275 };
1276 
BindingAcceleratioStructureComputeTestInstance(Context & context,const TestParams & testParams)1277 BindingAcceleratioStructureComputeTestInstance::BindingAcceleratioStructureComputeTestInstance (Context&			context,
1278 																								const TestParams&	testParams)
1279 	: BindingAcceleratioStructureTestInstance	(context, testParams)
1280 	, m_shaderModule	()
1281 {
1282 }
1283 
checkSupport(Context & context,const TestParams & testParams)1284 void BindingAcceleratioStructureComputeTestInstance::checkSupport (Context&				context,
1285 																   const TestParams&	testParams)
1286 {
1287 	DE_UNREF(context);
1288 	DE_UNREF(testParams);
1289 }
1290 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)1291 void BindingAcceleratioStructureComputeTestInstance::initPrograms (SourceCollections&	programCollection,
1292 																   const TestParams&	testParams)
1293 {
1294 	const vk::ShaderBuildOptions	buildOptions		(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1295 	const std::string				testShaderBody		= testParams.testConfigShaderBodyText(testParams);
1296 	const std::string				testBody			=
1297 		"  ivec3       pos      = ivec3(gl_WorkGroupID);\n"
1298 		"  ivec3       size     = ivec3(gl_NumWorkGroups);\n"
1299 		+ testShaderBody;
1300 
1301 	switch (testParams.stage)
1302 	{
1303 		case VK_SHADER_STAGE_COMPUTE_BIT:
1304 		{
1305 			std::stringstream css;
1306 			css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1307 				<< "#extension GL_EXT_ray_query : require\n"
1308 				<< "\n"
1309 				<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1310 				<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1311 				<< "\n"
1312 				<< "void main()\n"
1313 				<< "{\n"
1314 				<< testBody
1315 				<< "}\n";
1316 
1317 			programCollection.glslSources.add("comp") << glu::ComputeSource(css.str()) << buildOptions;
1318 
1319 			break;
1320 		}
1321 
1322 		default:
1323 			TCU_THROW(InternalError, "Unknown stage");
1324 	}
1325 }
1326 
initPipeline(void)1327 void BindingAcceleratioStructureComputeTestInstance::initPipeline (void)
1328 {
1329 	const DeviceInterface&	vkd			= m_context.getDeviceInterface();
1330 	const VkDevice			device		= m_context.getDevice();
1331 	vk::BinaryCollection&	collection	= m_context.getBinaryCollection();
1332 
1333 	m_shaderModule		= createShaderModule(vkd, device, collection.get("comp"), 0);
1334 	m_pipelineLayout	= makePipelineLayout(vkd, device, m_descriptorSetLayoutAS.get(), m_descriptorSetLayoutImg.get());
1335 	m_pipeline			= makeComputePipeline(vkd, device, *m_pipelineLayout, *m_shaderModule);
1336 }
1337 
fillCommandBuffer(VkCommandBuffer commandBuffer)1338 void BindingAcceleratioStructureComputeTestInstance::fillCommandBuffer (VkCommandBuffer	commandBuffer)
1339 {
1340 	const DeviceInterface&	vkd	= m_context.getDeviceInterface();
1341 
1342 	vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline.get());
1343 
1344 	vkd.cmdDispatch(commandBuffer, m_testParams.width, m_testParams.height, 1);
1345 }
1346 
1347 class BindingAcceleratioStructureRayTracingTestInstance : public BindingAcceleratioStructureTestInstance
1348 {
1349 public:
1350 													BindingAcceleratioStructureRayTracingTestInstance	(Context&							context,
1351 																										 const TestParams&					testParams);
~BindingAcceleratioStructureRayTracingTestInstance()1352 	virtual											~BindingAcceleratioStructureRayTracingTestInstance	() {}
1353 
1354 	static void										checkSupport										(Context&							context,
1355 																										 const TestParams&					testParams);
1356 	static void										initPrograms										(SourceCollections&					programCollection,
1357 																										 const TestParams&					testParams);
1358 
1359 protected:
1360 	virtual void									initPipeline										(void) override;
1361 	virtual void									fillCommandBuffer									(VkCommandBuffer					commandBuffer) override;
1362 
1363 	de::MovePtr<BufferWithMemory>					createShaderBindingTable							(const InstanceInterface&			vki,
1364 																										 const DeviceInterface&				vkd,
1365 																										 const VkDevice						device,
1366 																										 const VkPhysicalDevice				physicalDevice,
1367 																										 const VkPipeline					pipeline,
1368 																										 Allocator&							allocator,
1369 																										 de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
1370 																										 const deUint32						group);
1371 
getExtraAccelerationDescriptorCount(void)1372 	virtual deUint32								getExtraAccelerationDescriptorCount					(void) override													{ return 1; }
getShaderStageFlags(void)1373 	virtual VkShaderStageFlags						getShaderStageFlags									(void) override													{ return ALL_RAY_TRACING_STAGES; }
getPipelineBindPoint(void)1374 	virtual VkPipelineBindPoint						getPipelineBindPoint								(void) override													{ return VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR; }
1375 
1376 	deUint32										m_shaders;
1377 	deUint32										m_raygenShaderGroup;
1378 	deUint32										m_missShaderGroup;
1379 	deUint32										m_hitShaderGroup;
1380 	deUint32										m_callableShaderGroup;
1381 	deUint32										m_shaderGroupCount;
1382 
1383 	Move<VkDescriptorSetLayout>						m_descriptorSetLayoutSvc;
1384 	Move<VkDescriptorSet>							m_descriptorSetSvc;
1385 
1386 	de::MovePtr<RayTracingPipeline>					m_rayTracingPipeline;
1387 
1388 	de::MovePtr<BufferWithMemory>					m_raygenShaderBindingTable;
1389 	de::MovePtr<BufferWithMemory>					m_hitShaderBindingTable;
1390 	de::MovePtr<BufferWithMemory>					m_missShaderBindingTable;
1391 	de::MovePtr<BufferWithMemory>					m_callableShaderBindingTable;
1392 
1393 	VkStridedDeviceAddressRegionKHR					m_raygenShaderBindingTableRegion;
1394 	VkStridedDeviceAddressRegionKHR					m_missShaderBindingTableRegion;
1395 	VkStridedDeviceAddressRegionKHR					m_hitShaderBindingTableRegion;
1396 	VkStridedDeviceAddressRegionKHR					m_callableShaderBindingTableRegion;
1397 
1398 	de::SharedPtr<BottomLevelAccelerationStructure>	m_bottomLevelAccelerationStructure;
1399 	de::SharedPtr<TopLevelAccelerationStructure>	m_topLevelAccelerationStructure;
1400 };
1401 
BindingAcceleratioStructureRayTracingTestInstance(Context & context,const TestParams & testParams)1402 BindingAcceleratioStructureRayTracingTestInstance::BindingAcceleratioStructureRayTracingTestInstance (Context&			context,
1403 																									  const TestParams&	testParams)
1404 	: BindingAcceleratioStructureTestInstance	(context, testParams)
1405 	, m_shaders									(0)
1406 	, m_raygenShaderGroup						(~0u)
1407 	, m_missShaderGroup							(~0u)
1408 	, m_hitShaderGroup							(~0u)
1409 	, m_callableShaderGroup						(~0u)
1410 	, m_shaderGroupCount						(0)
1411 
1412 	, m_descriptorSetLayoutSvc					()
1413 	, m_descriptorSetSvc						()
1414 
1415 	, m_rayTracingPipeline						()
1416 
1417 	, m_raygenShaderBindingTable				()
1418 	, m_hitShaderBindingTable					()
1419 	, m_missShaderBindingTable					()
1420 	, m_callableShaderBindingTable				()
1421 
1422 	, m_raygenShaderBindingTableRegion			()
1423 	, m_missShaderBindingTableRegion			()
1424 	, m_hitShaderBindingTableRegion				()
1425 	, m_callableShaderBindingTableRegion		()
1426 
1427 	, m_bottomLevelAccelerationStructure		()
1428 	, m_topLevelAccelerationStructure			()
1429 {
1430 }
1431 
checkSupport(Context & context,const TestParams & testParams)1432 void BindingAcceleratioStructureRayTracingTestInstance::checkSupport (Context&			context,
1433 																	  const TestParams&	testParams)
1434 {
1435 	DE_UNREF(testParams);
1436 
1437 	context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1438 
1439 	const VkPhysicalDeviceRayTracingPipelineFeaturesKHR&	rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
1440 
1441 	if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE)
1442 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1443 }
1444 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)1445 void BindingAcceleratioStructureRayTracingTestInstance::initPrograms (SourceCollections&	programCollection,
1446 																	  const TestParams&		testParams)
1447 {
1448 	const vk::ShaderBuildOptions	buildOptions				(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1449 	const std::string				testShaderBody				= testParams.testConfigShaderBodyText(testParams);
1450 	const std::string				testBody					=
1451 		"  ivec3       pos      = ivec3(gl_LaunchIDEXT);\n"
1452 		"  ivec3       size     = ivec3(gl_LaunchSizeEXT);\n"
1453 		+ testShaderBody;
1454 	const std::string				commonRayGenerationShader	=
1455 		std::string(glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460)) + "\n"
1456 		"#extension GL_EXT_ray_tracing : require\n"
1457 		"\n"
1458 		"layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
1459 		"layout(set = 2, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
1460 		"\n"
1461 		"void main()\n"
1462 		"{\n"
1463 		"  uint  rayFlags = 0;\n"
1464 		"  uint  cullMask = 0xFF;\n"
1465 		"  float tmin     = 0.0;\n"
1466 		"  float tmax     = 9.0;\n"
1467 		"  vec3  origin   = vec3((float(gl_LaunchIDEXT.x) + 0.5f) / float(gl_LaunchSizeEXT.x), (float(gl_LaunchIDEXT.y) + 0.5f) / float(gl_LaunchSizeEXT.y), 0.0);\n"
1468 		"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1469 		"  traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
1470 		"}\n";
1471 
1472 	switch (testParams.stage)
1473 	{
1474 		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
1475 		{
1476 			std::stringstream css;
1477 			css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1478 				<< "#extension GL_EXT_ray_tracing : require\n"
1479 				<< "#extension GL_EXT_ray_query : require\n"
1480 				<< "\n"
1481 				<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1482 				<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1483 				<< "\n"
1484 				<< "void main()\n"
1485 				<< "{\n"
1486 				<< testBody
1487 				<< "}\n";
1488 
1489 			programCollection.glslSources.add("rgen") << glu::RaygenSource(css.str()) << buildOptions;
1490 
1491 			break;
1492 		}
1493 
1494 		case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
1495 		{
1496 			programCollection.glslSources.add("rgen") << glu::RaygenSource(commonRayGenerationShader) << buildOptions;
1497 
1498 			{
1499 				std::stringstream css;
1500 				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1501 					<< "#extension GL_EXT_ray_tracing : require\n"
1502 					<< "#extension GL_EXT_ray_query : require\n"
1503 					<< "\n"
1504 					<< "hitAttributeEXT vec3 attribs;\n"
1505 					<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1506 					<< "\n"
1507 					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1508 					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1509 					<< "\n"
1510 					<< "void main()\n"
1511 					<< "{\n"
1512 					<< testBody
1513 					<< "}\n";
1514 
1515 				programCollection.glslSources.add("ahit") << glu::AnyHitSource(css.str()) << buildOptions;
1516 			}
1517 
1518 			programCollection.glslSources.add("chit") << glu::ClosestHitSource(getHitPassthrough()) << buildOptions;
1519 			programCollection.glslSources.add("miss") << glu::MissSource(getMissPassthrough()) << buildOptions;
1520 
1521 			break;
1522 		}
1523 
1524 		case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
1525 		{
1526 			programCollection.glslSources.add("rgen") << glu::RaygenSource(commonRayGenerationShader) << buildOptions;
1527 
1528 			{
1529 				std::stringstream css;
1530 				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1531 					<< "#extension GL_EXT_ray_tracing : require\n"
1532 					<< "#extension GL_EXT_ray_query : require\n"
1533 					<< "\n"
1534 					<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1535 					<< "hitAttributeEXT vec3 attribs;\n"
1536 					<< "\n"
1537 					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1538 					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1539 					<< "\n"
1540 					<< "void main()\n"
1541 					<< "{\n"
1542 					<< testBody
1543 					<< "}\n";
1544 
1545 				programCollection.glslSources.add("chit") << glu::ClosestHitSource(css.str()) << buildOptions;
1546 			}
1547 
1548 			programCollection.glslSources.add("ahit") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
1549 			programCollection.glslSources.add("miss") << glu::MissSource(getMissPassthrough()) << buildOptions;
1550 
1551 			break;
1552 		}
1553 
1554 		case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
1555 		{
1556 			programCollection.glslSources.add("rgen") << glu::RaygenSource(commonRayGenerationShader) << buildOptions;
1557 
1558 			{
1559 				std::stringstream css;
1560 				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1561 					<< "#extension GL_EXT_ray_tracing : require\n"
1562 					<< "#extension GL_EXT_ray_query : require\n"
1563 					<< "hitAttributeEXT vec3 hitAttribute;\n"
1564 					<< "\n"
1565 					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1566 					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1567 					<< "\n"
1568 					<< "void main()\n"
1569 					<< "{\n"
1570 					<< testBody
1571 					<< "  hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n"
1572 					<< "  reportIntersectionEXT(1.0f, 0);\n"
1573 					<< "}\n";
1574 
1575 				programCollection.glslSources.add("sect") << glu::IntersectionSource(css.str()) << buildOptions;
1576 			}
1577 
1578 			programCollection.glslSources.add("ahit") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
1579 			programCollection.glslSources.add("chit") << glu::ClosestHitSource(getHitPassthrough()) << buildOptions;
1580 			programCollection.glslSources.add("miss") << glu::MissSource(getMissPassthrough()) << buildOptions;
1581 
1582 			break;
1583 		}
1584 
1585 		case VK_SHADER_STAGE_MISS_BIT_KHR:
1586 		{
1587 			programCollection.glslSources.add("rgen") << glu::RaygenSource(commonRayGenerationShader) << buildOptions;
1588 
1589 			{
1590 				std::stringstream css;
1591 				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1592 					<< "#extension GL_EXT_ray_tracing : require\n"
1593 					<< "#extension GL_EXT_ray_query : require\n"
1594 					<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1595 					<< "\n"
1596 					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1597 					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1598 					<< "\n"
1599 					<< "void main()\n"
1600 					<< "{\n"
1601 					<< testBody
1602 					<< "}\n";
1603 
1604 				programCollection.glslSources.add("miss") << glu::MissSource(css.str()) << buildOptions;
1605 			}
1606 
1607 			programCollection.glslSources.add("ahit") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
1608 			programCollection.glslSources.add("chit") << glu::ClosestHitSource(getHitPassthrough()) << buildOptions;
1609 
1610 			break;
1611 		}
1612 
1613 		case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
1614 		{
1615 			{
1616 				std::stringstream css;
1617 				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1618 					<< "#extension GL_EXT_ray_tracing : require\n"
1619 					<< "#extension GL_EXT_ray_query : require\n"
1620 					<< "\n"
1621 					<< "layout(location = 0) callableDataEXT float dummy;"
1622 					<< "layout(set = 2, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
1623 					<< "\n"
1624 					<< "void main()\n"
1625 					<< "{\n"
1626 					<< "  executeCallableEXT(0, 0);\n"
1627 					<< "}\n";
1628 
1629 				programCollection.glslSources.add("rgen") << glu::RaygenSource(css.str()) << buildOptions;
1630 			}
1631 
1632 			{
1633 				std::stringstream css;
1634 				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1635 					<< "#extension GL_EXT_ray_tracing : require\n"
1636 					<< "#extension GL_EXT_ray_query : require\n"
1637 					<< "layout(location = 0) callableDataInEXT float dummy;"
1638 					<< "\n"
1639 					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
1640 					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1641 					<< "\n"
1642 					<< "void main()\n"
1643 					<< "{\n"
1644 					<< testBody
1645 					<< "}\n";
1646 
1647 				programCollection.glslSources.add("call") << glu::CallableSource(css.str()) << buildOptions;
1648 			}
1649 
1650 			programCollection.glslSources.add("ahit") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
1651 			programCollection.glslSources.add("chit") << glu::ClosestHitSource(getHitPassthrough()) << buildOptions;
1652 			programCollection.glslSources.add("miss") << glu::MissSource(getMissPassthrough()) << buildOptions;
1653 
1654 			break;
1655 		}
1656 
1657 		default:
1658 			TCU_THROW(InternalError, "Unknown stage");
1659 	}
1660 }
1661 
initPipeline(void)1662 void BindingAcceleratioStructureRayTracingTestInstance::initPipeline (void)
1663 {
1664 	const InstanceInterface&	vki						= m_context.getInstanceInterface();
1665 	const DeviceInterface&		vkd						= m_context.getDeviceInterface();
1666 	const VkDevice				device					= m_context.getDevice();
1667 	const VkPhysicalDevice		physicalDevice			= m_context.getPhysicalDevice();
1668 	vk::BinaryCollection&		collection				= m_context.getBinaryCollection();
1669 	Allocator&					allocator				= m_context.getDefaultAllocator();
1670 	const deUint32				shaderGroupHandleSize	= getShaderGroupHandleSize(vki, physicalDevice);
1671 	const VkShaderStageFlags	hitStages				= VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
1672 	deUint32					shaderCount				= 0;
1673 
1674 	m_shaderGroupCount = 0;
1675 
1676 	if (collection.contains("rgen")) m_shaders |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
1677 	if (collection.contains("ahit")) m_shaders |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
1678 	if (collection.contains("chit")) m_shaders |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
1679 	if (collection.contains("miss")) m_shaders |= VK_SHADER_STAGE_MISS_BIT_KHR;
1680 	if (collection.contains("sect")) m_shaders |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
1681 	if (collection.contains("call")) m_shaders |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
1682 
1683 	for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
1684 		shaderCount++;
1685 
1686 	if (shaderCount != (deUint32)dePop32(m_shaders))
1687 		TCU_THROW(InternalError, "Unused shaders detected in the collection");
1688 
1689 	if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))
1690 		m_raygenShaderGroup		= m_shaderGroupCount++;
1691 
1692 	if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))
1693 		m_missShaderGroup		= m_shaderGroupCount++;
1694 
1695 	if (0 != (m_shaders & hitStages))
1696 		m_hitShaderGroup		= m_shaderGroupCount++;
1697 
1698 	if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))
1699 		m_callableShaderGroup	= m_shaderGroupCount++;
1700 
1701 	m_rayTracingPipeline		= de::newMovePtr<RayTracingPipeline>();
1702 
1703 	m_descriptorSetLayoutSvc	= DescriptorSetLayoutBuilder()
1704 									.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1705 									.build(vkd, device);
1706 	m_descriptorSetSvc			= makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutSvc);
1707 
1708 	if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))			m_rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR			, createShaderModule(vkd, device, collection.get("rgen"), 0), m_raygenShaderGroup);
1709 	if (0 != (m_shaders & VK_SHADER_STAGE_ANY_HIT_BIT_KHR))			m_rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR			, createShaderModule(vkd, device, collection.get("ahit"), 0), m_hitShaderGroup);
1710 	if (0 != (m_shaders & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR))		m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR		, createShaderModule(vkd, device, collection.get("chit"), 0), m_hitShaderGroup);
1711 	if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))			m_rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR			, createShaderModule(vkd, device, collection.get("miss"), 0), m_missShaderGroup);
1712 	if (0 != (m_shaders & VK_SHADER_STAGE_INTERSECTION_BIT_KHR))	m_rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR	, createShaderModule(vkd, device, collection.get("sect"), 0), m_hitShaderGroup);
1713 	if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))		m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR		, createShaderModule(vkd, device, collection.get("call"), 0), m_callableShaderGroup);
1714 
1715 	m_pipelineLayout					= makePipelineLayout(vkd, device, m_descriptorSetLayoutAS.get(), m_descriptorSetLayoutImg.get(), m_descriptorSetLayoutSvc.get());
1716 	m_pipeline							= m_rayTracingPipeline->createPipeline(vkd, device, *m_pipelineLayout);
1717 
1718 	m_raygenShaderBindingTable			= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_raygenShaderGroup);
1719 	m_missShaderBindingTable			= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_missShaderGroup);
1720 	m_hitShaderBindingTable				= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_hitShaderGroup);
1721 	m_callableShaderBindingTable		= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_callableShaderGroup);
1722 
1723 	m_raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_raygenShaderBindingTable),		shaderGroupHandleSize, 1);
1724 	m_missShaderBindingTableRegion		= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_missShaderBindingTable),		shaderGroupHandleSize, 1);
1725 	m_hitShaderBindingTableRegion		= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_hitShaderBindingTable),			shaderGroupHandleSize, 1);
1726 	m_callableShaderBindingTableRegion	= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_callableShaderBindingTable),	shaderGroupHandleSize, 1);
1727 }
1728 
fillCommandBuffer(VkCommandBuffer commandBuffer)1729 void BindingAcceleratioStructureRayTracingTestInstance::fillCommandBuffer (VkCommandBuffer	commandBuffer)
1730 {
1731 	const DeviceInterface&							vkd									= m_context.getDeviceInterface();
1732 	const VkDevice									device								= m_context.getDevice();
1733 	Allocator&										allocator							= m_context.getDefaultAllocator();
1734 	de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure	= makeBottomLevelAccelerationStructure();
1735 	de::MovePtr<TopLevelAccelerationStructure>		topLevelAccelerationStructure		= makeTopLevelAccelerationStructure();
1736 
1737 	m_bottomLevelAccelerationStructure = de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release());
1738 	m_bottomLevelAccelerationStructure->setDefaultGeometryData(m_testParams.stage);
1739 	m_bottomLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1740 
1741 	m_topLevelAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(topLevelAccelerationStructure.release());
1742 	m_topLevelAccelerationStructure->setInstanceCount(1);
1743 	m_topLevelAccelerationStructure->addInstance(m_bottomLevelAccelerationStructure);
1744 	m_topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
1745 
1746 	const TopLevelAccelerationStructure*				topLevelAccelerationStructurePtr		= m_topLevelAccelerationStructure.get();
1747 	const VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet	= makeWriteDescriptorSetAccelerationStructureKHR(topLevelAccelerationStructurePtr->getPtr());
1748 
1749 	DescriptorSetUpdateBuilder()
1750 		.writeSingle(*m_descriptorSetSvc, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1751 		.update(vkd, device);
1752 
1753 	vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *m_pipelineLayout, 2, 1, &m_descriptorSetSvc.get(), 0, DE_NULL);
1754 
1755 	vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, m_pipeline.get());
1756 
1757 	cmdTraceRays(vkd,
1758 		commandBuffer,
1759 		&m_raygenShaderBindingTableRegion,
1760 		&m_missShaderBindingTableRegion,
1761 		&m_hitShaderBindingTableRegion,
1762 		&m_callableShaderBindingTableRegion,
1763 		m_testParams.width, m_testParams.height, 1);
1764 }
1765 
createShaderBindingTable(const InstanceInterface & vki,const DeviceInterface & vkd,const VkDevice device,const VkPhysicalDevice physicalDevice,const VkPipeline pipeline,Allocator & allocator,de::MovePtr<RayTracingPipeline> & rayTracingPipeline,const deUint32 group)1766 de::MovePtr<BufferWithMemory> BindingAcceleratioStructureRayTracingTestInstance::createShaderBindingTable (const InstanceInterface&			vki,
1767 																										   const DeviceInterface&			vkd,
1768 																										   const VkDevice					device,
1769 																										   const VkPhysicalDevice			physicalDevice,
1770 																										   const VkPipeline					pipeline,
1771 																										   Allocator&						allocator,
1772 																										   de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
1773 																										   const deUint32					group)
1774 {
1775 	de::MovePtr<BufferWithMemory>	shaderBindingTable;
1776 
1777 	if (group < m_shaderGroupCount)
1778 	{
1779 		const deUint32	shaderGroupHandleSize		= getShaderGroupHandleSize(vki, physicalDevice);
1780 		const deUint32	shaderGroupBaseAlignment	= getShaderGroupBaseAlignment(vki, physicalDevice);
1781 
1782 		shaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, group, 1u);
1783 	}
1784 
1785 	return shaderBindingTable;
1786 }
1787 
1788 
1789 class BindingAcceleratioStructureRayTracingRayTracingTestInstance : public BindingAcceleratioStructureTestInstance
1790 {
1791 public:
1792 													BindingAcceleratioStructureRayTracingRayTracingTestInstance		(Context&							context,
1793 																													 const TestParams&					testParams);
~BindingAcceleratioStructureRayTracingRayTracingTestInstance()1794 	virtual											~BindingAcceleratioStructureRayTracingRayTracingTestInstance	() {}
1795 
1796 	static void										checkSupport													(Context&							context,
1797 																													 const TestParams&					testParams);
1798 	static void										initPrograms													(SourceCollections&					programCollection,
1799 																													 const TestParams&					testParams);
1800 
1801 protected:
1802 	virtual void									initPipeline													(void) override;
1803 	virtual void									fillCommandBuffer												(VkCommandBuffer					commandBuffer) override;
1804 
1805 	void											calcShaderGroup													(deUint32&							shaderGroupCounter,
1806 																													 const VkShaderStageFlags			shaders1,
1807 																													 const VkShaderStageFlags			shaders2,
1808 																													 const VkShaderStageFlags			shaderStageFlags,
1809 																													 deUint32&							shaderGroup,
1810 																													 deUint32&							shaderGroupCount) const;
1811 
1812 
1813 	de::MovePtr<BufferWithMemory>					createShaderBindingTable										(const InstanceInterface&			vki,
1814 																													 const DeviceInterface&				vkd,
1815 																													 const VkDevice						device,
1816 																													 const VkPhysicalDevice				physicalDevice,
1817 																													 const VkPipeline					pipeline,
1818 																													 Allocator&							allocator,
1819 																													 de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
1820 																													 const deUint32						group,
1821 																													 const deUint32						groupCount = 1);
1822 
getExtraAccelerationDescriptorCount(void)1823 	virtual deUint32								getExtraAccelerationDescriptorCount								(void) override													{ return 1; }
getShaderStageFlags(void)1824 	virtual VkShaderStageFlags						getShaderStageFlags												(void) override													{ return ALL_RAY_TRACING_STAGES; }
getPipelineBindPoint(void)1825 	virtual VkPipelineBindPoint						getPipelineBindPoint											(void) override													{ return VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR; }
1826 
1827 	deUint32										m_shaders;
1828 	deUint32										m_raygenShaderGroup;
1829 	deUint32										m_missShaderGroup;
1830 	deUint32										m_hitShaderGroup;
1831 	deUint32										m_callableShaderGroup;
1832 	deUint32										m_shaderGroupCount;
1833 
1834 	Move<VkDescriptorSetLayout>						m_descriptorSetLayoutSvc;
1835 	Move<VkDescriptorSet>							m_descriptorSetSvc;
1836 
1837 	de::MovePtr<RayTracingPipeline>					m_rayTracingPipeline;
1838 
1839 	de::MovePtr<BufferWithMemory>					m_raygenShaderBindingTable;
1840 	de::MovePtr<BufferWithMemory>					m_hitShaderBindingTable;
1841 	de::MovePtr<BufferWithMemory>					m_missShaderBindingTable;
1842 	de::MovePtr<BufferWithMemory>					m_callableShaderBindingTable;
1843 
1844 	VkStridedDeviceAddressRegionKHR					m_raygenShaderBindingTableRegion;
1845 	VkStridedDeviceAddressRegionKHR					m_missShaderBindingTableRegion;
1846 	VkStridedDeviceAddressRegionKHR					m_hitShaderBindingTableRegion;
1847 	VkStridedDeviceAddressRegionKHR					m_callableShaderBindingTableRegion;
1848 
1849 	de::SharedPtr<BottomLevelAccelerationStructure>	m_bottomLevelAccelerationStructure;
1850 	de::SharedPtr<TopLevelAccelerationStructure>	m_topLevelAccelerationStructure;
1851 };
1852 
BindingAcceleratioStructureRayTracingRayTracingTestInstance(Context & context,const TestParams & testParams)1853 BindingAcceleratioStructureRayTracingRayTracingTestInstance::BindingAcceleratioStructureRayTracingRayTracingTestInstance (Context&			context,
1854 																														  const TestParams&	testParams)
1855 	: BindingAcceleratioStructureTestInstance	(context, testParams)
1856 	, m_shaders									(0)
1857 	, m_raygenShaderGroup						(~0u)
1858 	, m_missShaderGroup							(~0u)
1859 	, m_hitShaderGroup							(~0u)
1860 	, m_callableShaderGroup						(~0u)
1861 	, m_shaderGroupCount						(0)
1862 
1863 	, m_descriptorSetLayoutSvc					()
1864 	, m_descriptorSetSvc						()
1865 
1866 	, m_rayTracingPipeline						()
1867 
1868 	, m_raygenShaderBindingTable				()
1869 	, m_hitShaderBindingTable					()
1870 	, m_missShaderBindingTable					()
1871 	, m_callableShaderBindingTable				()
1872 
1873 	, m_raygenShaderBindingTableRegion			()
1874 	, m_missShaderBindingTableRegion			()
1875 	, m_hitShaderBindingTableRegion				()
1876 	, m_callableShaderBindingTableRegion		()
1877 
1878 	, m_bottomLevelAccelerationStructure		()
1879 	, m_topLevelAccelerationStructure			()
1880 {
1881 }
1882 
checkSupport(Context & context,const TestParams & testParams)1883 void BindingAcceleratioStructureRayTracingRayTracingTestInstance::checkSupport (Context&			context,
1884 																				const TestParams&	testParams)
1885 {
1886 	DE_UNREF(testParams);
1887 
1888 	context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1889 
1890 	const VkPhysicalDeviceRayTracingPipelineFeaturesKHR&	rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
1891 
1892 	if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE)
1893 		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
1894 }
1895 
initPrograms(SourceCollections & programCollection,const TestParams & testParams)1896 void BindingAcceleratioStructureRayTracingRayTracingTestInstance::initPrograms (SourceCollections&	programCollection,
1897 																				const TestParams&	testParams)
1898 {
1899 	const vk::ShaderBuildOptions	buildOptions				(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1900 	const std::string				testShaderBody				= testParams.testConfigShaderBodyText(testParams);
1901 	const std::string				testBody					=
1902 		"  ivec3       pos      = ivec3(gl_LaunchIDEXT);\n"
1903 		"  ivec3       size     = ivec3(gl_LaunchSizeEXT);\n"
1904 		+ testShaderBody;
1905 	const std::string				testOutClosestHitShader		=
1906 		std::string(glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460)) + "\n"
1907 		"#extension GL_EXT_ray_tracing : require\n"
1908 		"\n"
1909 		"hitAttributeEXT vec3 attribs;\n"
1910 		"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1911 		"layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1912 		"\n"
1913 		"void main()\n"
1914 		"{\n"
1915 		+ testBody +
1916 		"}\n";
1917 	const std::string				testInShaderFragment		=
1918 		"  uint  rayFlags = 0;\n"
1919 		"  uint  cullMask = 0xFF;\n"
1920 		"  float tmin     = 0.0;\n"
1921 		"  float tmax     = 9.0;\n"
1922 		"  vec3  origin   = vec3((float(gl_LaunchIDEXT.x) + 0.5f) / float(gl_LaunchSizeEXT.x), (float(gl_LaunchIDEXT.y) + 0.5f) / float(gl_LaunchSizeEXT.y), 0.0);\n"
1923 		"  vec3  direct   = vec3(0.0, 0.0, 1.0);\n"
1924 		"\n"
1925 		"  traceRayEXT(topLevelAS, rayFlags, cullMask, 1, 0, 1, origin, tmin, direct, tmax, 0);\n";
1926 	const std::string				commonRayGenerationShader	=
1927 		std::string(glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460)) + "\n"
1928 		"#extension GL_EXT_ray_tracing : require\n"
1929 		"\n"
1930 		"layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
1931 		"layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1932 		"layout(set = 2, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
1933 		"\n"
1934 		"void main()\n"
1935 		"{\n"
1936 		"  uint  rayFlags = 0;\n"
1937 		"  uint  cullMask = 0xFF;\n"
1938 		"  float tmin     = 0.0;\n"
1939 		"  float tmax     = 9.0;\n"
1940 		"  vec3  origin   = vec3((float(gl_LaunchIDEXT.x) + 0.5f) / float(gl_LaunchSizeEXT.x), (float(gl_LaunchIDEXT.y) + 0.5f) / float(gl_LaunchSizeEXT.y), 0.0);\n"
1941 		"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
1942 		"\n"
1943 		"  traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
1944 		"}\n";
1945 
1946 	programCollection.glslSources.add("chit0") << glu::ClosestHitSource(testOutClosestHitShader) << buildOptions;
1947 	programCollection.glslSources.add("ahit0") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
1948 	programCollection.glslSources.add("miss0") << glu::MissSource(getMissPassthrough()) << buildOptions;
1949 
1950 	switch (testParams.stage)
1951 	{
1952 		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
1953 		{
1954 			{
1955 				std::stringstream css;
1956 				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1957 					<< "#extension GL_EXT_ray_tracing : require\n"
1958 					<< "\n"
1959 					<< "layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
1960 					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
1961 					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1962 					<< "\n"
1963 					<< "void main()\n"
1964 					<< "{\n"
1965 					<< testInShaderFragment
1966 					<< "}\n";
1967 
1968 				programCollection.glslSources.add("rgen") << glu::RaygenSource(css.str()) << buildOptions;
1969 			}
1970 
1971 			programCollection.glslSources.add("chit") << glu::ClosestHitSource(getHitPassthrough()) << buildOptions;
1972 			programCollection.glslSources.add("ahit") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
1973 			programCollection.glslSources.add("miss") << glu::MissSource(getMissPassthrough()) << buildOptions;
1974 
1975 			break;
1976 		}
1977 
1978 		case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
1979 		{
1980 			programCollection.glslSources.add("rgen") << glu::RaygenSource(commonRayGenerationShader) << buildOptions;
1981 
1982 			{
1983 				std::stringstream css;
1984 				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
1985 					<< "#extension GL_EXT_ray_tracing : require\n"
1986 					<< "\n"
1987 					<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1988 					<< "hitAttributeEXT vec3 attribs;\n"
1989 					<< "\n"
1990 					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
1991 					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
1992 					<< "\n"
1993 					<< "void main()\n"
1994 					<< "{\n"
1995 					<< testInShaderFragment
1996 					<< "}\n";
1997 
1998 				programCollection.glslSources.add("chit") << glu::ClosestHitSource(css.str()) << buildOptions;
1999 			}
2000 
2001 			programCollection.glslSources.add("ahit") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
2002 			programCollection.glslSources.add("miss") << glu::MissSource(getMissPassthrough()) << buildOptions;
2003 
2004 			break;
2005 		}
2006 
2007 		case VK_SHADER_STAGE_MISS_BIT_KHR:
2008 		{
2009 			programCollection.glslSources.add("rgen") << glu::RaygenSource(commonRayGenerationShader) << buildOptions;
2010 
2011 			{
2012 				std::stringstream css;
2013 				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
2014 					<< "#extension GL_EXT_ray_tracing : require\n"
2015 					<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
2016 					<< "\n"
2017 					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
2018 					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
2019 					<< "\n"
2020 					<< "void main()\n"
2021 					<< "{\n"
2022 					<< testInShaderFragment
2023 					<< "}\n";
2024 
2025 				programCollection.glslSources.add("miss") << glu::MissSource(css.str()) << buildOptions;
2026 			}
2027 
2028 			programCollection.glslSources.add("ahit") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
2029 			programCollection.glslSources.add("chit") << glu::ClosestHitSource(getHitPassthrough()) << buildOptions;
2030 
2031 			break;
2032 		}
2033 
2034 		default:
2035 			TCU_THROW(InternalError, "Unknown stage");
2036 	}
2037 }
2038 
calcShaderGroup(deUint32 & shaderGroupCounter,const VkShaderStageFlags shaders1,const VkShaderStageFlags shaders2,const VkShaderStageFlags shaderStageFlags,deUint32 & shaderGroup,deUint32 & shaderGroupCount) const2039 void BindingAcceleratioStructureRayTracingRayTracingTestInstance::calcShaderGroup (deUint32&				shaderGroupCounter,
2040 																				   const VkShaderStageFlags	shaders1,
2041 																				   const VkShaderStageFlags	shaders2,
2042 																				   const VkShaderStageFlags	shaderStageFlags,
2043 																				   deUint32&				shaderGroup,
2044 																				   deUint32&				shaderGroupCount) const
2045 {
2046 	const deUint32	shader1Count = ((shaders1 & shaderStageFlags) != 0) ? 1 : 0;
2047 	const deUint32	shader2Count = ((shaders2 & shaderStageFlags) != 0) ? 1 : 0;
2048 
2049 	shaderGroupCount = shader1Count + shader2Count;
2050 
2051 	if (shaderGroupCount != 0)
2052 	{
2053 		shaderGroup			= shaderGroupCounter;
2054 		shaderGroupCounter += shaderGroupCount;
2055 	}
2056 }
2057 
initPipeline(void)2058 void BindingAcceleratioStructureRayTracingRayTracingTestInstance::initPipeline (void)
2059 {
2060 	const InstanceInterface&	vki						= m_context.getInstanceInterface();
2061 	const DeviceInterface&		vkd						= m_context.getDeviceInterface();
2062 	const VkDevice				device					= m_context.getDevice();
2063 	const VkPhysicalDevice		physicalDevice			= m_context.getPhysicalDevice();
2064 	vk::BinaryCollection&		collection				= m_context.getBinaryCollection();
2065 	Allocator&					allocator				= m_context.getDefaultAllocator();
2066 	const deUint32				shaderGroupHandleSize	= getShaderGroupHandleSize(vki, physicalDevice);
2067 	const VkShaderStageFlags	hitStages				= VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
2068 	deUint32					shaderCount				= 0;
2069 	VkShaderStageFlags			shaders0				= static_cast<VkShaderStageFlags>(0);
2070 	deUint32					raygenShaderGroupCount	= 0;
2071 	deUint32					hitShaderGroupCount		= 0;
2072 	deUint32					missShaderGroupCount	= 0;
2073 
2074 	if (collection.contains("rgen")) m_shaders |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
2075 	if (collection.contains("ahit")) m_shaders |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
2076 	if (collection.contains("chit")) m_shaders |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
2077 	if (collection.contains("miss")) m_shaders |= VK_SHADER_STAGE_MISS_BIT_KHR;
2078 
2079 	if (collection.contains("ahit0")) shaders0 |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
2080 	if (collection.contains("chit0")) shaders0 |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
2081 	if (collection.contains("miss0")) shaders0 |= VK_SHADER_STAGE_MISS_BIT_KHR;
2082 
2083 	for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
2084 		shaderCount++;
2085 
2086 	if (shaderCount != (deUint32)(dePop32(m_shaders) + dePop32(shaders0)))
2087 		TCU_THROW(InternalError, "Unused shaders detected in the collection");
2088 
2089 	calcShaderGroup(m_shaderGroupCount, m_shaders, shaders0, VK_SHADER_STAGE_RAYGEN_BIT_KHR, m_raygenShaderGroup, raygenShaderGroupCount);
2090 	calcShaderGroup(m_shaderGroupCount, m_shaders, shaders0, VK_SHADER_STAGE_MISS_BIT_KHR,   m_missShaderGroup,   missShaderGroupCount);
2091 	calcShaderGroup(m_shaderGroupCount, m_shaders, shaders0, hitStages,                      m_hitShaderGroup,    hitShaderGroupCount);
2092 
2093 	m_rayTracingPipeline		= de::newMovePtr<RayTracingPipeline>();
2094 
2095 	m_descriptorSetLayoutSvc	= DescriptorSetLayoutBuilder()
2096 									.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
2097 									.build(vkd, device);
2098 	m_descriptorSetSvc			= makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutSvc);
2099 
2100 	if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))			m_rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR			, createShaderModule(vkd, device, collection.get("rgen"), 0), m_raygenShaderGroup);
2101 	if (0 != (m_shaders & VK_SHADER_STAGE_ANY_HIT_BIT_KHR))			m_rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR			, createShaderModule(vkd, device, collection.get("ahit"), 0), m_hitShaderGroup);
2102 	if (0 != (m_shaders & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR))		m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR		, createShaderModule(vkd, device, collection.get("chit"), 0), m_hitShaderGroup);
2103 	if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))			m_rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR			, createShaderModule(vkd, device, collection.get("miss"), 0), m_missShaderGroup);
2104 
2105 	// The "chit" and "miss" cases both generate more rays from their shaders.
2106 	if (m_testParams.testType == TEST_TYPE_USING_RAY_TRACING && (m_testParams.stage == VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR || m_testParams.stage == VK_SHADER_STAGE_MISS_BIT_KHR))
2107 		m_rayTracingPipeline->setMaxRecursionDepth(2u);
2108 
2109 	if (0 != (shaders0 & VK_SHADER_STAGE_ANY_HIT_BIT_KHR))			m_rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR			, createShaderModule(vkd, device, collection.get("ahit0"), 0), m_hitShaderGroup + 1);
2110 	if (0 != (shaders0 & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR))		m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR		, createShaderModule(vkd, device, collection.get("chit0"), 0), m_hitShaderGroup + 1);
2111 	if (0 != (shaders0 & VK_SHADER_STAGE_MISS_BIT_KHR))				m_rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR			, createShaderModule(vkd, device, collection.get("miss0"), 0), m_missShaderGroup + 1);
2112 
2113 	m_pipelineLayout					= makePipelineLayout(vkd, device, m_descriptorSetLayoutAS.get(), m_descriptorSetLayoutImg.get(), m_descriptorSetLayoutSvc.get());
2114 	m_pipeline							= m_rayTracingPipeline->createPipeline(vkd, device, *m_pipelineLayout);
2115 
2116 	m_raygenShaderBindingTable			= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_raygenShaderGroup,   raygenShaderGroupCount);
2117 	m_missShaderBindingTable			= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_missShaderGroup,     missShaderGroupCount);
2118 	m_hitShaderBindingTable				= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_hitShaderGroup,      hitShaderGroupCount);
2119 
2120 	m_raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_raygenShaderBindingTable),	shaderGroupHandleSize, raygenShaderGroupCount);
2121 	m_missShaderBindingTableRegion		= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_missShaderBindingTable),	shaderGroupHandleSize, missShaderGroupCount);
2122 	m_hitShaderBindingTableRegion		= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_hitShaderBindingTable),		shaderGroupHandleSize, hitShaderGroupCount);
2123 	m_callableShaderBindingTableRegion	= makeStridedDeviceAddressRegion(vkd, device, DE_NULL, 0, 0);
2124 }
2125 
fillCommandBuffer(VkCommandBuffer commandBuffer)2126 void BindingAcceleratioStructureRayTracingRayTracingTestInstance::fillCommandBuffer (VkCommandBuffer	commandBuffer)
2127 {
2128 	const DeviceInterface&							vkd									= m_context.getDeviceInterface();
2129 	const VkDevice									device								= m_context.getDevice();
2130 	Allocator&										allocator							= m_context.getDefaultAllocator();
2131 	de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure	= makeBottomLevelAccelerationStructure();
2132 	de::MovePtr<TopLevelAccelerationStructure>		topLevelAccelerationStructure		= makeTopLevelAccelerationStructure();
2133 
2134 	m_bottomLevelAccelerationStructure = de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release());
2135 	m_bottomLevelAccelerationStructure->setDefaultGeometryData(m_testParams.stage);
2136 	m_bottomLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
2137 
2138 	m_topLevelAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(topLevelAccelerationStructure.release());
2139 	m_topLevelAccelerationStructure->setInstanceCount(1);
2140 	m_topLevelAccelerationStructure->addInstance(m_bottomLevelAccelerationStructure);
2141 	m_topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);
2142 
2143 	const TopLevelAccelerationStructure*				topLevelAccelerationStructurePtr		= m_topLevelAccelerationStructure.get();
2144 	const VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet	= makeWriteDescriptorSetAccelerationStructureKHR(topLevelAccelerationStructurePtr->getPtr());
2145 
2146 	DescriptorSetUpdateBuilder()
2147 		.writeSingle(*m_descriptorSetSvc, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
2148 		.update(vkd, device);
2149 
2150 	vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *m_pipelineLayout, 2, 1, &m_descriptorSetSvc.get(), 0, DE_NULL);
2151 
2152 	vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, m_pipeline.get());
2153 
2154 	cmdTraceRays(vkd,
2155 		commandBuffer,
2156 		&m_raygenShaderBindingTableRegion,
2157 		&m_missShaderBindingTableRegion,
2158 		&m_hitShaderBindingTableRegion,
2159 		&m_callableShaderBindingTableRegion,
2160 		m_testParams.width, m_testParams.height, 1);
2161 }
2162 
createShaderBindingTable(const InstanceInterface & vki,const DeviceInterface & vkd,const VkDevice device,const VkPhysicalDevice physicalDevice,const VkPipeline pipeline,Allocator & allocator,de::MovePtr<RayTracingPipeline> & rayTracingPipeline,const deUint32 group,const deUint32 groupCount)2163 de::MovePtr<BufferWithMemory> BindingAcceleratioStructureRayTracingRayTracingTestInstance::createShaderBindingTable (const InstanceInterface&			vki,
2164 																													 const DeviceInterface&				vkd,
2165 																													 const VkDevice						device,
2166 																													 const VkPhysicalDevice				physicalDevice,
2167 																													 const VkPipeline					pipeline,
2168 																													 Allocator&							allocator,
2169 																													 de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
2170 																													 const deUint32						group,
2171 																													 const deUint32						groupCount)
2172 {
2173 	de::MovePtr<BufferWithMemory>	shaderBindingTable;
2174 
2175 	if (group < m_shaderGroupCount)
2176 	{
2177 		const deUint32	shaderGroupHandleSize		= getShaderGroupHandleSize(vki, physicalDevice);
2178 		const deUint32	shaderGroupBaseAlignment	= getShaderGroupBaseAlignment(vki, physicalDevice);
2179 
2180 		shaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, group, groupCount);
2181 	}
2182 
2183 	return shaderBindingTable;
2184 }
2185 
2186 
getRayQueryShaderBodyText(const TestParams & testParams)2187 const std::string getRayQueryShaderBodyText (const TestParams& testParams)
2188 {
2189 	DE_UNREF(testParams);
2190 
2191 	const std::string result =
2192 		"  const float mult     = " + de::toString(FIXED_POINT_DIVISOR) + ".0f;\n"
2193 		"  uint        rayFlags = 0;\n"
2194 		"  uint        cullMask = 0xFF;\n"
2195 		"  float       tmin     = 0.0;\n"
2196 		"  float       tmax     = 9.0;\n"
2197 		"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
2198 		"  vec3        direct   = vec3(0.0, 0.0, 1.0);\n"
2199 		"  int         value    = 0;\n"
2200 		"  rayQueryEXT rayQuery;\n"
2201 		"\n"
2202 		"  rayQueryInitializeEXT(rayQuery, tlas, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
2203 		"\n"
2204 		"  while(rayQueryProceedEXT(rayQuery))\n"
2205 		"  {\n"
2206 		"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
2207 		"    {\n"
2208 		"      const float t = rayQueryGetIntersectionTEXT(rayQuery, false);"
2209 		"\n"
2210 		"      value = int(round(mult * t));\n"
2211 		"    }\n"
2212 		"  }\n"
2213 		"\n"
2214 		"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2215 
2216 	return result;
2217 }
2218 
getRayTracingShaderBodyText(const TestParams & testParams)2219 const std::string getRayTracingShaderBodyText (const TestParams& testParams)
2220 {
2221 	DE_UNREF(testParams);
2222 
2223 	const std::string result =
2224 		"  const float mult     = " + de::toString(FIXED_POINT_DIVISOR) + ".0f;\n"
2225 		"  int         value    = int(round(mult * gl_HitTEXT));\n"
2226 		"\n"
2227 		"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";
2228 
2229 	return result;
2230 }
2231 
2232 class BindingAccelerationStructureTestCase : public TestCase
2233 {
2234 	public:
2235 							BindingAccelerationStructureTestCase	(tcu::TestContext& context, const char* name, const char* desc, const TestParams testParams);
2236 							~BindingAccelerationStructureTestCase	(void);
2237 
2238 	virtual void			checkSupport							(Context& context) const;
2239 	virtual	void			initPrograms							(SourceCollections& programCollection) const;
2240 	virtual TestInstance*	createInstance							(Context& context) const;
2241 
2242 private:
2243 	TestParams				m_testParams;
2244 };
2245 
BindingAccelerationStructureTestCase(tcu::TestContext & context,const char * name,const char * desc,const TestParams testParams)2246 BindingAccelerationStructureTestCase::BindingAccelerationStructureTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams testParams)
2247 	: vkt::TestCase	(context, name, desc)
2248 	, m_testParams		(testParams)
2249 {
2250 }
2251 
~BindingAccelerationStructureTestCase(void)2252 BindingAccelerationStructureTestCase::~BindingAccelerationStructureTestCase (void)
2253 {
2254 }
2255 
checkSupport(Context & context) const2256 void BindingAccelerationStructureTestCase::checkSupport (Context& context) const
2257 {
2258 	context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
2259 
2260 	const VkPhysicalDeviceAccelerationStructureFeaturesKHR&	accelerationStructureFeaturesKHR	= context.getAccelerationStructureFeatures();
2261 	if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
2262 		TCU_THROW(TestError, "Requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
2263 
2264 	switch (m_testParams.testType)
2265 	{
2266 		case TEST_TYPE_USING_RAY_QUERY:
2267 		{
2268 			context.requireDeviceFunctionality("VK_KHR_ray_query");
2269 
2270 			const VkPhysicalDeviceRayQueryFeaturesKHR&	rayQueryFeaturesKHR	= context.getRayQueryFeatures();
2271 
2272 			if (rayQueryFeaturesKHR.rayQuery == DE_FALSE)
2273 				TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");
2274 
2275 			break;
2276 		}
2277 
2278 		case TEST_TYPE_USING_RAY_TRACING:
2279 		{
2280 			context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
2281 
2282 			const VkPhysicalDeviceRayTracingPipelineFeaturesKHR&	rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
2283 
2284 			if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE)
2285 				TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
2286 
2287 			break;
2288 		}
2289 
2290 		default:
2291 			TCU_THROW(InternalError, "Unknown test type");
2292 	}
2293 
2294 	switch (m_testParams.updateMethod)
2295 	{
2296 		case UPDATE_METHOD_NORMAL:
2297 		{
2298 			break;
2299 		}
2300 
2301 		case UPDATE_METHOD_WITH_TEMPLATE:
2302 		{
2303 			context.requireDeviceFunctionality("VK_KHR_descriptor_update_template");
2304 
2305 			break;
2306 		}
2307 
2308 		case UPDATE_METHOD_WITH_PUSH:
2309 		{
2310 			context.requireDeviceFunctionality("VK_KHR_push_descriptor");
2311 
2312 			break;
2313 		}
2314 
2315 		case UPDATE_METHOD_WITH_PUSH_TEMPLATE:
2316 		{
2317 			context.requireDeviceFunctionality("VK_KHR_push_descriptor");
2318 			context.requireDeviceFunctionality("VK_KHR_descriptor_update_template");
2319 
2320 			break;
2321 		}
2322 
2323 		default:
2324 			TCU_THROW(InternalError, "Unknown update method");
2325 	}
2326 
2327 	m_testParams.pipelineCheckSupport(context, m_testParams);
2328 }
2329 
createInstance(Context & context) const2330 TestInstance* BindingAccelerationStructureTestCase::createInstance (Context& context) const
2331 {
2332 	switch (m_testParams.testType)
2333 	{
2334 		case TEST_TYPE_USING_RAY_QUERY:
2335 		{
2336 			switch (m_testParams.stage)
2337 			{
2338 				case VK_SHADER_STAGE_VERTEX_BIT:
2339 				case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
2340 				case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
2341 				case VK_SHADER_STAGE_GEOMETRY_BIT:
2342 				case VK_SHADER_STAGE_FRAGMENT_BIT:
2343 				{
2344 					return new BindingAcceleratioStructureGraphicsTestInstance(context, m_testParams);
2345 				}
2346 
2347 				case VK_SHADER_STAGE_COMPUTE_BIT:
2348 				{
2349 					return new BindingAcceleratioStructureComputeTestInstance(context, m_testParams);
2350 				}
2351 
2352 				case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2353 				case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2354 				case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2355 				case VK_SHADER_STAGE_MISS_BIT_KHR:
2356 				case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2357 				case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2358 				{
2359 					return new BindingAcceleratioStructureRayTracingTestInstance(context, m_testParams);
2360 				}
2361 
2362 				default:
2363 					TCU_THROW(InternalError, "Unknown shader stage");
2364 			}
2365 		}
2366 
2367 		case TEST_TYPE_USING_RAY_TRACING:
2368 		{
2369 			return new BindingAcceleratioStructureRayTracingRayTracingTestInstance(context, m_testParams);
2370 		}
2371 
2372 		default:
2373 			TCU_THROW(InternalError, "Unknown shader stage");
2374 	}
2375 }
2376 
initPrograms(SourceCollections & programCollection) const2377 void BindingAccelerationStructureTestCase::initPrograms (SourceCollections& programCollection) const
2378 {
2379 	m_testParams.pipelineInitPrograms(programCollection, m_testParams);
2380 }
2381 
getPipelineRayQueryCheckSupport(const VkShaderStageFlagBits stage)2382 static inline CheckSupportFunc getPipelineRayQueryCheckSupport (const VkShaderStageFlagBits stage)
2383 {
2384 	switch (stage)
2385 	{
2386 		case VK_SHADER_STAGE_VERTEX_BIT:
2387 		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
2388 		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
2389 		case VK_SHADER_STAGE_GEOMETRY_BIT:
2390 		case VK_SHADER_STAGE_FRAGMENT_BIT:
2391 			return BindingAcceleratioStructureGraphicsTestInstance::checkSupport;
2392 
2393 		case VK_SHADER_STAGE_COMPUTE_BIT:
2394 			return BindingAcceleratioStructureComputeTestInstance::checkSupport;
2395 
2396 		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2397 		case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2398 		case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2399 		case VK_SHADER_STAGE_MISS_BIT_KHR:
2400 		case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2401 		case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2402 			return BindingAcceleratioStructureRayTracingTestInstance::checkSupport;
2403 
2404 		default:
2405 			TCU_THROW(InternalError, "Unknown shader stage");
2406 	}
2407 }
2408 
getPipelineRayTracingCheckSupport(const VkShaderStageFlagBits stage)2409 static inline CheckSupportFunc getPipelineRayTracingCheckSupport (const VkShaderStageFlagBits stage)
2410 {
2411 	DE_UNREF(stage);
2412 
2413 	return BindingAcceleratioStructureRayTracingRayTracingTestInstance::checkSupport;
2414 }
2415 
getPipelineRayQueryInitPrograms(const VkShaderStageFlagBits stage)2416 static inline InitProgramsFunc getPipelineRayQueryInitPrograms (const VkShaderStageFlagBits stage)
2417 {
2418 	switch (stage)
2419 	{
2420 		case VK_SHADER_STAGE_VERTEX_BIT:
2421 		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
2422 		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
2423 		case VK_SHADER_STAGE_GEOMETRY_BIT:
2424 		case VK_SHADER_STAGE_FRAGMENT_BIT:
2425 			return BindingAcceleratioStructureGraphicsTestInstance::initPrograms;
2426 
2427 		case VK_SHADER_STAGE_COMPUTE_BIT:
2428 			return BindingAcceleratioStructureComputeTestInstance::initPrograms;
2429 
2430 		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2431 		case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2432 		case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2433 		case VK_SHADER_STAGE_MISS_BIT_KHR:
2434 		case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2435 		case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2436 			return BindingAcceleratioStructureRayTracingTestInstance::initPrograms;
2437 
2438 		default:
2439 			TCU_THROW(InternalError, "Unknown shader stage");
2440 	}
2441 }
2442 
getPipelineRayTracingInitPrograms(const VkShaderStageFlagBits stage)2443 static inline InitProgramsFunc getPipelineRayTracingInitPrograms (const VkShaderStageFlagBits stage)
2444 {
2445 	DE_UNREF(stage);
2446 
2447 	return BindingAcceleratioStructureRayTracingRayTracingTestInstance::initPrograms;
2448 }
2449 
getShaderBodyTextFunc(const TestType testType)2450 static inline ShaderBodyTextFunc getShaderBodyTextFunc (const TestType testType)
2451 {
2452 	switch (testType)
2453 	{
2454 		case TEST_TYPE_USING_RAY_QUERY:		return getRayQueryShaderBodyText;
2455 		case TEST_TYPE_USING_RAY_TRACING:	return getRayTracingShaderBodyText;
2456 		default:							TCU_THROW(InternalError, "Unknown test type");
2457 	}
2458 }
2459 
2460 }	// anonymous
2461 
createDescriptorUpdateASTests(tcu::TestContext & testCtx)2462 tcu::TestCaseGroup* createDescriptorUpdateASTests (tcu::TestContext& testCtx)
2463 {
2464 	de::MovePtr<tcu::TestCaseGroup> group	(new tcu::TestCaseGroup(testCtx, "acceleration_structure", "Tests acceleration structure descriptor updates"));
2465 
2466 	const struct TestTypes
2467 	{
2468 		TestType	testType;
2469 		const char*	name;
2470 	}
2471 	testTypes[] =
2472 	{
2473 		{ TEST_TYPE_USING_RAY_QUERY,	"ray_query"		},
2474 		{ TEST_TYPE_USING_RAY_TRACING,	"ray_tracing"	},
2475 	};
2476 	const struct UpdateMethods
2477 	{
2478 		const UpdateMethod	method;
2479 		const char*			name;
2480 		const char*			description;
2481 	}
2482 	updateMethods[] =
2483 	{
2484 		{ UPDATE_METHOD_NORMAL,				"regular",				"Use regular descriptor updates"		},
2485 		{ UPDATE_METHOD_WITH_TEMPLATE,		"with_template",		"Use descriptor update templates"		},
2486 		{ UPDATE_METHOD_WITH_PUSH,			"with_push",			"Use push descriptor updates"			},
2487 		{ UPDATE_METHOD_WITH_PUSH_TEMPLATE,	"with_push_template",	"Use push descriptor update templates"	},
2488 	};
2489 	const struct PipelineStages
2490 	{
2491 		VkShaderStageFlagBits	stage;
2492 		const char*				name;
2493 		const bool				rayTracing;
2494 	}
2495 	pipelineStages[] =
2496 	{
2497 		{ VK_SHADER_STAGE_VERTEX_BIT,					"vert",	false	},
2498 		{ VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,		"tesc",	false	},
2499 		{ VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,	"tese",	false	},
2500 		{ VK_SHADER_STAGE_GEOMETRY_BIT,					"geom",	false	},
2501 		{ VK_SHADER_STAGE_FRAGMENT_BIT,					"frag",	false	},
2502 		{ VK_SHADER_STAGE_COMPUTE_BIT,					"comp",	false	},
2503 		{ VK_SHADER_STAGE_RAYGEN_BIT_KHR,				"rgen",	true	},
2504 		{ VK_SHADER_STAGE_ANY_HIT_BIT_KHR,				"ahit",	false	},
2505 		{ VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,			"chit",	true	},
2506 		{ VK_SHADER_STAGE_MISS_BIT_KHR,					"miss",	true	},
2507 		{ VK_SHADER_STAGE_INTERSECTION_BIT_KHR,			"sect",	false	},
2508 		{ VK_SHADER_STAGE_CALLABLE_BIT_KHR,				"call",	false	},
2509 	};
2510 
2511 	for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
2512 	{
2513 		de::MovePtr<tcu::TestCaseGroup>	testTypeGroup		(new tcu::TestCaseGroup(group->getTestContext(), testTypes[testTypeNdx].name, ""));
2514 		const TestType					testType			= testTypes[testTypeNdx].testType;
2515 		const ShaderBodyTextFunc		shaderBodyTextFunc	= getShaderBodyTextFunc(testType);
2516 		const deUint32					imageDepth			= 1;
2517 
2518 		for (size_t updateMethodsNdx = 0; updateMethodsNdx < DE_LENGTH_OF_ARRAY(updateMethods); ++updateMethodsNdx)
2519 		{
2520 			de::MovePtr<tcu::TestCaseGroup>	updateMethodsGroup		(new tcu::TestCaseGroup(group->getTestContext(), updateMethods[updateMethodsNdx].name, updateMethods[updateMethodsNdx].description));
2521 			const UpdateMethod				updateMethod			= updateMethods[updateMethodsNdx].method;
2522 
2523 			for (size_t pipelineStageNdx = 0; pipelineStageNdx < DE_LENGTH_OF_ARRAY(pipelineStages); ++pipelineStageNdx)
2524 			{
2525 				const VkShaderStageFlagBits	stage					= pipelineStages[pipelineStageNdx].stage;
2526 				const CheckSupportFunc		pipelineCheckSupport	= (testType == TEST_TYPE_USING_RAY_QUERY)
2527 																	? getPipelineRayQueryCheckSupport(stage)
2528 																	: getPipelineRayTracingCheckSupport(stage);
2529 				const InitProgramsFunc		pipelineInitPrograms	= (testType == TEST_TYPE_USING_RAY_QUERY)
2530 																	? getPipelineRayQueryInitPrograms(stage)
2531 																	: getPipelineRayTracingInitPrograms(stage);
2532 
2533 				if (testType == TEST_TYPE_USING_RAY_TRACING && !pipelineStages[pipelineStageNdx].rayTracing)
2534 					continue;
2535 
2536 				const TestParams	testParams	=
2537 				{
2538 					TEST_WIDTH,				//  deUint32				width;
2539 					TEST_HEIGHT,			//  deUint32				height;
2540 					imageDepth,				//  deUint32				depth;
2541 					testType,				//  TestType				testType;
2542 					updateMethod,			//  UpdateMethod			updateMethod;
2543 					stage,					//  VkShaderStageFlagBits	stage;
2544 					VK_FORMAT_R32_SINT,		//  VkFormat				format;
2545 					pipelineCheckSupport,	//  CheckSupportFunc		pipelineCheckSupport;
2546 					pipelineInitPrograms,	//  InitProgramsFunc		pipelineInitPrograms;
2547 					shaderBodyTextFunc,		//  ShaderTestTextFunc		testConfigShaderBodyText;
2548 				};
2549 
2550 				updateMethodsGroup->addChild(new BindingAccelerationStructureTestCase(group->getTestContext(), pipelineStages[pipelineStageNdx].name, "", testParams));
2551 			}
2552 
2553 			testTypeGroup->addChild(updateMethodsGroup.release());
2554 		}
2555 
2556 		group->addChild(testTypeGroup.release());
2557 	}
2558 
2559 	return group.release();
2560 }
2561 
2562 }	// RayQuery
2563 }	// vkt
2564