1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests
3e5c31af7Sopenharmony_ci * ------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2020-2022 The Khronos Group Inc.
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *	  http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief Basic cmdTraceRays* tests.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "vktRayTracingTraceRaysTests.hpp"
25e5c31af7Sopenharmony_ci
26e5c31af7Sopenharmony_ci#include "vkDefs.hpp"
27e5c31af7Sopenharmony_ci
28e5c31af7Sopenharmony_ci#include "vktTestCase.hpp"
29e5c31af7Sopenharmony_ci#include "vktTestGroupUtil.hpp"
30e5c31af7Sopenharmony_ci#include "vkCmdUtil.hpp"
31e5c31af7Sopenharmony_ci#include "vkObjUtil.hpp"
32e5c31af7Sopenharmony_ci#include "vkBuilderUtil.hpp"
33e5c31af7Sopenharmony_ci#include "vkBarrierUtil.hpp"
34e5c31af7Sopenharmony_ci#include "vkBufferWithMemory.hpp"
35e5c31af7Sopenharmony_ci#include "vkImageWithMemory.hpp"
36e5c31af7Sopenharmony_ci#include "vkTypeUtil.hpp"
37e5c31af7Sopenharmony_ci
38e5c31af7Sopenharmony_ci#include "vkRayTracingUtil.hpp"
39e5c31af7Sopenharmony_ci
40e5c31af7Sopenharmony_ci#include <limits>
41e5c31af7Sopenharmony_ci#include <tuple>
42e5c31af7Sopenharmony_ci
43e5c31af7Sopenharmony_cinamespace vkt
44e5c31af7Sopenharmony_ci{
45e5c31af7Sopenharmony_cinamespace RayTracing
46e5c31af7Sopenharmony_ci{
47e5c31af7Sopenharmony_cinamespace
48e5c31af7Sopenharmony_ci{
49e5c31af7Sopenharmony_ciusing namespace vk;
50e5c31af7Sopenharmony_ciusing namespace vkt;
51e5c31af7Sopenharmony_ci
52e5c31af7Sopenharmony_cistatic const VkFlags	ALL_RAY_TRACING_STAGES	= VK_SHADER_STAGE_RAYGEN_BIT_KHR
53e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_ANY_HIT_BIT_KHR
54e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
55e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_MISS_BIT_KHR
56e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_INTERSECTION_BIT_KHR
57e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_CALLABLE_BIT_KHR;
58e5c31af7Sopenharmony_ci
59e5c31af7Sopenharmony_ciconstexpr deUint32		kClearColorValue	= 0xFFu;
60e5c31af7Sopenharmony_ciconstexpr deUint32		kHitColorValue		= 2u;
61e5c31af7Sopenharmony_ciconstexpr deUint32		kMissColorValue		= 1u;
62e5c31af7Sopenharmony_ci
63e5c31af7Sopenharmony_cienum class TraceType
64e5c31af7Sopenharmony_ci{
65e5c31af7Sopenharmony_ci	DIRECT			= 0,
66e5c31af7Sopenharmony_ci	INDIRECT_CPU	= 1,
67e5c31af7Sopenharmony_ci	INDIRECT_GPU	= 2,
68e5c31af7Sopenharmony_ci	INDIRECT2_GPU	= 3,
69e5c31af7Sopenharmony_ci	INDIRECT2_CPU	= 4,
70e5c31af7Sopenharmony_ci};
71e5c31af7Sopenharmony_ci
72e5c31af7Sopenharmony_cistruct TestParams
73e5c31af7Sopenharmony_ci{
74e5c31af7Sopenharmony_ci	TraceType						traceType;
75e5c31af7Sopenharmony_ci	VkTraceRaysIndirectCommandKHR	traceDimensions;	// Note: to be used for both direct and indirect variants.
76e5c31af7Sopenharmony_ci	bool							useKhrMaintenance1Semantics;
77e5c31af7Sopenharmony_ci	VkTraceRaysIndirectCommand2KHR	extendedTraceDimensions;
78e5c31af7Sopenharmony_ci};
79e5c31af7Sopenharmony_cistruct TestParams2
80e5c31af7Sopenharmony_ci{
81e5c31af7Sopenharmony_ci	TraceType		traceType;
82e5c31af7Sopenharmony_ci	VkExtent3D		traceDimensions;
83e5c31af7Sopenharmony_ci	bool			partialCopy;
84e5c31af7Sopenharmony_ci	VkQueueFlagBits	submitQueue;
85e5c31af7Sopenharmony_ci};
86e5c31af7Sopenharmony_ci
87e5c31af7Sopenharmony_cideUint32 getShaderGroupSize (const InstanceInterface&	vki,
88e5c31af7Sopenharmony_ci							 const VkPhysicalDevice		physicalDevice)
89e5c31af7Sopenharmony_ci{
90e5c31af7Sopenharmony_ci	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
91e5c31af7Sopenharmony_ci
92e5c31af7Sopenharmony_ci	rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physicalDevice);
93e5c31af7Sopenharmony_ci	return rayTracingPropertiesKHR->getShaderGroupHandleSize();
94e5c31af7Sopenharmony_ci}
95e5c31af7Sopenharmony_ci
96e5c31af7Sopenharmony_cideUint32 getShaderGroupBaseAlignment (const InstanceInterface&	vki,
97e5c31af7Sopenharmony_ci									  const VkPhysicalDevice	physicalDevice)
98e5c31af7Sopenharmony_ci{
99e5c31af7Sopenharmony_ci	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
100e5c31af7Sopenharmony_ci
101e5c31af7Sopenharmony_ci	rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
102e5c31af7Sopenharmony_ci	return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
103e5c31af7Sopenharmony_ci}
104e5c31af7Sopenharmony_ci
105e5c31af7Sopenharmony_citemplate<typename T>
106e5c31af7Sopenharmony_cibool isNullTrace (const T cmd)
107e5c31af7Sopenharmony_ci{
108e5c31af7Sopenharmony_ci	return (cmd.width == 0u || cmd.height == 0u || cmd.depth == 0u);
109e5c31af7Sopenharmony_ci}
110e5c31af7Sopenharmony_ci
111e5c31af7Sopenharmony_citemplate<typename T>
112e5c31af7Sopenharmony_ciVkExtent3D getImageExtent (const T cmd)
113e5c31af7Sopenharmony_ci{
114e5c31af7Sopenharmony_ci	return (isNullTrace(cmd) ? makeExtent3D(8u, 8u, 1u) : makeExtent3D(cmd.width, cmd.height, cmd.depth));
115e5c31af7Sopenharmony_ci}
116e5c31af7Sopenharmony_ci
117e5c31af7Sopenharmony_cibool isNullExtent (const VkExtent3D& extent)
118e5c31af7Sopenharmony_ci{
119e5c31af7Sopenharmony_ci	return (extent.width == 0u || extent.height == 0u || extent.depth == 0u);
120e5c31af7Sopenharmony_ci}
121e5c31af7Sopenharmony_ci
122e5c31af7Sopenharmony_ciVkExtent3D getNonNullImageExtent (const VkExtent3D& extent)
123e5c31af7Sopenharmony_ci{
124e5c31af7Sopenharmony_ci	return (isNullExtent(extent) ? makeExtent3D(8u, 8u, 1u) : makeExtent3D(extent.width, extent.height, extent.depth));
125e5c31af7Sopenharmony_ci}
126e5c31af7Sopenharmony_ci
127e5c31af7Sopenharmony_ciVkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, deUint32 depth, VkFormat format)
128e5c31af7Sopenharmony_ci{
129e5c31af7Sopenharmony_ci	const VkImageCreateInfo			imageCreateInfo			=
130e5c31af7Sopenharmony_ci	{
131e5c31af7Sopenharmony_ci		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,																// VkStructureType			sType;
132e5c31af7Sopenharmony_ci		DE_NULL,																							// const void*				pNext;
133e5c31af7Sopenharmony_ci		(VkImageCreateFlags)0u,																				// VkImageCreateFlags		flags;
134e5c31af7Sopenharmony_ci		VK_IMAGE_TYPE_3D,																					// VkImageType				imageType;
135e5c31af7Sopenharmony_ci		format,																								// VkFormat					format;
136e5c31af7Sopenharmony_ci		makeExtent3D(width, height, depth),																	// VkExtent3D				extent;
137e5c31af7Sopenharmony_ci		1u,																									// deUint32					mipLevels;
138e5c31af7Sopenharmony_ci		1u,																									// deUint32					arrayLayers;
139e5c31af7Sopenharmony_ci		VK_SAMPLE_COUNT_1_BIT,																				// VkSampleCountFlagBits	samples;
140e5c31af7Sopenharmony_ci		VK_IMAGE_TILING_OPTIMAL,																			// VkImageTiling			tiling;
141e5c31af7Sopenharmony_ci		VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,		// VkImageUsageFlags		usage;
142e5c31af7Sopenharmony_ci		VK_SHARING_MODE_EXCLUSIVE,																			// VkSharingMode			sharingMode;
143e5c31af7Sopenharmony_ci		0u,																									// deUint32					queueFamilyIndexCount;
144e5c31af7Sopenharmony_ci		DE_NULL,																							// const deUint32*			pQueueFamilyIndices;
145e5c31af7Sopenharmony_ci		VK_IMAGE_LAYOUT_UNDEFINED																			// VkImageLayout			initialLayout;
146e5c31af7Sopenharmony_ci	};
147e5c31af7Sopenharmony_ci
148e5c31af7Sopenharmony_ci	return imageCreateInfo;
149e5c31af7Sopenharmony_ci}
150e5c31af7Sopenharmony_ci
151e5c31af7Sopenharmony_cistd::tuple<bool, VkQueue, deUint32> getQueueFamilyIndexAtExact (const DeviceInterface&		vkd,
152e5c31af7Sopenharmony_ci																const InstanceInterface&	vki,
153e5c31af7Sopenharmony_ci																VkPhysicalDevice			physDevice,
154e5c31af7Sopenharmony_ci																VkDevice					device,
155e5c31af7Sopenharmony_ci																VkQueueFlagBits				bits,
156e5c31af7Sopenharmony_ci																deUint32					queueIndex = 0)
157e5c31af7Sopenharmony_ci{
158e5c31af7Sopenharmony_ci	bool		found				= false;
159e5c31af7Sopenharmony_ci	VkQueue		queue				= 0;
160e5c31af7Sopenharmony_ci	deUint32	queueFamilyCount	= 0;
161e5c31af7Sopenharmony_ci	deUint32	queueFamilyIndex	= std::numeric_limits<deUint32>::max();
162e5c31af7Sopenharmony_ci
163e5c31af7Sopenharmony_ci	vki.getPhysicalDeviceQueueFamilyProperties(physDevice, &queueFamilyCount, nullptr);
164e5c31af7Sopenharmony_ci
165e5c31af7Sopenharmony_ci	std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
166e5c31af7Sopenharmony_ci	vki.getPhysicalDeviceQueueFamilyProperties(physDevice, &queueFamilyCount, queueFamilies.data());
167e5c31af7Sopenharmony_ci
168e5c31af7Sopenharmony_ci	for (uint32_t index = 0; index < queueFamilyCount; ++index)
169e5c31af7Sopenharmony_ci	{
170e5c31af7Sopenharmony_ci		if ((queueFamilies[index].queueFlags & bits) == bits)
171e5c31af7Sopenharmony_ci		{
172e5c31af7Sopenharmony_ci			queueFamilyIndex = index;
173e5c31af7Sopenharmony_ci			break;
174e5c31af7Sopenharmony_ci		}
175e5c31af7Sopenharmony_ci	}
176e5c31af7Sopenharmony_ci
177e5c31af7Sopenharmony_ci	if (std::numeric_limits<deUint32>::max() != queueFamilyIndex)
178e5c31af7Sopenharmony_ci	{
179e5c31af7Sopenharmony_ci		found = true;
180e5c31af7Sopenharmony_ci		vkd.getDeviceQueue(device, queueFamilyIndex, queueIndex, &queue);
181e5c31af7Sopenharmony_ci	}
182e5c31af7Sopenharmony_ci#ifdef __cpp_lib_constexpr_tuple
183e5c31af7Sopenharmony_ci	return { found, queue, queueFamilyIndex };
184e5c31af7Sopenharmony_ci#else
185e5c31af7Sopenharmony_ci    return std::tuple<bool, VkQueue, deUint32>(found, queue, queueFamilyIndex);
186e5c31af7Sopenharmony_ci#endif
187e5c31af7Sopenharmony_ci}
188e5c31af7Sopenharmony_ci
189e5c31af7Sopenharmony_citypedef std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	BlasVec;
190e5c31af7Sopenharmony_ciauto initTopAccelerationStructure (VkCommandBuffer		cmdBuffer,
191e5c31af7Sopenharmony_ci								   const BlasVec&		bottomLevelAccelerationStructures,
192e5c31af7Sopenharmony_ci								   Context&				context,
193e5c31af7Sopenharmony_ci								   const VkExtent3D&	imageExtent) -> de::MovePtr<TopLevelAccelerationStructure>
194e5c31af7Sopenharmony_ci{
195e5c31af7Sopenharmony_ci	const DeviceInterface&						vkd				= context.getDeviceInterface();
196e5c31af7Sopenharmony_ci	const VkDevice								device			= context.getDevice();
197e5c31af7Sopenharmony_ci	Allocator&									allocator		= context.getDefaultAllocator();
198e5c31af7Sopenharmony_ci	const deUint32								instanceCount	= imageExtent.depth * imageExtent.height * imageExtent.width / 2;
199e5c31af7Sopenharmony_ci
200e5c31af7Sopenharmony_ci	de::MovePtr<TopLevelAccelerationStructure>	result = makeTopLevelAccelerationStructure();
201e5c31af7Sopenharmony_ci	result->setInstanceCount(instanceCount);
202e5c31af7Sopenharmony_ci
203e5c31af7Sopenharmony_ci	deUint32 currentInstanceIndex = 0;
204e5c31af7Sopenharmony_ci
205e5c31af7Sopenharmony_ci	for (deUint32 z = 0; z < imageExtent.depth; ++z)
206e5c31af7Sopenharmony_ci	for (deUint32 y = 0; y < imageExtent.height; ++y)
207e5c31af7Sopenharmony_ci	for (deUint32 x = 0; x < imageExtent.width; ++x)
208e5c31af7Sopenharmony_ci	{
209e5c31af7Sopenharmony_ci		if (((x + y + z) % 2) == 0)
210e5c31af7Sopenharmony_ci			continue;
211e5c31af7Sopenharmony_ci		result->addInstance(bottomLevelAccelerationStructures[currentInstanceIndex++]);
212e5c31af7Sopenharmony_ci	}
213e5c31af7Sopenharmony_ci	result->createAndBuild(vkd, device, cmdBuffer, allocator);
214e5c31af7Sopenharmony_ci
215e5c31af7Sopenharmony_ci	return result;
216e5c31af7Sopenharmony_ci}
217e5c31af7Sopenharmony_ci
218e5c31af7Sopenharmony_ciclass RayTracingTraceRaysIndirectTestCase : public TestCase
219e5c31af7Sopenharmony_ci{
220e5c31af7Sopenharmony_ci	public:
221e5c31af7Sopenharmony_ci							RayTracingTraceRaysIndirectTestCase		(tcu::TestContext& context, const char* name, const TestParams data);
222e5c31af7Sopenharmony_ci							~RayTracingTraceRaysIndirectTestCase	(void);
223e5c31af7Sopenharmony_ci
224e5c31af7Sopenharmony_ci	virtual void			checkSupport								(Context& context) const;
225e5c31af7Sopenharmony_ci	virtual	void			initPrograms								(SourceCollections& programCollection) const;
226e5c31af7Sopenharmony_ci	virtual TestInstance*	createInstance								(Context& context) const;
227e5c31af7Sopenharmony_ciprivate:
228e5c31af7Sopenharmony_ci	TestParams				m_data;
229e5c31af7Sopenharmony_ci};
230e5c31af7Sopenharmony_ci
231e5c31af7Sopenharmony_ciclass RayTracingTraceRaysIndirectTestInstance : public TestInstance
232e5c31af7Sopenharmony_ci{
233e5c31af7Sopenharmony_cipublic:
234e5c31af7Sopenharmony_ci																	RayTracingTraceRaysIndirectTestInstance			(Context& context, const TestParams& data);
235e5c31af7Sopenharmony_ci																	~RayTracingTraceRaysIndirectTestInstance		(void);
236e5c31af7Sopenharmony_ci	tcu::TestStatus													iterate								(void);
237e5c31af7Sopenharmony_ci
238e5c31af7Sopenharmony_ciprotected:
239e5c31af7Sopenharmony_ci	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	initBottomAccelerationStructures	(VkCommandBuffer												cmdBuffer);
240e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>									runTest								();
241e5c31af7Sopenharmony_ci
242e5c31af7Sopenharmony_ciprivate:
243e5c31af7Sopenharmony_ci	TestParams														m_data;
244e5c31af7Sopenharmony_ci	VkExtent3D														m_imageExtent;
245e5c31af7Sopenharmony_ci};
246e5c31af7Sopenharmony_ci
247e5c31af7Sopenharmony_ci
248e5c31af7Sopenharmony_ciRayTracingTraceRaysIndirectTestCase::RayTracingTraceRaysIndirectTestCase (tcu::TestContext& context, const char* name, const TestParams data)
249e5c31af7Sopenharmony_ci	: vkt::TestCase	(context, name)
250e5c31af7Sopenharmony_ci	, m_data		(data)
251e5c31af7Sopenharmony_ci{
252e5c31af7Sopenharmony_ci}
253e5c31af7Sopenharmony_ci
254e5c31af7Sopenharmony_ciRayTracingTraceRaysIndirectTestCase::~RayTracingTraceRaysIndirectTestCase	(void)
255e5c31af7Sopenharmony_ci{
256e5c31af7Sopenharmony_ci}
257e5c31af7Sopenharmony_ci
258e5c31af7Sopenharmony_civoid RayTracingTraceRaysIndirectTestCase::checkSupport(Context& context) const
259e5c31af7Sopenharmony_ci{
260e5c31af7Sopenharmony_ci	context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
261e5c31af7Sopenharmony_ci	context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
262e5c31af7Sopenharmony_ci
263e5c31af7Sopenharmony_ci	const VkPhysicalDeviceRayTracingPipelineFeaturesKHR&	rayTracingPipelineFeaturesKHR		= context.getRayTracingPipelineFeatures();
264e5c31af7Sopenharmony_ci	if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE )
265e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
266e5c31af7Sopenharmony_ci
267e5c31af7Sopenharmony_ci	if (rayTracingPipelineFeaturesKHR.rayTracingPipelineTraceRaysIndirect == DE_FALSE)
268e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipelineTraceRaysIndirect");
269e5c31af7Sopenharmony_ci
270e5c31af7Sopenharmony_ci	if (m_data.useKhrMaintenance1Semantics) {
271e5c31af7Sopenharmony_ci		context.requireDeviceFunctionality("VK_KHR_ray_tracing_maintenance1");
272e5c31af7Sopenharmony_ci
273e5c31af7Sopenharmony_ci		const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(context.getInstanceInterface(), context.getPhysicalDevice());
274e5c31af7Sopenharmony_ci		if (!deviceFeatures.shaderInt64)
275e5c31af7Sopenharmony_ci		{
276e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "Device feature shaderInt64 is not supported");
277e5c31af7Sopenharmony_ci		}
278e5c31af7Sopenharmony_ci	}
279e5c31af7Sopenharmony_ci
280e5c31af7Sopenharmony_ci	const VkPhysicalDeviceAccelerationStructureFeaturesKHR&	accelerationStructureFeaturesKHR	= context.getAccelerationStructureFeatures();
281e5c31af7Sopenharmony_ci	if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
282e5c31af7Sopenharmony_ci		TCU_THROW(TestError, "VK_KHR_ray_tracing_pipeline requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
283e5c31af7Sopenharmony_ci}
284e5c31af7Sopenharmony_ci
285e5c31af7Sopenharmony_civoid RayTracingTraceRaysIndirectTestCase::initPrograms (SourceCollections& programCollection) const
286e5c31af7Sopenharmony_ci{
287e5c31af7Sopenharmony_ci	const vk::ShaderBuildOptions	buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
288e5c31af7Sopenharmony_ci	{
289e5c31af7Sopenharmony_ci		std::stringstream css;
290e5c31af7Sopenharmony_ci		css <<
291e5c31af7Sopenharmony_ci			"#version 460 core\n"
292e5c31af7Sopenharmony_ci			<< (m_data.useKhrMaintenance1Semantics ? "#extension GL_ARB_gpu_shader_int64: enable\n" : "\n") <<
293e5c31af7Sopenharmony_ci			"struct TraceRaysIndirectCommand\n"
294e5c31af7Sopenharmony_ci			"{\n";
295e5c31af7Sopenharmony_ci		if (m_data.useKhrMaintenance1Semantics)
296e5c31af7Sopenharmony_ci		{
297e5c31af7Sopenharmony_ci			css <<
298e5c31af7Sopenharmony_ci				"	uint64_t raygenShaderRecordAddress;\n"
299e5c31af7Sopenharmony_ci				"	uint64_t raygenShaderRecordSize;\n"
300e5c31af7Sopenharmony_ci				"	uint64_t missShaderBindingTableAddress;\n"
301e5c31af7Sopenharmony_ci				"	uint64_t missShaderBindingTableSize;\n"
302e5c31af7Sopenharmony_ci				"	uint64_t missShaderBindingTableStride;\n"
303e5c31af7Sopenharmony_ci				"	uint64_t hitShaderBindingTableAddress;\n"
304e5c31af7Sopenharmony_ci				"	uint64_t hitShaderBindingTableSize;\n"
305e5c31af7Sopenharmony_ci				"	uint64_t hitShaderBindingTableStride;\n"
306e5c31af7Sopenharmony_ci				"	uint64_t callableShaderBindingTableAddress;\n"
307e5c31af7Sopenharmony_ci				"	uint64_t callableShaderBindingTableSize;\n"
308e5c31af7Sopenharmony_ci				"	uint64_t callableShaderBindingTableStride;\n";
309e5c31af7Sopenharmony_ci		}
310e5c31af7Sopenharmony_ci		css <<
311e5c31af7Sopenharmony_ci			"	uint width;\n"
312e5c31af7Sopenharmony_ci			"	uint height;\n"
313e5c31af7Sopenharmony_ci			"	uint depth;\n"
314e5c31af7Sopenharmony_ci			"};\n"
315e5c31af7Sopenharmony_ci			"layout(binding = 0) uniform IndirectCommandsUBO\n"
316e5c31af7Sopenharmony_ci			"{\n"
317e5c31af7Sopenharmony_ci			"	TraceRaysIndirectCommand indirectCommands;\n"
318e5c31af7Sopenharmony_ci			"} ubo;\n"
319e5c31af7Sopenharmony_ci			"layout(binding = 1) buffer IndirectCommandsSBO\n"
320e5c31af7Sopenharmony_ci			"{\n"
321e5c31af7Sopenharmony_ci			"	TraceRaysIndirectCommand indirectCommands;\n"
322e5c31af7Sopenharmony_ci			"};\n"
323e5c31af7Sopenharmony_ci			"void main()\n"
324e5c31af7Sopenharmony_ci			"{\n";
325e5c31af7Sopenharmony_ci		if (m_data.useKhrMaintenance1Semantics)
326e5c31af7Sopenharmony_ci		{
327e5c31af7Sopenharmony_ci			css <<
328e5c31af7Sopenharmony_ci				"  indirectCommands.raygenShaderRecordAddress         = ubo.indirectCommands.raygenShaderRecordAddress;\n"
329e5c31af7Sopenharmony_ci				"  indirectCommands.raygenShaderRecordSize            = ubo.indirectCommands.raygenShaderRecordSize;\n"
330e5c31af7Sopenharmony_ci				"  indirectCommands.missShaderBindingTableAddress     = ubo.indirectCommands.missShaderBindingTableAddress;\n"
331e5c31af7Sopenharmony_ci				"  indirectCommands.missShaderBindingTableSize        = ubo.indirectCommands.missShaderBindingTableSize;\n"
332e5c31af7Sopenharmony_ci				"  indirectCommands.missShaderBindingTableStride      = ubo.indirectCommands.missShaderBindingTableStride;\n"
333e5c31af7Sopenharmony_ci				"  indirectCommands.hitShaderBindingTableAddress      = ubo.indirectCommands.hitShaderBindingTableAddress;\n"
334e5c31af7Sopenharmony_ci				"  indirectCommands.hitShaderBindingTableSize         = ubo.indirectCommands.hitShaderBindingTableSize;\n"
335e5c31af7Sopenharmony_ci				"  indirectCommands.hitShaderBindingTableStride       = ubo.indirectCommands.hitShaderBindingTableStride;\n"
336e5c31af7Sopenharmony_ci				"  indirectCommands.callableShaderBindingTableAddress = ubo.indirectCommands.callableShaderBindingTableAddress;\n"
337e5c31af7Sopenharmony_ci				"  indirectCommands.callableShaderBindingTableSize    = ubo.indirectCommands.callableShaderBindingTableSize;\n"
338e5c31af7Sopenharmony_ci				"  indirectCommands.callableShaderBindingTableStride  = ubo.indirectCommands.callableShaderBindingTableStride;\n";
339e5c31af7Sopenharmony_ci		}
340e5c31af7Sopenharmony_ci		css <<
341e5c31af7Sopenharmony_ci			"  indirectCommands.width  = ubo.indirectCommands.width;\n"
342e5c31af7Sopenharmony_ci			"  indirectCommands.height = ubo.indirectCommands.height;\n"
343e5c31af7Sopenharmony_ci			"  indirectCommands.depth  = ubo.indirectCommands.depth;\n"
344e5c31af7Sopenharmony_ci			"}\n";
345e5c31af7Sopenharmony_ci
346e5c31af7Sopenharmony_ci		programCollection.glslSources.add("compute_indirect_command") << glu::ComputeSource(css.str()) << buildOptions;
347e5c31af7Sopenharmony_ci	}
348e5c31af7Sopenharmony_ci
349e5c31af7Sopenharmony_ci	{
350e5c31af7Sopenharmony_ci		std::stringstream css;
351e5c31af7Sopenharmony_ci		css <<
352e5c31af7Sopenharmony_ci			"#version 460 core\n"
353e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
354e5c31af7Sopenharmony_ci			"layout(location = 0) rayPayloadEXT uvec4 hitValue;\n"
355e5c31af7Sopenharmony_ci			"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
356e5c31af7Sopenharmony_ci			"layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
357e5c31af7Sopenharmony_ci			"\n"
358e5c31af7Sopenharmony_ci			"void main()\n"
359e5c31af7Sopenharmony_ci			"{\n"
360e5c31af7Sopenharmony_ci			"  float tmin     = 0.0;\n"
361e5c31af7Sopenharmony_ci			"  float tmax     = 1.0;\n"
362e5c31af7Sopenharmony_ci			"  vec3  origin   = vec3(float(gl_LaunchIDEXT.x) + 0.5f, float(gl_LaunchIDEXT.y) + 0.5f, float(gl_LaunchIDEXT.z + 0.5f));\n"
363e5c31af7Sopenharmony_ci			"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
364e5c31af7Sopenharmony_ci			"  hitValue       = uvec4(0,0,0,0);\n"
365e5c31af7Sopenharmony_ci			"  traceRayEXT(topLevelAS, 0, 0xFF, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
366e5c31af7Sopenharmony_ci			"  imageStore(result, ivec3(gl_LaunchIDEXT), hitValue);\n"
367e5c31af7Sopenharmony_ci			"}\n";
368e5c31af7Sopenharmony_ci		programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
369e5c31af7Sopenharmony_ci	}
370e5c31af7Sopenharmony_ci
371e5c31af7Sopenharmony_ci	{
372e5c31af7Sopenharmony_ci		std::stringstream css;
373e5c31af7Sopenharmony_ci		css <<
374e5c31af7Sopenharmony_ci			"#version 460 core\n"
375e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
376e5c31af7Sopenharmony_ci			"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
377e5c31af7Sopenharmony_ci			"void main()\n"
378e5c31af7Sopenharmony_ci			"{\n"
379e5c31af7Sopenharmony_ci			"  hitValue = uvec4(" << kHitColorValue << ",0,0,1);\n"
380e5c31af7Sopenharmony_ci			"}\n";
381e5c31af7Sopenharmony_ci		programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
382e5c31af7Sopenharmony_ci	}
383e5c31af7Sopenharmony_ci
384e5c31af7Sopenharmony_ci	{
385e5c31af7Sopenharmony_ci		std::stringstream css;
386e5c31af7Sopenharmony_ci		css <<
387e5c31af7Sopenharmony_ci			"#version 460 core\n"
388e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
389e5c31af7Sopenharmony_ci			"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
390e5c31af7Sopenharmony_ci			"void main()\n"
391e5c31af7Sopenharmony_ci			"{\n"
392e5c31af7Sopenharmony_ci			"  hitValue = uvec4(" << kMissColorValue << ",0,0,1);\n"
393e5c31af7Sopenharmony_ci			"}\n";
394e5c31af7Sopenharmony_ci
395e5c31af7Sopenharmony_ci		programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
396e5c31af7Sopenharmony_ci	}
397e5c31af7Sopenharmony_ci}
398e5c31af7Sopenharmony_ci
399e5c31af7Sopenharmony_ciTestInstance* RayTracingTraceRaysIndirectTestCase::createInstance (Context& context) const
400e5c31af7Sopenharmony_ci{
401e5c31af7Sopenharmony_ci	return new RayTracingTraceRaysIndirectTestInstance(context, m_data);
402e5c31af7Sopenharmony_ci}
403e5c31af7Sopenharmony_ci
404e5c31af7Sopenharmony_ciRayTracingTraceRaysIndirectTestInstance::RayTracingTraceRaysIndirectTestInstance (Context& context, const TestParams& data)
405e5c31af7Sopenharmony_ci	: vkt::TestInstance		(context)
406e5c31af7Sopenharmony_ci	, m_data				(data)
407e5c31af7Sopenharmony_ci{
408e5c31af7Sopenharmony_ci	m_imageExtent = data.useKhrMaintenance1Semantics ? getImageExtent(data.extendedTraceDimensions) : getImageExtent(data.traceDimensions);
409e5c31af7Sopenharmony_ci}
410e5c31af7Sopenharmony_ci
411e5c31af7Sopenharmony_ciRayTracingTraceRaysIndirectTestInstance::~RayTracingTraceRaysIndirectTestInstance (void)
412e5c31af7Sopenharmony_ci{
413e5c31af7Sopenharmony_ci}
414e5c31af7Sopenharmony_ci
415e5c31af7Sopenharmony_cistd::vector<de::SharedPtr<BottomLevelAccelerationStructure> > RayTracingTraceRaysIndirectTestInstance::initBottomAccelerationStructures (VkCommandBuffer cmdBuffer)
416e5c31af7Sopenharmony_ci{
417e5c31af7Sopenharmony_ci	const DeviceInterface&											vkd			= m_context.getDeviceInterface();
418e5c31af7Sopenharmony_ci	const VkDevice													device		= m_context.getDevice();
419e5c31af7Sopenharmony_ci	Allocator&														allocator	= m_context.getDefaultAllocator();
420e5c31af7Sopenharmony_ci	std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >	result;
421e5c31af7Sopenharmony_ci
422e5c31af7Sopenharmony_ci	tcu::Vec3 v0(0.0, 1.0, 0.0);
423e5c31af7Sopenharmony_ci	tcu::Vec3 v1(0.0, 0.0, 0.0);
424e5c31af7Sopenharmony_ci	tcu::Vec3 v2(1.0, 1.0, 0.0);
425e5c31af7Sopenharmony_ci	tcu::Vec3 v3(1.0, 0.0, 0.0);
426e5c31af7Sopenharmony_ci
427e5c31af7Sopenharmony_ci	for (deUint32 z = 0; z < m_imageExtent.depth; ++z)
428e5c31af7Sopenharmony_ci	for (deUint32 y = 0; y < m_imageExtent.height; ++y)
429e5c31af7Sopenharmony_ci	for (deUint32 x = 0; x < m_imageExtent.width; ++x)
430e5c31af7Sopenharmony_ci	{
431e5c31af7Sopenharmony_ci		// let's build a 3D chessboard of geometries
432e5c31af7Sopenharmony_ci		if (((x + y + z) % 2) == 0)
433e5c31af7Sopenharmony_ci			continue;
434e5c31af7Sopenharmony_ci		tcu::Vec3 xyz((float)x, (float)y, (float)z);
435e5c31af7Sopenharmony_ci		std::vector<tcu::Vec3>	geometryData;
436e5c31af7Sopenharmony_ci
437e5c31af7Sopenharmony_ci		de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
438e5c31af7Sopenharmony_ci		bottomLevelAccelerationStructure->setGeometryCount(1u);
439e5c31af7Sopenharmony_ci
440e5c31af7Sopenharmony_ci		geometryData.push_back(xyz + v0);
441e5c31af7Sopenharmony_ci		geometryData.push_back(xyz + v1);
442e5c31af7Sopenharmony_ci		geometryData.push_back(xyz + v2);
443e5c31af7Sopenharmony_ci		geometryData.push_back(xyz + v2);
444e5c31af7Sopenharmony_ci		geometryData.push_back(xyz + v1);
445e5c31af7Sopenharmony_ci		geometryData.push_back(xyz + v3);
446e5c31af7Sopenharmony_ci
447e5c31af7Sopenharmony_ci		bottomLevelAccelerationStructure->addGeometry(geometryData, true);
448e5c31af7Sopenharmony_ci		bottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
449e5c31af7Sopenharmony_ci		result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
450e5c31af7Sopenharmony_ci	}
451e5c31af7Sopenharmony_ci
452e5c31af7Sopenharmony_ci	return result;
453e5c31af7Sopenharmony_ci}
454e5c31af7Sopenharmony_ci
455e5c31af7Sopenharmony_cide::MovePtr<BufferWithMemory> RayTracingTraceRaysIndirectTestInstance::runTest()
456e5c31af7Sopenharmony_ci{
457e5c31af7Sopenharmony_ci	const InstanceInterface&			vki									= m_context.getInstanceInterface();
458e5c31af7Sopenharmony_ci	const DeviceInterface&				vkd									= m_context.getDeviceInterface();
459e5c31af7Sopenharmony_ci	const VkDevice						device								= m_context.getDevice();
460e5c31af7Sopenharmony_ci	const VkPhysicalDevice				physicalDevice						= m_context.getPhysicalDevice();
461e5c31af7Sopenharmony_ci	const deUint32						queueFamilyIndex					= m_context.getUniversalQueueFamilyIndex();
462e5c31af7Sopenharmony_ci	const VkQueue						queue								= m_context.getUniversalQueue();
463e5c31af7Sopenharmony_ci	Allocator&							allocator							= m_context.getDefaultAllocator();
464e5c31af7Sopenharmony_ci	const deUint32						pixelCount							= m_imageExtent.depth * m_imageExtent.height * m_imageExtent.width;
465e5c31af7Sopenharmony_ci	const deUint32						shaderGroupHandleSize				= getShaderGroupSize(vki, physicalDevice);
466e5c31af7Sopenharmony_ci	const deUint32						shaderGroupBaseAlignment			= getShaderGroupBaseAlignment(vki, physicalDevice);
467e5c31af7Sopenharmony_ci
468e5c31af7Sopenharmony_ci	Move<VkDescriptorSetLayout>			computeDescriptorSetLayout;
469e5c31af7Sopenharmony_ci	Move<VkDescriptorPool>				computeDescriptorPool;
470e5c31af7Sopenharmony_ci	Move<VkDescriptorSet>				computeDescriptorSet;
471e5c31af7Sopenharmony_ci	Move<VkPipelineLayout>				computePipelineLayout;
472e5c31af7Sopenharmony_ci	Move<VkShaderModule>				computeShader;
473e5c31af7Sopenharmony_ci	Move<VkPipeline>					computePipeline;
474e5c31af7Sopenharmony_ci
475e5c31af7Sopenharmony_ci	if (m_data.traceType == TraceType::INDIRECT_GPU || m_data.traceType == TraceType::INDIRECT2_GPU)
476e5c31af7Sopenharmony_ci	{
477e5c31af7Sopenharmony_ci		computeDescriptorSetLayout			= DescriptorSetLayoutBuilder()
478e5c31af7Sopenharmony_ci													.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
479e5c31af7Sopenharmony_ci													.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
480e5c31af7Sopenharmony_ci													.build(vkd, device);
481e5c31af7Sopenharmony_ci		computeDescriptorPool				= DescriptorPoolBuilder()
482e5c31af7Sopenharmony_ci													.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
483e5c31af7Sopenharmony_ci													.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
484e5c31af7Sopenharmony_ci													.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
485e5c31af7Sopenharmony_ci		computeDescriptorSet				= makeDescriptorSet(vkd, device, *computeDescriptorPool, *computeDescriptorSetLayout);
486e5c31af7Sopenharmony_ci		computePipelineLayout				= makePipelineLayout(vkd, device, computeDescriptorSetLayout.get());
487e5c31af7Sopenharmony_ci
488e5c31af7Sopenharmony_ci		computeShader						= createShaderModule(vkd, device, m_context.getBinaryCollection().get("compute_indirect_command"), 0);
489e5c31af7Sopenharmony_ci		const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
490e5c31af7Sopenharmony_ci		{
491e5c31af7Sopenharmony_ci			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
492e5c31af7Sopenharmony_ci			DE_NULL,												// const void*							pNext;
493e5c31af7Sopenharmony_ci			VkPipelineShaderStageCreateFlags(0u),					// VkPipelineShaderStageCreateFlags		flags;
494e5c31af7Sopenharmony_ci			VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
495e5c31af7Sopenharmony_ci			*computeShader,											// VkShaderModule						module;
496e5c31af7Sopenharmony_ci			"main",													// const char*							pName;
497e5c31af7Sopenharmony_ci			DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
498e5c31af7Sopenharmony_ci		};
499e5c31af7Sopenharmony_ci		const VkComputePipelineCreateInfo pipelineCreateInfo =
500e5c31af7Sopenharmony_ci		{
501e5c31af7Sopenharmony_ci			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
502e5c31af7Sopenharmony_ci			DE_NULL,											// const void*						pNext;
503e5c31af7Sopenharmony_ci			VkPipelineCreateFlags(0u),							// VkPipelineCreateFlags			flags;
504e5c31af7Sopenharmony_ci			pipelineShaderStageParams,							// VkPipelineShaderStageCreateInfo	stage;
505e5c31af7Sopenharmony_ci			*computePipelineLayout,								// VkPipelineLayout					layout;
506e5c31af7Sopenharmony_ci			DE_NULL,											// VkPipeline						basePipelineHandle;
507e5c31af7Sopenharmony_ci			0,													// deInt32							basePipelineIndex;
508e5c31af7Sopenharmony_ci		};
509e5c31af7Sopenharmony_ci
510e5c31af7Sopenharmony_ci		computePipeline = vk::createComputePipeline(vkd, device, (VkPipelineCache)0u, &pipelineCreateInfo);
511e5c31af7Sopenharmony_ci	}
512e5c31af7Sopenharmony_ci
513e5c31af7Sopenharmony_ci	const Move<VkDescriptorSetLayout>	descriptorSetLayout					= DescriptorSetLayoutBuilder()
514e5c31af7Sopenharmony_ci																					.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
515e5c31af7Sopenharmony_ci																					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
516e5c31af7Sopenharmony_ci																					.build(vkd, device);
517e5c31af7Sopenharmony_ci	const Move<VkDescriptorPool>		descriptorPool						= DescriptorPoolBuilder()
518e5c31af7Sopenharmony_ci																					.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
519e5c31af7Sopenharmony_ci																					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
520e5c31af7Sopenharmony_ci																					.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
521e5c31af7Sopenharmony_ci	const Move<VkDescriptorSet>			descriptorSet						= makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
522e5c31af7Sopenharmony_ci	const Move<VkPipelineLayout>		pipelineLayout						= makePipelineLayout(vkd, device, descriptorSetLayout.get());
523e5c31af7Sopenharmony_ci
524e5c31af7Sopenharmony_ci	de::MovePtr<RayTracingPipeline>		rayTracingPipeline					= de::newMovePtr<RayTracingPipeline>();
525e5c31af7Sopenharmony_ci	rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR,		createShaderModule(vkd, device, m_context.getBinaryCollection().get("rgen"), 0), 0);
526e5c31af7Sopenharmony_ci	rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,	createShaderModule(vkd, device, m_context.getBinaryCollection().get("chit"), 0), 1);
527e5c31af7Sopenharmony_ci	rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR,			createShaderModule(vkd, device, m_context.getBinaryCollection().get("miss"), 0), 2);
528e5c31af7Sopenharmony_ci	Move<VkPipeline>					pipeline							= rayTracingPipeline->createPipeline(vkd, device, *pipelineLayout);
529e5c31af7Sopenharmony_ci
530e5c31af7Sopenharmony_ci	const de::MovePtr<BufferWithMemory>	raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1 );
531e5c31af7Sopenharmony_ci	const de::MovePtr<BufferWithMemory>	hitShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1 );
532e5c31af7Sopenharmony_ci	const de::MovePtr<BufferWithMemory>	missShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1 );
533e5c31af7Sopenharmony_ci
534e5c31af7Sopenharmony_ci	const VkStridedDeviceAddressRegionKHR	raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
535e5c31af7Sopenharmony_ci	const VkStridedDeviceAddressRegionKHR	missShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
536e5c31af7Sopenharmony_ci	const VkStridedDeviceAddressRegionKHR	hitShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
537e5c31af7Sopenharmony_ci	const VkStridedDeviceAddressRegionKHR	callableShaderBindingTableRegion= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
538e5c31af7Sopenharmony_ci
539e5c31af7Sopenharmony_ci	const VkFormat						imageFormat							= VK_FORMAT_R32_UINT;
540e5c31af7Sopenharmony_ci	const VkImageCreateInfo				imageCreateInfo						= makeImageCreateInfo(m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, imageFormat);
541e5c31af7Sopenharmony_ci	const VkImageSubresourceRange		imageSubresourceRange				= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0, 1u);
542e5c31af7Sopenharmony_ci	const de::MovePtr<ImageWithMemory>	image								= de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
543e5c31af7Sopenharmony_ci	const Move<VkImageView>				imageView							= makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, imageFormat, imageSubresourceRange);
544e5c31af7Sopenharmony_ci
545e5c31af7Sopenharmony_ci	const VkBufferCreateInfo			resultBufferCreateInfo				= makeBufferCreateInfo(pixelCount*sizeof(deUint32), VK_BUFFER_USAGE_TRANSFER_DST_BIT);
546e5c31af7Sopenharmony_ci	const VkImageSubresourceLayers		resultBufferImageSubresourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
547e5c31af7Sopenharmony_ci	const VkBufferImageCopy				resultBufferImageRegion				= makeBufferImageCopy(m_imageExtent, resultBufferImageSubresourceLayers);
548e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>		resultBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
549e5c31af7Sopenharmony_ci
550e5c31af7Sopenharmony_ci	const VkDescriptorImageInfo			descriptorImageInfo					= makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
551e5c31af7Sopenharmony_ci
552e5c31af7Sopenharmony_ci	// create indirect command buffer and fill it with parameter values
553e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>		indirectBuffer;
554e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>		uniformBuffer;
555e5c31af7Sopenharmony_ci
556e5c31af7Sopenharmony_ci	// Update trace details according to VK_KHR_ray_tracing_maintenance1 semantics
557e5c31af7Sopenharmony_ci	m_data.extendedTraceDimensions.raygenShaderRecordAddress			= raygenShaderBindingTableRegion.deviceAddress;
558e5c31af7Sopenharmony_ci	m_data.extendedTraceDimensions.raygenShaderRecordSize				= raygenShaderBindingTableRegion.size;
559e5c31af7Sopenharmony_ci	m_data.extendedTraceDimensions.missShaderBindingTableAddress		= missShaderBindingTableRegion.deviceAddress;
560e5c31af7Sopenharmony_ci	m_data.extendedTraceDimensions.missShaderBindingTableSize			= missShaderBindingTableRegion.size;
561e5c31af7Sopenharmony_ci	m_data.extendedTraceDimensions.missShaderBindingTableStride			= missShaderBindingTableRegion.stride;
562e5c31af7Sopenharmony_ci	m_data.extendedTraceDimensions.hitShaderBindingTableAddress			= hitShaderBindingTableRegion.deviceAddress;
563e5c31af7Sopenharmony_ci	m_data.extendedTraceDimensions.hitShaderBindingTableSize			= hitShaderBindingTableRegion.size;
564e5c31af7Sopenharmony_ci	m_data.extendedTraceDimensions.hitShaderBindingTableStride			= hitShaderBindingTableRegion.stride;
565e5c31af7Sopenharmony_ci	m_data.extendedTraceDimensions.callableShaderBindingTableAddress	= callableShaderBindingTableRegion.deviceAddress;
566e5c31af7Sopenharmony_ci	m_data.extendedTraceDimensions.callableShaderBindingTableSize		= callableShaderBindingTableRegion.size;
567e5c31af7Sopenharmony_ci	m_data.extendedTraceDimensions.callableShaderBindingTableStride		= callableShaderBindingTableRegion.stride;
568e5c31af7Sopenharmony_ci
569e5c31af7Sopenharmony_ci	if (m_data.traceType != TraceType::DIRECT)
570e5c31af7Sopenharmony_ci	{
571e5c31af7Sopenharmony_ci		const bool							indirectGpu = (m_data.traceType == TraceType::INDIRECT_GPU || m_data.traceType == TraceType::INDIRECT2_GPU);
572e5c31af7Sopenharmony_ci		VkDeviceSize						bufferSize = m_data.useKhrMaintenance1Semantics ?  sizeof(VkTraceRaysIndirectCommand2KHR) : sizeof(VkTraceRaysIndirectCommandKHR);
573e5c31af7Sopenharmony_ci		VkBufferUsageFlags					indirectBufferUsageFlags = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | (indirectGpu ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : VK_BUFFER_USAGE_TRANSFER_DST_BIT);
574e5c31af7Sopenharmony_ci		const VkBufferCreateInfo			indirectBufferCreateInfo = makeBufferCreateInfo(bufferSize, indirectBufferUsageFlags);
575e5c31af7Sopenharmony_ci		vk::MemoryRequirement				indirectBufferMemoryRequirement = MemoryRequirement::DeviceAddress | (indirectGpu ? MemoryRequirement::Any : MemoryRequirement::HostVisible);
576e5c31af7Sopenharmony_ci		indirectBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, indirectBufferCreateInfo, indirectBufferMemoryRequirement));
577e5c31af7Sopenharmony_ci	}
578e5c31af7Sopenharmony_ci
579e5c31af7Sopenharmony_ci	if (m_data.traceType == TraceType::INDIRECT_GPU)
580e5c31af7Sopenharmony_ci	{
581e5c31af7Sopenharmony_ci		const VkBufferCreateInfo			uniformBufferCreateInfo = makeBufferCreateInfo(sizeof(VkTraceRaysIndirectCommandKHR), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
582e5c31af7Sopenharmony_ci		uniformBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible));
583e5c31af7Sopenharmony_ci		deMemcpy(uniformBuffer->getAllocation().getHostPtr(), &m_data.traceDimensions, sizeof(VkTraceRaysIndirectCommandKHR));
584e5c31af7Sopenharmony_ci		flushMappedMemoryRange(vkd, device, uniformBuffer->getAllocation().getMemory(), uniformBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
585e5c31af7Sopenharmony_ci	}
586e5c31af7Sopenharmony_ci	else if (m_data.traceType == TraceType::INDIRECT_CPU)
587e5c31af7Sopenharmony_ci	{
588e5c31af7Sopenharmony_ci		deMemcpy(indirectBuffer->getAllocation().getHostPtr(), &m_data.traceDimensions, sizeof(VkTraceRaysIndirectCommandKHR));
589e5c31af7Sopenharmony_ci		flushMappedMemoryRange(vkd, device, indirectBuffer->getAllocation().getMemory(), indirectBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
590e5c31af7Sopenharmony_ci	}
591e5c31af7Sopenharmony_ci	else if (m_data.traceType == TraceType::INDIRECT2_GPU)
592e5c31af7Sopenharmony_ci	{
593e5c31af7Sopenharmony_ci		const VkBufferCreateInfo			uniformBufferCreateInfo = makeBufferCreateInfo(sizeof(VkTraceRaysIndirectCommand2KHR), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
594e5c31af7Sopenharmony_ci		uniformBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible));
595e5c31af7Sopenharmony_ci		deMemcpy(uniformBuffer->getAllocation().getHostPtr(), &m_data.extendedTraceDimensions, sizeof(VkTraceRaysIndirectCommand2KHR));
596e5c31af7Sopenharmony_ci		flushMappedMemoryRange(vkd, device, uniformBuffer->getAllocation().getMemory(), uniformBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
597e5c31af7Sopenharmony_ci	}
598e5c31af7Sopenharmony_ci	else if (m_data.traceType == TraceType::INDIRECT2_CPU)
599e5c31af7Sopenharmony_ci	{
600e5c31af7Sopenharmony_ci		deMemcpy(indirectBuffer->getAllocation().getHostPtr(), &m_data.extendedTraceDimensions, sizeof(VkTraceRaysIndirectCommand2KHR));
601e5c31af7Sopenharmony_ci		flushMappedMemoryRange(vkd, device, indirectBuffer->getAllocation().getMemory(), indirectBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
602e5c31af7Sopenharmony_ci	}
603e5c31af7Sopenharmony_ci
604e5c31af7Sopenharmony_ci	const Move<VkCommandPool>			cmdPool								= createCommandPool(vkd, device, 0, queueFamilyIndex);
605e5c31af7Sopenharmony_ci	const Move<VkCommandBuffer>			cmdBuffer							= allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
606e5c31af7Sopenharmony_ci
607e5c31af7Sopenharmony_ci	std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >	bottomLevelAccelerationStructures;
608e5c31af7Sopenharmony_ci	de::MovePtr<TopLevelAccelerationStructure>						topLevelAccelerationStructure;
609e5c31af7Sopenharmony_ci
610e5c31af7Sopenharmony_ci	beginCommandBuffer(vkd, *cmdBuffer, 0u);
611e5c31af7Sopenharmony_ci	{
612e5c31af7Sopenharmony_ci		const VkImageMemoryBarrier			preImageBarrier						= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
613e5c31af7Sopenharmony_ci																					VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
614e5c31af7Sopenharmony_ci																					**image, imageSubresourceRange);
615e5c31af7Sopenharmony_ci		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
616e5c31af7Sopenharmony_ci
617e5c31af7Sopenharmony_ci		const VkClearValue					clearValue							= makeClearValueColorU32(kClearColorValue, 0u, 0u, 0u);
618e5c31af7Sopenharmony_ci		vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
619e5c31af7Sopenharmony_ci
620e5c31af7Sopenharmony_ci		const VkImageMemoryBarrier			postImageBarrier					= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
621e5c31af7Sopenharmony_ci																					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
622e5c31af7Sopenharmony_ci																					**image, imageSubresourceRange);
623e5c31af7Sopenharmony_ci		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
624e5c31af7Sopenharmony_ci
625e5c31af7Sopenharmony_ci		bottomLevelAccelerationStructures	= initBottomAccelerationStructures(*cmdBuffer);
626e5c31af7Sopenharmony_ci		topLevelAccelerationStructure		= initTopAccelerationStructure(*cmdBuffer, bottomLevelAccelerationStructures, m_context, m_imageExtent);
627e5c31af7Sopenharmony_ci
628e5c31af7Sopenharmony_ci		if (m_data.traceType == TraceType::INDIRECT_GPU)
629e5c31af7Sopenharmony_ci		{
630e5c31af7Sopenharmony_ci			const VkDescriptorBufferInfo	uniformBufferDescriptorInfo = makeDescriptorBufferInfo(uniformBuffer->get(), 0ull, sizeof(VkTraceRaysIndirectCommandKHR));
631e5c31af7Sopenharmony_ci			const VkDescriptorBufferInfo	indirectBufferDescriptorInfo = makeDescriptorBufferInfo(indirectBuffer->get(), 0ull, sizeof(VkTraceRaysIndirectCommandKHR));
632e5c31af7Sopenharmony_ci
633e5c31af7Sopenharmony_ci			DescriptorSetUpdateBuilder()
634e5c31af7Sopenharmony_ci				.writeSingle(*computeDescriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &uniformBufferDescriptorInfo)
635e5c31af7Sopenharmony_ci				.writeSingle(*computeDescriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &indirectBufferDescriptorInfo)
636e5c31af7Sopenharmony_ci				.update(vkd, device);
637e5c31af7Sopenharmony_ci
638e5c31af7Sopenharmony_ci			vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
639e5c31af7Sopenharmony_ci			vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipelineLayout, 0u, 1u, &computeDescriptorSet.get(), 0u, DE_NULL);
640e5c31af7Sopenharmony_ci			vkd.cmdDispatch(*cmdBuffer, 1, 1, 1);
641e5c31af7Sopenharmony_ci
642e5c31af7Sopenharmony_ci			const VkBufferMemoryBarrier		fillIndirectBufferMemoryBarrier	= makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
643e5c31af7Sopenharmony_ci																				indirectBuffer->get(), 0ull, sizeof(VkTraceRaysIndirectCommandKHR));
644e5c31af7Sopenharmony_ci			cmdPipelineBufferMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, &fillIndirectBufferMemoryBarrier);
645e5c31af7Sopenharmony_ci		}
646e5c31af7Sopenharmony_ci		else if (m_data.traceType == TraceType::INDIRECT2_GPU)
647e5c31af7Sopenharmony_ci		{
648e5c31af7Sopenharmony_ci			const VkDescriptorBufferInfo	uniformBufferDescriptorInfo = makeDescriptorBufferInfo(uniformBuffer->get(), 0ull, sizeof(VkTraceRaysIndirectCommand2KHR));
649e5c31af7Sopenharmony_ci			const VkDescriptorBufferInfo	indirectBufferDescriptorInfo = makeDescriptorBufferInfo(indirectBuffer->get(), 0ull, sizeof(VkTraceRaysIndirectCommand2KHR));
650e5c31af7Sopenharmony_ci
651e5c31af7Sopenharmony_ci			DescriptorSetUpdateBuilder()
652e5c31af7Sopenharmony_ci				.writeSingle(*computeDescriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &uniformBufferDescriptorInfo)
653e5c31af7Sopenharmony_ci				.writeSingle(*computeDescriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &indirectBufferDescriptorInfo)
654e5c31af7Sopenharmony_ci				.update(vkd, device);
655e5c31af7Sopenharmony_ci
656e5c31af7Sopenharmony_ci			vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
657e5c31af7Sopenharmony_ci			vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipelineLayout, 0u, 1u, &computeDescriptorSet.get(), 0u, DE_NULL);
658e5c31af7Sopenharmony_ci			vkd.cmdDispatch(*cmdBuffer, 1, 1, 1);
659e5c31af7Sopenharmony_ci
660e5c31af7Sopenharmony_ci			const VkBufferMemoryBarrier		fillIndirectBufferMemoryBarrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
661e5c31af7Sopenharmony_ci																				indirectBuffer->get(), 0ull, sizeof(VkTraceRaysIndirectCommand2KHR));
662e5c31af7Sopenharmony_ci			cmdPipelineBufferMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, &fillIndirectBufferMemoryBarrier);
663e5c31af7Sopenharmony_ci
664e5c31af7Sopenharmony_ci		}
665e5c31af7Sopenharmony_ci
666e5c31af7Sopenharmony_ci		const TopLevelAccelerationStructure*			topLevelAccelerationStructurePtr		= topLevelAccelerationStructure.get();
667e5c31af7Sopenharmony_ci		VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet	=
668e5c31af7Sopenharmony_ci		{
669e5c31af7Sopenharmony_ci			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
670e5c31af7Sopenharmony_ci			DE_NULL,															//  const void*							pNext;
671e5c31af7Sopenharmony_ci			1u,																	//  deUint32							accelerationStructureCount;
672e5c31af7Sopenharmony_ci			topLevelAccelerationStructurePtr->getPtr(),							//  const VkAccelerationStructureKHR*	pAccelerationStructures;
673e5c31af7Sopenharmony_ci		};
674e5c31af7Sopenharmony_ci
675e5c31af7Sopenharmony_ci		DescriptorSetUpdateBuilder()
676e5c31af7Sopenharmony_ci			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
677e5c31af7Sopenharmony_ci			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
678e5c31af7Sopenharmony_ci			.update(vkd, device);
679e5c31af7Sopenharmony_ci
680e5c31af7Sopenharmony_ci		vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
681e5c31af7Sopenharmony_ci
682e5c31af7Sopenharmony_ci		vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipeline);
683e5c31af7Sopenharmony_ci
684e5c31af7Sopenharmony_ci		// Both calls should give the same results.
685e5c31af7Sopenharmony_ci		if (m_data.traceType == TraceType::DIRECT)
686e5c31af7Sopenharmony_ci		{
687e5c31af7Sopenharmony_ci			cmdTraceRays(vkd,
688e5c31af7Sopenharmony_ci				*cmdBuffer,
689e5c31af7Sopenharmony_ci				&raygenShaderBindingTableRegion,
690e5c31af7Sopenharmony_ci				&missShaderBindingTableRegion,
691e5c31af7Sopenharmony_ci				&hitShaderBindingTableRegion,
692e5c31af7Sopenharmony_ci				&callableShaderBindingTableRegion,
693e5c31af7Sopenharmony_ci				m_data.traceDimensions.width, m_data.traceDimensions.height, m_data.traceDimensions.depth);
694e5c31af7Sopenharmony_ci		}
695e5c31af7Sopenharmony_ci		else if(m_data.traceType == TraceType::INDIRECT_CPU || m_data.traceType == TraceType::INDIRECT_GPU)
696e5c31af7Sopenharmony_ci		{
697e5c31af7Sopenharmony_ci			cmdTraceRaysIndirect(vkd,
698e5c31af7Sopenharmony_ci				*cmdBuffer,
699e5c31af7Sopenharmony_ci				&raygenShaderBindingTableRegion,
700e5c31af7Sopenharmony_ci				&missShaderBindingTableRegion,
701e5c31af7Sopenharmony_ci				&hitShaderBindingTableRegion,
702e5c31af7Sopenharmony_ci				&callableShaderBindingTableRegion,
703e5c31af7Sopenharmony_ci				getBufferDeviceAddress(vkd, device, indirectBuffer->get(), 0));
704e5c31af7Sopenharmony_ci		}
705e5c31af7Sopenharmony_ci		else if (m_data.traceType == TraceType::INDIRECT2_CPU || m_data.traceType == TraceType::INDIRECT2_GPU)
706e5c31af7Sopenharmony_ci		{
707e5c31af7Sopenharmony_ci			vkd.cmdTraceRaysIndirect2KHR(
708e5c31af7Sopenharmony_ci				*cmdBuffer,
709e5c31af7Sopenharmony_ci				getBufferDeviceAddress(vkd, device, indirectBuffer->get(), 0));
710e5c31af7Sopenharmony_ci		}
711e5c31af7Sopenharmony_ci
712e5c31af7Sopenharmony_ci		const VkMemoryBarrier							postTraceMemoryBarrier					= makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
713e5c31af7Sopenharmony_ci		const VkMemoryBarrier							postCopyMemoryBarrier					= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
714e5c31af7Sopenharmony_ci		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier);
715e5c31af7Sopenharmony_ci
716e5c31af7Sopenharmony_ci		vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
717e5c31af7Sopenharmony_ci
718e5c31af7Sopenharmony_ci		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
719e5c31af7Sopenharmony_ci	}
720e5c31af7Sopenharmony_ci	endCommandBuffer(vkd, *cmdBuffer);
721e5c31af7Sopenharmony_ci
722e5c31af7Sopenharmony_ci	submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
723e5c31af7Sopenharmony_ci
724e5c31af7Sopenharmony_ci	invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
725e5c31af7Sopenharmony_ci
726e5c31af7Sopenharmony_ci	return resultBuffer;
727e5c31af7Sopenharmony_ci}
728e5c31af7Sopenharmony_ci
729e5c31af7Sopenharmony_citcu::TestStatus RayTracingTraceRaysIndirectTestInstance::iterate (void)
730e5c31af7Sopenharmony_ci{
731e5c31af7Sopenharmony_ci	// run test using arrays of pointers
732e5c31af7Sopenharmony_ci	const de::MovePtr<BufferWithMemory>	buffer		= runTest();
733e5c31af7Sopenharmony_ci	const deUint32*						bufferPtr	= (deUint32*)buffer->getAllocation().getHostPtr();
734e5c31af7Sopenharmony_ci	const bool							noWrites	= m_data.useKhrMaintenance1Semantics ? isNullTrace(m_data.extendedTraceDimensions) : isNullTrace(m_data.traceDimensions);
735e5c31af7Sopenharmony_ci
736e5c31af7Sopenharmony_ci	deUint32							failures		= 0;
737e5c31af7Sopenharmony_ci	deUint32							pos				= 0;
738e5c31af7Sopenharmony_ci
739e5c31af7Sopenharmony_ci	// verify results
740e5c31af7Sopenharmony_ci	for (deUint32 z = 0; z < m_imageExtent.depth; ++z)
741e5c31af7Sopenharmony_ci	for (deUint32 y = 0; y < m_imageExtent.height; ++y)
742e5c31af7Sopenharmony_ci	for (deUint32 x = 0; x < m_imageExtent.width; ++x)
743e5c31af7Sopenharmony_ci	{
744e5c31af7Sopenharmony_ci		const deUint32 expectedResult = (noWrites ? kClearColorValue : (((x + y + z) % 2) ? kHitColorValue : kMissColorValue));
745e5c31af7Sopenharmony_ci		if (bufferPtr[pos] != expectedResult)
746e5c31af7Sopenharmony_ci			failures++;
747e5c31af7Sopenharmony_ci		++pos;
748e5c31af7Sopenharmony_ci	}
749e5c31af7Sopenharmony_ci
750e5c31af7Sopenharmony_ci	if (failures == 0)
751e5c31af7Sopenharmony_ci		return tcu::TestStatus::pass("Pass");
752e5c31af7Sopenharmony_ci	else
753e5c31af7Sopenharmony_ci		return tcu::TestStatus::fail("Fail (failures=" + de::toString(failures) + ")");
754e5c31af7Sopenharmony_ci}
755e5c31af7Sopenharmony_ci
756e5c31af7Sopenharmony_citemplate<typename T>
757e5c31af7Sopenharmony_cistd::string makeDimensionsName (const T cmd)
758e5c31af7Sopenharmony_ci{
759e5c31af7Sopenharmony_ci	std::ostringstream name;
760e5c31af7Sopenharmony_ci	name << cmd.width << "_" << cmd.height << "_" << cmd.depth;
761e5c31af7Sopenharmony_ci	return name.str();
762e5c31af7Sopenharmony_ci}
763e5c31af7Sopenharmony_ci
764e5c31af7Sopenharmony_ciusing namespace tcu;
765e5c31af7Sopenharmony_ci
766e5c31af7Sopenharmony_ciclass TraceRaysIndirect2Instance : public TestInstance
767e5c31af7Sopenharmony_ci{
768e5c31af7Sopenharmony_cipublic:
769e5c31af7Sopenharmony_ci						TraceRaysIndirect2Instance	(Context&					context,
770e5c31af7Sopenharmony_ci													 const TestParams2&			params);
771e5c31af7Sopenharmony_ci	virtual				~TraceRaysIndirect2Instance	(void) override = default;
772e5c31af7Sopenharmony_ci	virtual TestStatus	iterate						(void) override;
773e5c31af7Sopenharmony_ci
774e5c31af7Sopenharmony_ciprotected:
775e5c31af7Sopenharmony_ci	void				makeIndirectStructAndFlush	(BufferWithMemory&			buffer,
776e5c31af7Sopenharmony_ci													 const bool					source,
777e5c31af7Sopenharmony_ci													 const BufferWithMemory&	rgenSbt,
778e5c31af7Sopenharmony_ci													 const BufferWithMemory&	hitSbt,
779e5c31af7Sopenharmony_ci													 const BufferWithMemory&	missSbt,
780e5c31af7Sopenharmony_ci													 const BufferWithMemory&	callSbt) const;
781e5c31af7Sopenharmony_ci	void				initBottomAccellStructures	(VkCommandBuffer			cmdBuffer,
782e5c31af7Sopenharmony_ci													 BottomLevelAccelerationStructurePool&	pool,
783e5c31af7Sopenharmony_ci													 const deUint32&			batchStructCount) const;
784e5c31af7Sopenharmony_ciprivate:
785e5c31af7Sopenharmony_ci	TestParams2			m_params;
786e5c31af7Sopenharmony_ci	const VkExtent3D	m_imageExtent;
787e5c31af7Sopenharmony_ci};
788e5c31af7Sopenharmony_ci
789e5c31af7Sopenharmony_ciclass TraceRaysIndirect2Case : public TestCase
790e5c31af7Sopenharmony_ci{
791e5c31af7Sopenharmony_cipublic:
792e5c31af7Sopenharmony_ci							TraceRaysIndirect2Case	(TestContext& testCtx, const std::string& name, const TestParams2& params);
793e5c31af7Sopenharmony_ci	virtual					~TraceRaysIndirect2Case	(void) override = default;
794e5c31af7Sopenharmony_ci	virtual void			initPrograms	(SourceCollections& programCollection) const override;
795e5c31af7Sopenharmony_ci	virtual TestInstance*	createInstance	(Context& context) const override;
796e5c31af7Sopenharmony_ci	virtual void			checkSupport	(Context& context) const override;
797e5c31af7Sopenharmony_ciprivate:
798e5c31af7Sopenharmony_ci	TestParams2	m_params;
799e5c31af7Sopenharmony_ci};
800e5c31af7Sopenharmony_ci
801e5c31af7Sopenharmony_ciTraceRaysIndirect2Case::TraceRaysIndirect2Case (TestContext& testCtx, const std::string& name, const TestParams2& params)
802e5c31af7Sopenharmony_ci	: TestCase	(testCtx, name)
803e5c31af7Sopenharmony_ci	, m_params	(params)
804e5c31af7Sopenharmony_ci{
805e5c31af7Sopenharmony_ci}
806e5c31af7Sopenharmony_ci
807e5c31af7Sopenharmony_ciTestInstance* TraceRaysIndirect2Case::createInstance (Context& context) const
808e5c31af7Sopenharmony_ci{
809e5c31af7Sopenharmony_ci	return new TraceRaysIndirect2Instance(context, m_params);
810e5c31af7Sopenharmony_ci}
811e5c31af7Sopenharmony_ci
812e5c31af7Sopenharmony_civoid TraceRaysIndirect2Case::checkSupport (Context& context) const
813e5c31af7Sopenharmony_ci{
814e5c31af7Sopenharmony_ci	context.requireInstanceFunctionality(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
815e5c31af7Sopenharmony_ci	context.requireDeviceFunctionality(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME);
816e5c31af7Sopenharmony_ci	context.requireDeviceFunctionality(VK_KHR_RAY_TRACING_MAINTENANCE_1_EXTENSION_NAME);
817e5c31af7Sopenharmony_ci
818e5c31af7Sopenharmony_ci	const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
819e5c31af7Sopenharmony_ci	if (features.shaderInt64 == VK_FALSE)
820e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "64-bit integers not supported by device");
821e5c31af7Sopenharmony_ci
822e5c31af7Sopenharmony_ci	const VkPhysicalDeviceAccelerationStructureFeaturesKHR&	accelerationStructureFeaturesKHR = context.getAccelerationStructureFeatures();
823e5c31af7Sopenharmony_ci	if (accelerationStructureFeaturesKHR.accelerationStructure == VK_FALSE)
824e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceAccelerationStructureFeaturesKHR::accelerationStructure");
825e5c31af7Sopenharmony_ci
826e5c31af7Sopenharmony_ci	const VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR& maintenance1FeaturesKHR = context.getRayTracingMaintenance1Features();
827e5c31af7Sopenharmony_ci	if (maintenance1FeaturesKHR.rayTracingMaintenance1 == VK_FALSE)
828e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR::rayTracingMaintenance1");
829e5c31af7Sopenharmony_ci	if (maintenance1FeaturesKHR.rayTracingPipelineTraceRaysIndirect2 == VK_FALSE)
830e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingMaintenance1FeaturesKHR::rayTracingPipelineTraceRaysIndirect2");
831e5c31af7Sopenharmony_ci
832e5c31af7Sopenharmony_ci	auto desiredQueue	= getQueueFamilyIndexAtExact(context.getDeviceInterface(),
833e5c31af7Sopenharmony_ci													 context.getInstanceInterface(),
834e5c31af7Sopenharmony_ci													 context.getPhysicalDevice(),
835e5c31af7Sopenharmony_ci													 context.getDevice(),
836e5c31af7Sopenharmony_ci													 m_params.submitQueue);
837e5c31af7Sopenharmony_ci	if (!std::get<0>(desiredQueue))
838e5c31af7Sopenharmony_ci	{
839e5c31af7Sopenharmony_ci		std::stringstream errorMsg;
840e5c31af7Sopenharmony_ci		errorMsg << "Desired queue " << m_params.submitQueue << " is not supported by device";
841e5c31af7Sopenharmony_ci		errorMsg.flush();
842e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, errorMsg.str());
843e5c31af7Sopenharmony_ci	}
844e5c31af7Sopenharmony_ci}
845e5c31af7Sopenharmony_ci
846e5c31af7Sopenharmony_civoid TraceRaysIndirect2Case::initPrograms (SourceCollections& programCollection) const
847e5c31af7Sopenharmony_ci{
848e5c31af7Sopenharmony_ci	const vk::ShaderBuildOptions	buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
849e5c31af7Sopenharmony_ci	{
850e5c31af7Sopenharmony_ci		std::stringstream css;
851e5c31af7Sopenharmony_ci		std::string comp(R"(
852e5c31af7Sopenharmony_ci		#version 460 core
853e5c31af7Sopenharmony_ci		#extension GL_ARB_gpu_shader_int64: enable
854e5c31af7Sopenharmony_ci		struct TraceRaysIndirectCommand
855e5c31af7Sopenharmony_ci		{
856e5c31af7Sopenharmony_ci			uint64_t raygenShaderRecordAddress;
857e5c31af7Sopenharmony_ci			uint64_t raygenShaderRecordSize;
858e5c31af7Sopenharmony_ci			uint64_t missShaderBindingTableAddress;
859e5c31af7Sopenharmony_ci			uint64_t missShaderBindingTableSize;
860e5c31af7Sopenharmony_ci			uint64_t missShaderBindingTableStride;
861e5c31af7Sopenharmony_ci			uint64_t hitShaderBindingTableAddress;
862e5c31af7Sopenharmony_ci			uint64_t hitShaderBindingTableSize;
863e5c31af7Sopenharmony_ci			uint64_t hitShaderBindingTableStride;
864e5c31af7Sopenharmony_ci			uint64_t callableShaderBindingTableAddress;
865e5c31af7Sopenharmony_ci			uint64_t callableShaderBindingTableSize;
866e5c31af7Sopenharmony_ci			uint64_t callableShaderBindingTableStride;
867e5c31af7Sopenharmony_ci			uint     width;
868e5c31af7Sopenharmony_ci			uint     height;
869e5c31af7Sopenharmony_ci			uint     depth;
870e5c31af7Sopenharmony_ci		};
871e5c31af7Sopenharmony_ci		layout(push_constant) uniform CopyStyle {
872e5c31af7Sopenharmony_ci			uint full;
873e5c31af7Sopenharmony_ci		} cs;
874e5c31af7Sopenharmony_ci		layout(binding = 0) uniform IndirectCommandsUBO {
875e5c31af7Sopenharmony_ci			TraceRaysIndirectCommand indirectCommands;
876e5c31af7Sopenharmony_ci		} ubo;
877e5c31af7Sopenharmony_ci		layout(binding = 1) buffer IndirectCommandsSBO {
878e5c31af7Sopenharmony_ci			TraceRaysIndirectCommand indirectCommands;
879e5c31af7Sopenharmony_ci		};
880e5c31af7Sopenharmony_ci		void main()
881e5c31af7Sopenharmony_ci		{
882e5c31af7Sopenharmony_ci			if (cs.full != 0) {
883e5c31af7Sopenharmony_ci				indirectCommands.raygenShaderRecordAddress         = ubo.indirectCommands.raygenShaderRecordAddress;
884e5c31af7Sopenharmony_ci				indirectCommands.raygenShaderRecordSize            = ubo.indirectCommands.raygenShaderRecordSize;
885e5c31af7Sopenharmony_ci				indirectCommands.missShaderBindingTableAddress     = ubo.indirectCommands.missShaderBindingTableAddress;
886e5c31af7Sopenharmony_ci				indirectCommands.missShaderBindingTableSize        = ubo.indirectCommands.missShaderBindingTableSize;
887e5c31af7Sopenharmony_ci				indirectCommands.missShaderBindingTableStride      = ubo.indirectCommands.missShaderBindingTableStride;
888e5c31af7Sopenharmony_ci				indirectCommands.hitShaderBindingTableAddress      = ubo.indirectCommands.hitShaderBindingTableAddress;
889e5c31af7Sopenharmony_ci				indirectCommands.hitShaderBindingTableSize         = ubo.indirectCommands.hitShaderBindingTableSize;
890e5c31af7Sopenharmony_ci				indirectCommands.hitShaderBindingTableStride       = ubo.indirectCommands.hitShaderBindingTableStride;
891e5c31af7Sopenharmony_ci				indirectCommands.callableShaderBindingTableAddress = ubo.indirectCommands.callableShaderBindingTableAddress;
892e5c31af7Sopenharmony_ci				indirectCommands.callableShaderBindingTableSize    = ubo.indirectCommands.callableShaderBindingTableSize;
893e5c31af7Sopenharmony_ci				indirectCommands.callableShaderBindingTableStride  = ubo.indirectCommands.callableShaderBindingTableStride;
894e5c31af7Sopenharmony_ci			}
895e5c31af7Sopenharmony_ci			else {
896e5c31af7Sopenharmony_ci				indirectCommands.raygenShaderRecordAddress         = ubo.indirectCommands.raygenShaderRecordAddress;
897e5c31af7Sopenharmony_ci
898e5c31af7Sopenharmony_ci				indirectCommands.missShaderBindingTableStride      = ubo.indirectCommands.missShaderBindingTableStride;
899e5c31af7Sopenharmony_ci
900e5c31af7Sopenharmony_ci				indirectCommands.hitShaderBindingTableSize         = ubo.indirectCommands.hitShaderBindingTableSize;
901e5c31af7Sopenharmony_ci
902e5c31af7Sopenharmony_ci				indirectCommands.callableShaderBindingTableAddress = ubo.indirectCommands.callableShaderBindingTableAddress;
903e5c31af7Sopenharmony_ci				indirectCommands.callableShaderBindingTableStride  = ubo.indirectCommands.callableShaderBindingTableStride;
904e5c31af7Sopenharmony_ci			}
905e5c31af7Sopenharmony_ci
906e5c31af7Sopenharmony_ci			indirectCommands.width                                 = ubo.indirectCommands.width;
907e5c31af7Sopenharmony_ci			indirectCommands.height                                = ubo.indirectCommands.height;
908e5c31af7Sopenharmony_ci			indirectCommands.depth                                 = ubo.indirectCommands.depth;
909e5c31af7Sopenharmony_ci
910e5c31af7Sopenharmony_ci		})");
911e5c31af7Sopenharmony_ci
912e5c31af7Sopenharmony_ci		programCollection.glslSources.add("compute_indirect_command") << glu::ComputeSource(comp) << buildOptions;
913e5c31af7Sopenharmony_ci	}
914e5c31af7Sopenharmony_ci
915e5c31af7Sopenharmony_ci	{
916e5c31af7Sopenharmony_ci		std::stringstream css;
917e5c31af7Sopenharmony_ci		css <<
918e5c31af7Sopenharmony_ci			"#version 460 core\n"
919e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
920e5c31af7Sopenharmony_ci			"layout(location = 0) rayPayloadEXT uvec4 hitValue;\n"
921e5c31af7Sopenharmony_ci			"layout(r32ui, set = 0, binding = 0) uniform uimage3D result;\n"
922e5c31af7Sopenharmony_ci			"layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
923e5c31af7Sopenharmony_ci			"\n"
924e5c31af7Sopenharmony_ci			"void main()\n"
925e5c31af7Sopenharmony_ci			"{\n"
926e5c31af7Sopenharmony_ci			"  float tmin     = 0.0;\n"
927e5c31af7Sopenharmony_ci			"  float tmax     = 1.0;\n"
928e5c31af7Sopenharmony_ci			"  vec3  origin   = vec3(float(gl_LaunchIDEXT.x) + 0.5f, float(gl_LaunchIDEXT.y) + 0.5f, float(gl_LaunchIDEXT.z + 0.5f));\n"
929e5c31af7Sopenharmony_ci			"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
930e5c31af7Sopenharmony_ci			"  hitValue       = uvec4(0,0,0,0);\n"
931e5c31af7Sopenharmony_ci			"  traceRayEXT(topLevelAS, 0, 0xFF, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
932e5c31af7Sopenharmony_ci			"  imageStore(result, ivec3(gl_LaunchIDEXT), hitValue);\n"
933e5c31af7Sopenharmony_ci			"}\n";
934e5c31af7Sopenharmony_ci		programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
935e5c31af7Sopenharmony_ci	}
936e5c31af7Sopenharmony_ci
937e5c31af7Sopenharmony_ci	{
938e5c31af7Sopenharmony_ci		std::stringstream css;
939e5c31af7Sopenharmony_ci		css <<
940e5c31af7Sopenharmony_ci			"#version 460 core\n"
941e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
942e5c31af7Sopenharmony_ci			"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
943e5c31af7Sopenharmony_ci			"void main()\n"
944e5c31af7Sopenharmony_ci			"{\n"
945e5c31af7Sopenharmony_ci			"  hitValue = uvec4(" << kHitColorValue << ",0,0,1);\n"
946e5c31af7Sopenharmony_ci			"}\n";
947e5c31af7Sopenharmony_ci		programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
948e5c31af7Sopenharmony_ci	}
949e5c31af7Sopenharmony_ci
950e5c31af7Sopenharmony_ci	{
951e5c31af7Sopenharmony_ci		std::stringstream css;
952e5c31af7Sopenharmony_ci		css <<
953e5c31af7Sopenharmony_ci			"#version 460 core\n"
954e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
955e5c31af7Sopenharmony_ci			"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
956e5c31af7Sopenharmony_ci			"void main()\n"
957e5c31af7Sopenharmony_ci			"{\n"
958e5c31af7Sopenharmony_ci			"  hitValue = uvec4(" << kMissColorValue << ",0,0,1);\n"
959e5c31af7Sopenharmony_ci			"}\n";
960e5c31af7Sopenharmony_ci
961e5c31af7Sopenharmony_ci		programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
962e5c31af7Sopenharmony_ci	}
963e5c31af7Sopenharmony_ci}
964e5c31af7Sopenharmony_ci
965e5c31af7Sopenharmony_ciTraceRaysIndirect2Instance::TraceRaysIndirect2Instance (Context& context, const TestParams2& params)
966e5c31af7Sopenharmony_ci	: TestInstance	(context)
967e5c31af7Sopenharmony_ci	, m_params		(params)
968e5c31af7Sopenharmony_ci	, m_imageExtent	(getNonNullImageExtent(params.traceDimensions))
969e5c31af7Sopenharmony_ci{
970e5c31af7Sopenharmony_ci}
971e5c31af7Sopenharmony_ci
972e5c31af7Sopenharmony_civoid TraceRaysIndirect2Instance::makeIndirectStructAndFlush	(BufferWithMemory&			buffer,
973e5c31af7Sopenharmony_ci															 const bool					source,
974e5c31af7Sopenharmony_ci															 const BufferWithMemory&	rgenSbt,
975e5c31af7Sopenharmony_ci															 const BufferWithMemory&	hitSbt,
976e5c31af7Sopenharmony_ci															 const BufferWithMemory&	missSbt,
977e5c31af7Sopenharmony_ci															 const BufferWithMemory&	callSbt) const
978e5c31af7Sopenharmony_ci{
979e5c31af7Sopenharmony_ci	DE_UNREF(callSbt);
980e5c31af7Sopenharmony_ci
981e5c31af7Sopenharmony_ci	const DeviceInterface&				vkd						= m_context.getDeviceInterface();
982e5c31af7Sopenharmony_ci	const InstanceInterface&			vki						= m_context.getInstanceInterface();
983e5c31af7Sopenharmony_ci	const VkPhysicalDevice				physicalDevice			= m_context.getPhysicalDevice();
984e5c31af7Sopenharmony_ci	const VkDevice						device					= m_context.getDevice();
985e5c31af7Sopenharmony_ci	const deUint32						shaderGroupHandleSize	= getShaderGroupSize(vki, physicalDevice);
986e5c31af7Sopenharmony_ci	Allocation&							alloc					= buffer.getAllocation();
987e5c31af7Sopenharmony_ci
988e5c31af7Sopenharmony_ci	VkTraceRaysIndirectCommand2KHR		data					{};
989e5c31af7Sopenharmony_ci
990e5c31af7Sopenharmony_ci	if (m_params.traceType == TraceType::INDIRECT_GPU && m_params.partialCopy)
991e5c31af7Sopenharmony_ci	{
992e5c31af7Sopenharmony_ci		if (source)
993e5c31af7Sopenharmony_ci		{
994e5c31af7Sopenharmony_ci			data.raygenShaderRecordAddress			= getBufferDeviceAddress(vkd, device, *rgenSbt, 0);
995e5c31af7Sopenharmony_ci			data.missShaderBindingTableStride		= shaderGroupHandleSize;
996e5c31af7Sopenharmony_ci			data.hitShaderBindingTableSize			= shaderGroupHandleSize;
997e5c31af7Sopenharmony_ci			data.callableShaderBindingTableAddress	= 0;
998e5c31af7Sopenharmony_ci			data.callableShaderBindingTableStride	= 0;
999e5c31af7Sopenharmony_ci		}
1000e5c31af7Sopenharmony_ci		else
1001e5c31af7Sopenharmony_ci		{
1002e5c31af7Sopenharmony_ci			data.raygenShaderRecordSize				= shaderGroupHandleSize;
1003e5c31af7Sopenharmony_ci			data.missShaderBindingTableAddress		= getBufferDeviceAddress(vkd, device, *missSbt, 0);
1004e5c31af7Sopenharmony_ci			data.missShaderBindingTableSize			= shaderGroupHandleSize;
1005e5c31af7Sopenharmony_ci			data.hitShaderBindingTableAddress		= getBufferDeviceAddress(vkd, device, *hitSbt, 0);
1006e5c31af7Sopenharmony_ci			data.hitShaderBindingTableStride		= shaderGroupHandleSize;
1007e5c31af7Sopenharmony_ci			data.callableShaderBindingTableSize		= 0;
1008e5c31af7Sopenharmony_ci		}
1009e5c31af7Sopenharmony_ci	}
1010e5c31af7Sopenharmony_ci	else
1011e5c31af7Sopenharmony_ci	{
1012e5c31af7Sopenharmony_ci		data.raygenShaderRecordAddress				= getBufferDeviceAddress(vkd, device, *rgenSbt, 0);
1013e5c31af7Sopenharmony_ci		data.raygenShaderRecordSize					= shaderGroupHandleSize;
1014e5c31af7Sopenharmony_ci
1015e5c31af7Sopenharmony_ci		data.missShaderBindingTableAddress			= getBufferDeviceAddress(vkd, device, *missSbt, 0);
1016e5c31af7Sopenharmony_ci		data.missShaderBindingTableSize				= shaderGroupHandleSize;
1017e5c31af7Sopenharmony_ci		data.missShaderBindingTableStride			= shaderGroupHandleSize;
1018e5c31af7Sopenharmony_ci
1019e5c31af7Sopenharmony_ci		data.hitShaderBindingTableAddress			= getBufferDeviceAddress(vkd, device, *hitSbt, 0);
1020e5c31af7Sopenharmony_ci		data.hitShaderBindingTableSize				= shaderGroupHandleSize;
1021e5c31af7Sopenharmony_ci		data.hitShaderBindingTableStride			= shaderGroupHandleSize;
1022e5c31af7Sopenharmony_ci
1023e5c31af7Sopenharmony_ci		data.callableShaderBindingTableAddress		= 0;
1024e5c31af7Sopenharmony_ci		data.callableShaderBindingTableSize			= 0;
1025e5c31af7Sopenharmony_ci		data.callableShaderBindingTableStride		= 0;
1026e5c31af7Sopenharmony_ci	}
1027e5c31af7Sopenharmony_ci
1028e5c31af7Sopenharmony_ci	data.width	= m_params.traceDimensions.width;
1029e5c31af7Sopenharmony_ci	data.height	= m_params.traceDimensions.height;
1030e5c31af7Sopenharmony_ci	data.depth	= m_params.traceDimensions.depth;
1031e5c31af7Sopenharmony_ci
1032e5c31af7Sopenharmony_ci	deMemcpy(alloc.getHostPtr(), &data, sizeof(data));
1033e5c31af7Sopenharmony_ci	flushMappedMemoryRange(vkd, device, alloc.getMemory(), alloc.getOffset(), VK_WHOLE_SIZE);
1034e5c31af7Sopenharmony_ci}
1035e5c31af7Sopenharmony_ci
1036e5c31af7Sopenharmony_civoid TraceRaysIndirect2Instance::initBottomAccellStructures (VkCommandBuffer						cmdBuffer,
1037e5c31af7Sopenharmony_ci															 BottomLevelAccelerationStructurePool&	pool,
1038e5c31af7Sopenharmony_ci															 const deUint32&						batchStructCount) const
1039e5c31af7Sopenharmony_ci{
1040e5c31af7Sopenharmony_ci	const DeviceInterface&											vkd			= m_context.getDeviceInterface();
1041e5c31af7Sopenharmony_ci	const VkDevice													device		= m_context.getDevice();
1042e5c31af7Sopenharmony_ci	Allocator&														allocator	= m_context.getDefaultAllocator();
1043e5c31af7Sopenharmony_ci
1044e5c31af7Sopenharmony_ci	pool.batchStructCount(batchStructCount);
1045e5c31af7Sopenharmony_ci	pool.batchGeomCount(batchStructCount * 8);
1046e5c31af7Sopenharmony_ci
1047e5c31af7Sopenharmony_ci	tcu::Vec3 v0(0.0, 1.0, 0.0);
1048e5c31af7Sopenharmony_ci	tcu::Vec3 v1(0.0, 0.0, 0.0);
1049e5c31af7Sopenharmony_ci	tcu::Vec3 v2(1.0, 1.0, 0.0);
1050e5c31af7Sopenharmony_ci	tcu::Vec3 v3(1.0, 0.0, 0.0);
1051e5c31af7Sopenharmony_ci
1052e5c31af7Sopenharmony_ci	for (deUint32 z = 0; z < m_imageExtent.depth; ++z)
1053e5c31af7Sopenharmony_ci	for (deUint32 y = 0; y < m_imageExtent.height; ++y)
1054e5c31af7Sopenharmony_ci	for (deUint32 x = 0; x < m_imageExtent.width; ++x)
1055e5c31af7Sopenharmony_ci	{
1056e5c31af7Sopenharmony_ci		// let's build a 3D chessboard of geometries
1057e5c31af7Sopenharmony_ci		if (((x + y + z) % 2) == 0)
1058e5c31af7Sopenharmony_ci			continue;
1059e5c31af7Sopenharmony_ci		tcu::Vec3 xyz((float)x, (float)y, (float)z);
1060e5c31af7Sopenharmony_ci		std::vector<tcu::Vec3>	geometryData;
1061e5c31af7Sopenharmony_ci
1062e5c31af7Sopenharmony_ci		auto bottomLevelAccelerationStructure = pool.add();
1063e5c31af7Sopenharmony_ci		bottomLevelAccelerationStructure->setGeometryCount(1u);
1064e5c31af7Sopenharmony_ci
1065e5c31af7Sopenharmony_ci		geometryData.push_back(xyz + v0);
1066e5c31af7Sopenharmony_ci		geometryData.push_back(xyz + v1);
1067e5c31af7Sopenharmony_ci		geometryData.push_back(xyz + v2);
1068e5c31af7Sopenharmony_ci		geometryData.push_back(xyz + v2);
1069e5c31af7Sopenharmony_ci		geometryData.push_back(xyz + v1);
1070e5c31af7Sopenharmony_ci		geometryData.push_back(xyz + v3);
1071e5c31af7Sopenharmony_ci
1072e5c31af7Sopenharmony_ci		bottomLevelAccelerationStructure->addGeometry(geometryData, true);
1073e5c31af7Sopenharmony_ci	}
1074e5c31af7Sopenharmony_ci
1075e5c31af7Sopenharmony_ci	pool.batchCreate(vkd, device, allocator);
1076e5c31af7Sopenharmony_ci	pool.batchBuild(vkd, device, cmdBuffer);
1077e5c31af7Sopenharmony_ci}
1078e5c31af7Sopenharmony_ci
1079e5c31af7Sopenharmony_ciTestStatus TraceRaysIndirect2Instance::iterate (void)
1080e5c31af7Sopenharmony_ci{
1081e5c31af7Sopenharmony_ci	const InstanceInterface&			vki									= m_context.getInstanceInterface();
1082e5c31af7Sopenharmony_ci	const DeviceInterface&				vkd									= m_context.getDeviceInterface();
1083e5c31af7Sopenharmony_ci	const VkDevice						device								= m_context.getDevice();
1084e5c31af7Sopenharmony_ci	const VkPhysicalDevice				physicalDevice						= m_context.getPhysicalDevice();
1085e5c31af7Sopenharmony_ci	const auto							queueAndFamilyIndex					= getQueueFamilyIndexAtExact(vkd, vki, physicalDevice, device, m_params.submitQueue);
1086e5c31af7Sopenharmony_ci	const VkQueue						queue								= std::get<1>(queueAndFamilyIndex);
1087e5c31af7Sopenharmony_ci	const deUint32						queueFamilyIndex					= std::get<2>(queueAndFamilyIndex);
1088e5c31af7Sopenharmony_ci	Allocator&							allocator							= m_context.getDefaultAllocator();
1089e5c31af7Sopenharmony_ci	const deUint32						width								= m_imageExtent.width;
1090e5c31af7Sopenharmony_ci	const deUint32						height								= m_imageExtent.height;
1091e5c31af7Sopenharmony_ci	const deUint32						depth								= m_imageExtent.depth;
1092e5c31af7Sopenharmony_ci	const deUint32						pixelCount							= width * height * depth;
1093e5c31af7Sopenharmony_ci	const deUint32						shaderGroupHandleSize				= getShaderGroupSize(vki, physicalDevice);
1094e5c31af7Sopenharmony_ci	const deUint32						shaderGroupBaseAlignment			= getShaderGroupBaseAlignment(vki, physicalDevice);
1095e5c31af7Sopenharmony_ci
1096e5c31af7Sopenharmony_ci	Move<VkDescriptorSetLayout>			computeDescriptorSetLayout;
1097e5c31af7Sopenharmony_ci	Move<VkDescriptorPool>				computeDescriptorPool;
1098e5c31af7Sopenharmony_ci	Move<VkDescriptorSet>				computeDescriptorSet;
1099e5c31af7Sopenharmony_ci	Move<VkPipelineLayout>				computePipelineLayout;
1100e5c31af7Sopenharmony_ci	Move<VkShaderModule>				computeShader;
1101e5c31af7Sopenharmony_ci	Move<VkPipeline>					computePipeline;
1102e5c31af7Sopenharmony_ci
1103e5c31af7Sopenharmony_ci	if (m_params.traceType == TraceType::INDIRECT_GPU)
1104e5c31af7Sopenharmony_ci	{
1105e5c31af7Sopenharmony_ci		computeDescriptorSetLayout			= DescriptorSetLayoutBuilder()
1106e5c31af7Sopenharmony_ci													.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
1107e5c31af7Sopenharmony_ci													.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
1108e5c31af7Sopenharmony_ci													.build(vkd, device);
1109e5c31af7Sopenharmony_ci		computeDescriptorPool				= DescriptorPoolBuilder()
1110e5c31af7Sopenharmony_ci													.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
1111e5c31af7Sopenharmony_ci													.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1112e5c31af7Sopenharmony_ci													.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1113e5c31af7Sopenharmony_ci		const VkPushConstantRange	full	{ VK_SHADER_STAGE_COMPUTE_BIT, 0, deUint32(sizeof(deUint32)) };
1114e5c31af7Sopenharmony_ci		computeDescriptorSet				= makeDescriptorSet(vkd, device, *computeDescriptorPool, *computeDescriptorSetLayout);
1115e5c31af7Sopenharmony_ci		computePipelineLayout				= makePipelineLayout(vkd, device, 1, &computeDescriptorSetLayout.get(), 1, &full);
1116e5c31af7Sopenharmony_ci
1117e5c31af7Sopenharmony_ci		computeShader						= createShaderModule(vkd, device, m_context.getBinaryCollection().get("compute_indirect_command"), 0);
1118e5c31af7Sopenharmony_ci		const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
1119e5c31af7Sopenharmony_ci		{
1120e5c31af7Sopenharmony_ci			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
1121e5c31af7Sopenharmony_ci			DE_NULL,												// const void*							pNext;
1122e5c31af7Sopenharmony_ci			VkPipelineShaderStageCreateFlags(0u),					// VkPipelineShaderStageCreateFlags		flags;
1123e5c31af7Sopenharmony_ci			VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
1124e5c31af7Sopenharmony_ci			*computeShader,											// VkShaderModule						module;
1125e5c31af7Sopenharmony_ci			"main",													// const char*							pName;
1126e5c31af7Sopenharmony_ci			DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
1127e5c31af7Sopenharmony_ci		};
1128e5c31af7Sopenharmony_ci		const VkComputePipelineCreateInfo pipelineCreateInfo =
1129e5c31af7Sopenharmony_ci		{
1130e5c31af7Sopenharmony_ci			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
1131e5c31af7Sopenharmony_ci			DE_NULL,											// const void*						pNext;
1132e5c31af7Sopenharmony_ci			VkPipelineCreateFlags(0u),							// VkPipelineCreateFlags			flags;
1133e5c31af7Sopenharmony_ci			pipelineShaderStageParams,							// VkPipelineShaderStageCreateInfo	stage;
1134e5c31af7Sopenharmony_ci			*computePipelineLayout,								// VkPipelineLayout					layout;
1135e5c31af7Sopenharmony_ci			DE_NULL,											// VkPipeline						basePipelineHandle;
1136e5c31af7Sopenharmony_ci			0,													// deInt32							basePipelineIndex;
1137e5c31af7Sopenharmony_ci		};
1138e5c31af7Sopenharmony_ci
1139e5c31af7Sopenharmony_ci		computePipeline = vk::createComputePipeline(vkd, device, (VkPipelineCache)0u, &pipelineCreateInfo);
1140e5c31af7Sopenharmony_ci	}
1141e5c31af7Sopenharmony_ci
1142e5c31af7Sopenharmony_ci	const Move<VkDescriptorSetLayout>	descriptorSetLayout					= DescriptorSetLayoutBuilder()
1143e5c31af7Sopenharmony_ci																					.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
1144e5c31af7Sopenharmony_ci																					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1145e5c31af7Sopenharmony_ci																					.build(vkd, device);
1146e5c31af7Sopenharmony_ci	const Move<VkDescriptorPool>		descriptorPool						= DescriptorPoolBuilder()
1147e5c31af7Sopenharmony_ci																					.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1148e5c31af7Sopenharmony_ci																					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1149e5c31af7Sopenharmony_ci																					.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1150e5c31af7Sopenharmony_ci	const Move<VkDescriptorSet>			descriptorSet						= makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
1151e5c31af7Sopenharmony_ci	const Move<VkPipelineLayout>		pipelineLayout						= makePipelineLayout(vkd, device, descriptorSetLayout.get());
1152e5c31af7Sopenharmony_ci
1153e5c31af7Sopenharmony_ci	de::MovePtr<RayTracingPipeline>		rayTracingPipeline					= de::newMovePtr<RayTracingPipeline>();
1154e5c31af7Sopenharmony_ci	rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR,		createShaderModule(vkd, device, m_context.getBinaryCollection().get("rgen"), 0), 0);
1155e5c31af7Sopenharmony_ci	rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,	createShaderModule(vkd, device, m_context.getBinaryCollection().get("chit"), 0), 1);
1156e5c31af7Sopenharmony_ci	rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR,			createShaderModule(vkd, device, m_context.getBinaryCollection().get("miss"), 0), 2);
1157e5c31af7Sopenharmony_ci	Move<VkPipeline>					pipeline							= rayTracingPipeline->createPipeline(vkd, device, *pipelineLayout);
1158e5c31af7Sopenharmony_ci
1159e5c31af7Sopenharmony_ci	const de::MovePtr<BufferWithMemory>	rgenSbt								= rayTracingPipeline->createShaderBindingTable(vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1 );
1160e5c31af7Sopenharmony_ci	const de::MovePtr<BufferWithMemory>	hitSbt								= rayTracingPipeline->createShaderBindingTable(vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1 );
1161e5c31af7Sopenharmony_ci	const de::MovePtr<BufferWithMemory>	missSbt								= rayTracingPipeline->createShaderBindingTable(vkd, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1 );
1162e5c31af7Sopenharmony_ci
1163e5c31af7Sopenharmony_ci	const VkFormat						imageFormat							= VK_FORMAT_R32_UINT;
1164e5c31af7Sopenharmony_ci	const VkImageCreateInfo				imageCreateInfo						= makeImageCreateInfo(width, height, depth, imageFormat);
1165e5c31af7Sopenharmony_ci	const VkImageSubresourceRange		imageSubresourceRange				= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0, 1u);
1166e5c31af7Sopenharmony_ci	const de::MovePtr<ImageWithMemory>	image								= de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1167e5c31af7Sopenharmony_ci	const Move<VkImageView>				imageView							= makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, imageFormat, imageSubresourceRange);
1168e5c31af7Sopenharmony_ci
1169e5c31af7Sopenharmony_ci	const VkBufferCreateInfo			resultBufferCreateInfo				= makeBufferCreateInfo(pixelCount*sizeof(deUint32), VK_BUFFER_USAGE_TRANSFER_DST_BIT);
1170e5c31af7Sopenharmony_ci	const VkImageSubresourceLayers		resultBufferImageSubresourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1171e5c31af7Sopenharmony_ci	const VkBufferImageCopy				resultBufferImageRegion				= makeBufferImageCopy(m_params.traceDimensions, resultBufferImageSubresourceLayers);
1172e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>		resultBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
1173e5c31af7Sopenharmony_ci	Allocation&							resultBufferAllocation				= resultBuffer->getAllocation();
1174e5c31af7Sopenharmony_ci
1175e5c31af7Sopenharmony_ci	const VkDescriptorImageInfo			descriptorImageInfo					= makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
1176e5c31af7Sopenharmony_ci
1177e5c31af7Sopenharmony_ci	// create indirect command buffer and fill it with parameter values
1178e5c31af7Sopenharmony_ci	const VkDeviceSize					bufferSize							= sizeof(VkTraceRaysIndirectCommand2KHR);
1179e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>		indirectBuffer;
1180e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>		uniformBuffer;
1181e5c31af7Sopenharmony_ci
1182e5c31af7Sopenharmony_ci	const bool							indirectGpu							= (m_params.traceType == TraceType::INDIRECT_GPU);
1183e5c31af7Sopenharmony_ci	VkBufferUsageFlags					indirectBufferUsageFlags			= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | ( indirectGpu ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : VK_BUFFER_USAGE_TRANSFER_DST_BIT );
1184e5c31af7Sopenharmony_ci	const VkBufferCreateInfo			indirectBufferCreateInfo			= makeBufferCreateInfo(bufferSize, indirectBufferUsageFlags);
1185e5c31af7Sopenharmony_ci	vk::MemoryRequirement				indirectBufferMemoryRequirement		= MemoryRequirement::DeviceAddress | MemoryRequirement::HostVisible;
1186e5c31af7Sopenharmony_ci	indirectBuffer															= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, indirectBufferCreateInfo, indirectBufferMemoryRequirement));
1187e5c31af7Sopenharmony_ci
1188e5c31af7Sopenharmony_ci	if (m_params.traceType == TraceType::INDIRECT_GPU)
1189e5c31af7Sopenharmony_ci	{
1190e5c31af7Sopenharmony_ci		const VkBufferCreateInfo			uniformBufferCreateInfo			= makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
1191e5c31af7Sopenharmony_ci		uniformBuffer														= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible));
1192e5c31af7Sopenharmony_ci		makeIndirectStructAndFlush(*uniformBuffer, true, *rgenSbt, *hitSbt, *missSbt, *missSbt);
1193e5c31af7Sopenharmony_ci		makeIndirectStructAndFlush(*indirectBuffer, false, *rgenSbt, *hitSbt, *missSbt, *missSbt);
1194e5c31af7Sopenharmony_ci	}
1195e5c31af7Sopenharmony_ci	else if (m_params.traceType == TraceType::INDIRECT_CPU)
1196e5c31af7Sopenharmony_ci	{
1197e5c31af7Sopenharmony_ci		makeIndirectStructAndFlush(*indirectBuffer, true, *rgenSbt, *hitSbt, *missSbt, *missSbt);
1198e5c31af7Sopenharmony_ci	}
1199e5c31af7Sopenharmony_ci	else
1200e5c31af7Sopenharmony_ci	{
1201e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Invalid test parameters");
1202e5c31af7Sopenharmony_ci	}
1203e5c31af7Sopenharmony_ci
1204e5c31af7Sopenharmony_ci	de::MovePtr<TopLevelAccelerationStructure>	topLevelAccelerationStructure;
1205e5c31af7Sopenharmony_ci	BottomLevelAccelerationStructurePool	blasPool;
1206e5c31af7Sopenharmony_ci	const Move<VkCommandPool>				cmdPool							= createCommandPool(vkd, device, 0, queueFamilyIndex);
1207e5c31af7Sopenharmony_ci	const Move<VkCommandBuffer>				cmdBuffer						= allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1208e5c31af7Sopenharmony_ci
1209e5c31af7Sopenharmony_ci	beginCommandBuffer(vkd, *cmdBuffer, 0u);
1210e5c31af7Sopenharmony_ci	{
1211e5c31af7Sopenharmony_ci		const VkImageMemoryBarrier			preImageBarrier						= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
1212e5c31af7Sopenharmony_ci																					VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1213e5c31af7Sopenharmony_ci																					**image, imageSubresourceRange);
1214e5c31af7Sopenharmony_ci		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
1215e5c31af7Sopenharmony_ci
1216e5c31af7Sopenharmony_ci		const VkClearValue					clearValue							= makeClearValueColorU32(kClearColorValue, 0u, 0u, 0u);
1217e5c31af7Sopenharmony_ci		vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
1218e5c31af7Sopenharmony_ci
1219e5c31af7Sopenharmony_ci		const VkImageMemoryBarrier			postImageBarrier					= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
1220e5c31af7Sopenharmony_ci																					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1221e5c31af7Sopenharmony_ci																					**image, imageSubresourceRange);
1222e5c31af7Sopenharmony_ci		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
1223e5c31af7Sopenharmony_ci
1224e5c31af7Sopenharmony_ci
1225e5c31af7Sopenharmony_ci		initBottomAccellStructures(*cmdBuffer, blasPool, 4);
1226e5c31af7Sopenharmony_ci		topLevelAccelerationStructure		= initTopAccelerationStructure(*cmdBuffer, blasPool.structures(), m_context, m_imageExtent);
1227e5c31af7Sopenharmony_ci
1228e5c31af7Sopenharmony_ci		if (m_params.traceType == TraceType::INDIRECT_GPU)
1229e5c31af7Sopenharmony_ci		{
1230e5c31af7Sopenharmony_ci			const deUint32					fullCopyStyle					= m_params.partialCopy ? 0 : 1;
1231e5c31af7Sopenharmony_ci			const VkDescriptorBufferInfo	uniformBufferDescriptorInfo		= makeDescriptorBufferInfo(**uniformBuffer, 0ull, bufferSize);
1232e5c31af7Sopenharmony_ci			const VkDescriptorBufferInfo	indirectBufferDescriptorInfo	= makeDescriptorBufferInfo(**indirectBuffer, 0ull, bufferSize);
1233e5c31af7Sopenharmony_ci			DescriptorSetUpdateBuilder()
1234e5c31af7Sopenharmony_ci				.writeSingle(*computeDescriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &uniformBufferDescriptorInfo)
1235e5c31af7Sopenharmony_ci				.writeSingle(*computeDescriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &indirectBufferDescriptorInfo)
1236e5c31af7Sopenharmony_ci				.update(vkd, device);
1237e5c31af7Sopenharmony_ci
1238e5c31af7Sopenharmony_ci			vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
1239e5c31af7Sopenharmony_ci			vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *computePipelineLayout, 0u, 1u, &computeDescriptorSet.get(), 0u, DE_NULL);
1240e5c31af7Sopenharmony_ci			vkd.cmdPushConstants(*cmdBuffer, *computePipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, deUint32(sizeof(deUint32)), &fullCopyStyle);
1241e5c31af7Sopenharmony_ci			vkd.cmdDispatch(*cmdBuffer, 1, 1, 1);
1242e5c31af7Sopenharmony_ci
1243e5c31af7Sopenharmony_ci			const VkBufferMemoryBarrier		fillIndirectBufferMemoryBarrier	= makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
1244e5c31af7Sopenharmony_ci																				**indirectBuffer, 0ull, bufferSize);
1245e5c31af7Sopenharmony_ci			cmdPipelineBufferMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, &fillIndirectBufferMemoryBarrier);
1246e5c31af7Sopenharmony_ci		}
1247e5c31af7Sopenharmony_ci
1248e5c31af7Sopenharmony_ci		const TopLevelAccelerationStructure*			topLevelAccelerationStructurePtr		= topLevelAccelerationStructure.get();
1249e5c31af7Sopenharmony_ci		VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet	=
1250e5c31af7Sopenharmony_ci		{
1251e5c31af7Sopenharmony_ci			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
1252e5c31af7Sopenharmony_ci			DE_NULL,															//  const void*							pNext;
1253e5c31af7Sopenharmony_ci			1u,																	//  deUint32							accelerationStructureCount;
1254e5c31af7Sopenharmony_ci			topLevelAccelerationStructurePtr->getPtr(),							//  const VkAccelerationStructureKHR*	pAccelerationStructures;
1255e5c31af7Sopenharmony_ci		};
1256e5c31af7Sopenharmony_ci
1257e5c31af7Sopenharmony_ci		DescriptorSetUpdateBuilder()
1258e5c31af7Sopenharmony_ci			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
1259e5c31af7Sopenharmony_ci			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1260e5c31af7Sopenharmony_ci			.update(vkd, device);
1261e5c31af7Sopenharmony_ci
1262e5c31af7Sopenharmony_ci		vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
1263e5c31af7Sopenharmony_ci
1264e5c31af7Sopenharmony_ci		vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipeline);
1265e5c31af7Sopenharmony_ci
1266e5c31af7Sopenharmony_ci		cmdTraceRaysIndirect2(vkd, *cmdBuffer, getBufferDeviceAddress(vkd, device, **indirectBuffer, 0));
1267e5c31af7Sopenharmony_ci
1268e5c31af7Sopenharmony_ci		const VkMemoryBarrier							postTraceMemoryBarrier					= makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
1269e5c31af7Sopenharmony_ci		const VkMemoryBarrier							postCopyMemoryBarrier					= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
1270e5c31af7Sopenharmony_ci		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier);
1271e5c31af7Sopenharmony_ci
1272e5c31af7Sopenharmony_ci		vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
1273e5c31af7Sopenharmony_ci
1274e5c31af7Sopenharmony_ci		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
1275e5c31af7Sopenharmony_ci	}
1276e5c31af7Sopenharmony_ci	endCommandBuffer(vkd, *cmdBuffer);
1277e5c31af7Sopenharmony_ci
1278e5c31af7Sopenharmony_ci	submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1279e5c31af7Sopenharmony_ci
1280e5c31af7Sopenharmony_ci	invalidateMappedMemoryRange(vkd, device, resultBufferAllocation.getMemory(), resultBufferAllocation.getOffset(), VK_WHOLE_SIZE);
1281e5c31af7Sopenharmony_ci
1282e5c31af7Sopenharmony_ci	// run test using arrays of pointers
1283e5c31af7Sopenharmony_ci	const deUint32*						bufferPtr	= (deUint32*)resultBufferAllocation.getHostPtr();
1284e5c31af7Sopenharmony_ci	const bool							noWrites	= isNullExtent(m_params.traceDimensions);
1285e5c31af7Sopenharmony_ci
1286e5c31af7Sopenharmony_ci	const auto							allocationCount	= blasPool.getAllocationCount();
1287e5c31af7Sopenharmony_ci	deUint32							failures		= 0;
1288e5c31af7Sopenharmony_ci	deUint32							pos				= 0;
1289e5c31af7Sopenharmony_ci	deUint32							all				= 0;
1290e5c31af7Sopenharmony_ci
1291e5c31af7Sopenharmony_ci	// verify results
1292e5c31af7Sopenharmony_ci	for (deUint32 z = 0; z < depth; ++z)
1293e5c31af7Sopenharmony_ci	for (deUint32 y = 0; y < height; ++y)
1294e5c31af7Sopenharmony_ci	for (deUint32 x = 0; x < width; ++x)
1295e5c31af7Sopenharmony_ci	{
1296e5c31af7Sopenharmony_ci		const deUint32 expectedResult = (noWrites ? kClearColorValue : (((x + y + z) % 2) ? kHitColorValue : kMissColorValue));
1297e5c31af7Sopenharmony_ci		if (bufferPtr[pos] != expectedResult)
1298e5c31af7Sopenharmony_ci			failures++;
1299e5c31af7Sopenharmony_ci		++pos;
1300e5c31af7Sopenharmony_ci		++all;
1301e5c31af7Sopenharmony_ci	}
1302e5c31af7Sopenharmony_ci
1303e5c31af7Sopenharmony_ci	if (failures == 0)
1304e5c31af7Sopenharmony_ci		return tcu::TestStatus::pass(std::to_string(allocationCount) +" allocations");
1305e5c31af7Sopenharmony_ci	else
1306e5c31af7Sopenharmony_ci	{
1307e5c31af7Sopenharmony_ci		const auto msg = std::to_string(allocationCount) +" allocations, " + std::to_string(failures) + " failures from " + std::to_string(all);
1308e5c31af7Sopenharmony_ci		return tcu::TestStatus::fail(msg);
1309e5c31af7Sopenharmony_ci	}
1310e5c31af7Sopenharmony_ci}
1311e5c31af7Sopenharmony_ci
1312e5c31af7Sopenharmony_cistd::string makeDimensionsName (const VkTraceRaysIndirectCommandKHR& cmd)
1313e5c31af7Sopenharmony_ci{
1314e5c31af7Sopenharmony_ci	std::ostringstream name;
1315e5c31af7Sopenharmony_ci	name << cmd.width << "_" << cmd.height << "_" << cmd.depth;
1316e5c31af7Sopenharmony_ci	return name.str();
1317e5c31af7Sopenharmony_ci}
1318e5c31af7Sopenharmony_ci
1319e5c31af7Sopenharmony_cistd::string makeDimensionsName (const VkExtent3D& extent)
1320e5c31af7Sopenharmony_ci{
1321e5c31af7Sopenharmony_ci	std::ostringstream name;
1322e5c31af7Sopenharmony_ci	name << extent.width << "x" << extent.height << "x" << extent.depth;
1323e5c31af7Sopenharmony_ci	return name.str();
1324e5c31af7Sopenharmony_ci}
1325e5c31af7Sopenharmony_ci
1326e5c31af7Sopenharmony_ci}	// anonymous
1327e5c31af7Sopenharmony_ci
1328e5c31af7Sopenharmony_citcu::TestCaseGroup* createTraceRaysTests(tcu::TestContext& testCtx)
1329e5c31af7Sopenharmony_ci{
1330e5c31af7Sopenharmony_ci	// Tests veryfying vkCmdTraceRays* commands
1331e5c31af7Sopenharmony_ci	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "trace_rays_cmds"));
1332e5c31af7Sopenharmony_ci
1333e5c31af7Sopenharmony_ci	struct BufferSourceTypeData
1334e5c31af7Sopenharmony_ci	{
1335e5c31af7Sopenharmony_ci		TraceType								traceType;
1336e5c31af7Sopenharmony_ci		const char*								name;
1337e5c31af7Sopenharmony_ci	} bufferSourceTypes[] =
1338e5c31af7Sopenharmony_ci	{
1339e5c31af7Sopenharmony_ci		{ TraceType::DIRECT,		"direct"			},
1340e5c31af7Sopenharmony_ci		{ TraceType::INDIRECT_CPU,	"indirect_cpu"		},
1341e5c31af7Sopenharmony_ci		{ TraceType::INDIRECT_GPU,	"indirect_gpu"		},
1342e5c31af7Sopenharmony_ci	};
1343e5c31af7Sopenharmony_ci
1344e5c31af7Sopenharmony_ci	const VkTraceRaysIndirectCommandKHR traceDimensions[] =
1345e5c31af7Sopenharmony_ci	{
1346e5c31af7Sopenharmony_ci		{  0,  0, 0 },
1347e5c31af7Sopenharmony_ci		{  0,  1, 1 },
1348e5c31af7Sopenharmony_ci		{  1,  0, 1 },
1349e5c31af7Sopenharmony_ci		{  1,  1, 0 },
1350e5c31af7Sopenharmony_ci		{  8,  1, 1 },
1351e5c31af7Sopenharmony_ci		{  8,  8, 1 },
1352e5c31af7Sopenharmony_ci		{  8,  8, 8 },
1353e5c31af7Sopenharmony_ci		{ 11,  1, 1 },
1354e5c31af7Sopenharmony_ci		{ 11, 13, 1 },
1355e5c31af7Sopenharmony_ci		{ 11, 13, 5 },
1356e5c31af7Sopenharmony_ci	};
1357e5c31af7Sopenharmony_ci
1358e5c31af7Sopenharmony_ci	for (size_t bufferSourceNdx = 0; bufferSourceNdx < DE_LENGTH_OF_ARRAY(bufferSourceTypes); ++bufferSourceNdx)
1359e5c31af7Sopenharmony_ci	{
1360e5c31af7Sopenharmony_ci		de::MovePtr<tcu::TestCaseGroup> bufferSourceGroup(new tcu::TestCaseGroup(group->getTestContext(), bufferSourceTypes[bufferSourceNdx].name));
1361e5c31af7Sopenharmony_ci
1362e5c31af7Sopenharmony_ci		for (size_t traceDimensionsIdx = 0; traceDimensionsIdx < DE_LENGTH_OF_ARRAY(traceDimensions); ++traceDimensionsIdx)
1363e5c31af7Sopenharmony_ci		{
1364e5c31af7Sopenharmony_ci			TestParams testParams
1365e5c31af7Sopenharmony_ci			{
1366e5c31af7Sopenharmony_ci				bufferSourceTypes[bufferSourceNdx].traceType,
1367e5c31af7Sopenharmony_ci				traceDimensions[traceDimensionsIdx],
1368e5c31af7Sopenharmony_ci				false,
1369e5c31af7Sopenharmony_ci				{/* Intentionally empty */},
1370e5c31af7Sopenharmony_ci			};
1371e5c31af7Sopenharmony_ci			const auto testName = makeDimensionsName(traceDimensions[traceDimensionsIdx]);
1372e5c31af7Sopenharmony_ci			bufferSourceGroup->addChild(new RayTracingTraceRaysIndirectTestCase(group->getTestContext(), testName.c_str(), testParams));
1373e5c31af7Sopenharmony_ci		}
1374e5c31af7Sopenharmony_ci
1375e5c31af7Sopenharmony_ci		group->addChild(bufferSourceGroup.release());
1376e5c31af7Sopenharmony_ci	}
1377e5c31af7Sopenharmony_ci
1378e5c31af7Sopenharmony_ci	return group.release();
1379e5c31af7Sopenharmony_ci}
1380e5c31af7Sopenharmony_ci
1381e5c31af7Sopenharmony_citcu::TestCaseGroup* createTraceRaysMaintenance1Tests(tcu::TestContext& testCtx)
1382e5c31af7Sopenharmony_ci{
1383e5c31af7Sopenharmony_ci	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "trace_rays_cmds_maintenance_1", "Tests veryfying vkCmdTraceRays* commands"));
1384e5c31af7Sopenharmony_ci
1385e5c31af7Sopenharmony_ci	struct BufferSourceTypeData
1386e5c31af7Sopenharmony_ci	{
1387e5c31af7Sopenharmony_ci		TraceType								traceType;
1388e5c31af7Sopenharmony_ci		const char*								name;
1389e5c31af7Sopenharmony_ci	} bufferSourceTypes[] =
1390e5c31af7Sopenharmony_ci	{
1391e5c31af7Sopenharmony_ci		{ TraceType::INDIRECT2_CPU,	"indirect2_cpu"		},
1392e5c31af7Sopenharmony_ci		{ TraceType::INDIRECT2_GPU,	"indirect2_gpu"		},
1393e5c31af7Sopenharmony_ci	};
1394e5c31af7Sopenharmony_ci
1395e5c31af7Sopenharmony_ci	const VkTraceRaysIndirectCommand2KHR extendedTraceDimensions[] =
1396e5c31af7Sopenharmony_ci	{
1397e5c31af7Sopenharmony_ci		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0, 0 },
1398e5c31af7Sopenharmony_ci		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  1, 1 },
1399e5c31af7Sopenharmony_ci		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  1,  0, 1 },
1400e5c31af7Sopenharmony_ci		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  1,  1, 0 },
1401e5c31af7Sopenharmony_ci		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  8,  1, 1 },
1402e5c31af7Sopenharmony_ci		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  8,  8, 1 },
1403e5c31af7Sopenharmony_ci		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  8,  8, 8 },
1404e5c31af7Sopenharmony_ci		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11,  1, 1 },
1405e5c31af7Sopenharmony_ci		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 13, 1 },
1406e5c31af7Sopenharmony_ci		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 13, 5 },
1407e5c31af7Sopenharmony_ci	};
1408e5c31af7Sopenharmony_ci
1409e5c31af7Sopenharmony_ci	for (size_t bufferSourceNdx = 0; bufferSourceNdx < DE_LENGTH_OF_ARRAY(bufferSourceTypes); ++bufferSourceNdx)
1410e5c31af7Sopenharmony_ci	{
1411e5c31af7Sopenharmony_ci		de::MovePtr<tcu::TestCaseGroup> bufferSourceGroup(new tcu::TestCaseGroup(group->getTestContext(), bufferSourceTypes[bufferSourceNdx].name));
1412e5c31af7Sopenharmony_ci
1413e5c31af7Sopenharmony_ci		for (size_t extendedTraceDimensionsIdx = 0; extendedTraceDimensionsIdx < DE_LENGTH_OF_ARRAY(extendedTraceDimensions); ++extendedTraceDimensionsIdx)
1414e5c31af7Sopenharmony_ci		{
1415e5c31af7Sopenharmony_ci			TestParams testParams
1416e5c31af7Sopenharmony_ci			{
1417e5c31af7Sopenharmony_ci				bufferSourceTypes[bufferSourceNdx].traceType,
1418e5c31af7Sopenharmony_ci				{/* Intentionally empty */},
1419e5c31af7Sopenharmony_ci				true,
1420e5c31af7Sopenharmony_ci				extendedTraceDimensions[extendedTraceDimensionsIdx],
1421e5c31af7Sopenharmony_ci			};
1422e5c31af7Sopenharmony_ci			const auto testName = makeDimensionsName(extendedTraceDimensions[extendedTraceDimensionsIdx]);
1423e5c31af7Sopenharmony_ci			bufferSourceGroup->addChild(new RayTracingTraceRaysIndirectTestCase(group->getTestContext(), testName.c_str(), testParams));
1424e5c31af7Sopenharmony_ci		}
1425e5c31af7Sopenharmony_ci
1426e5c31af7Sopenharmony_ci		group->addChild(bufferSourceGroup.release());
1427e5c31af7Sopenharmony_ci	}
1428e5c31af7Sopenharmony_ci
1429e5c31af7Sopenharmony_ci	return group.release();
1430e5c31af7Sopenharmony_ci}
1431e5c31af7Sopenharmony_ci
1432e5c31af7Sopenharmony_citcu::TestCaseGroup*	createTraceRays2Tests(tcu::TestContext& testCtx)
1433e5c31af7Sopenharmony_ci{
1434e5c31af7Sopenharmony_ci	auto group	= new tcu::TestCaseGroup(testCtx, "trace_rays_indirect2", "Tests veryfying vkCmdTraceRaysIndirect2KHR command");
1435e5c31af7Sopenharmony_ci
1436e5c31af7Sopenharmony_ci	std::pair<TraceType, const char*> const	bufferSources[]
1437e5c31af7Sopenharmony_ci	{
1438e5c31af7Sopenharmony_ci		{ TraceType::INDIRECT_CPU,	"indirect_cpu"		},
1439e5c31af7Sopenharmony_ci		{ TraceType::INDIRECT_GPU,	"indirect_gpu"		},
1440e5c31af7Sopenharmony_ci	};
1441e5c31af7Sopenharmony_ci
1442e5c31af7Sopenharmony_ci	std::pair<bool, const char*> const copyStyles[]
1443e5c31af7Sopenharmony_ci	{
1444e5c31af7Sopenharmony_ci		{ true,		"full_copy"	},
1445e5c31af7Sopenharmony_ci		{ false,	"partial_copy" }
1446e5c31af7Sopenharmony_ci	};
1447e5c31af7Sopenharmony_ci
1448e5c31af7Sopenharmony_ci	std::pair<VkQueueFlagBits, const char*> submitQueues[]
1449e5c31af7Sopenharmony_ci	{
1450e5c31af7Sopenharmony_ci		{ VK_QUEUE_GRAPHICS_BIT,	"submit_graphics" },
1451e5c31af7Sopenharmony_ci		{ VK_QUEUE_COMPUTE_BIT,		"submit_compute" }
1452e5c31af7Sopenharmony_ci	};
1453e5c31af7Sopenharmony_ci
1454e5c31af7Sopenharmony_ci	const VkExtent3D traceDimensions[] =
1455e5c31af7Sopenharmony_ci	{
1456e5c31af7Sopenharmony_ci		{ 11, 17, 1 },
1457e5c31af7Sopenharmony_ci		{ 19, 11, 2 },
1458e5c31af7Sopenharmony_ci		{ 23, 47, 3 },
1459e5c31af7Sopenharmony_ci		{ 47, 19, 4 }
1460e5c31af7Sopenharmony_ci	};
1461e5c31af7Sopenharmony_ci
1462e5c31af7Sopenharmony_ci	for (const auto& bufferSource : bufferSources)
1463e5c31af7Sopenharmony_ci	{
1464e5c31af7Sopenharmony_ci		auto bufferSourceGroup	= new TestCaseGroup(testCtx, bufferSource.second);
1465e5c31af7Sopenharmony_ci
1466e5c31af7Sopenharmony_ci		for (const auto& copyStyle : copyStyles)
1467e5c31af7Sopenharmony_ci		{
1468e5c31af7Sopenharmony_ci			auto copyStyleGroup	= new TestCaseGroup(testCtx, copyStyle.second);
1469e5c31af7Sopenharmony_ci
1470e5c31af7Sopenharmony_ci			for (const auto& submitQueue : submitQueues)
1471e5c31af7Sopenharmony_ci			{
1472e5c31af7Sopenharmony_ci				auto submitQueueGroup = new TestCaseGroup(testCtx, submitQueue.second);
1473e5c31af7Sopenharmony_ci
1474e5c31af7Sopenharmony_ci				for (const auto& traceDimension : traceDimensions)
1475e5c31af7Sopenharmony_ci				{
1476e5c31af7Sopenharmony_ci					TestParams2 testParams
1477e5c31af7Sopenharmony_ci					{
1478e5c31af7Sopenharmony_ci						bufferSource.first,
1479e5c31af7Sopenharmony_ci						traceDimension,
1480e5c31af7Sopenharmony_ci						copyStyle.first,
1481e5c31af7Sopenharmony_ci						submitQueue.first
1482e5c31af7Sopenharmony_ci					};
1483e5c31af7Sopenharmony_ci					const auto testName = makeDimensionsName(traceDimension);
1484e5c31af7Sopenharmony_ci					submitQueueGroup->addChild(new TraceRaysIndirect2Case(testCtx, testName.c_str(), testParams));
1485e5c31af7Sopenharmony_ci				}
1486e5c31af7Sopenharmony_ci				copyStyleGroup->addChild(submitQueueGroup);
1487e5c31af7Sopenharmony_ci			}
1488e5c31af7Sopenharmony_ci			bufferSourceGroup->addChild(copyStyleGroup);
1489e5c31af7Sopenharmony_ci		}
1490e5c31af7Sopenharmony_ci		group->addChild(bufferSourceGroup);
1491e5c31af7Sopenharmony_ci	}
1492e5c31af7Sopenharmony_ci
1493e5c31af7Sopenharmony_ci	return group;
1494e5c31af7Sopenharmony_ci}
1495e5c31af7Sopenharmony_ci
1496e5c31af7Sopenharmony_ci}	// RayTracing
1497e5c31af7Sopenharmony_ci
1498e5c31af7Sopenharmony_ci}	// vkt
1499