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