1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests
3e5c31af7Sopenharmony_ci * ------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2020 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 Ray Tracing Shader Binding Table tests
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "vktRayTracingShaderBindingTableTests.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#include "vkImageUtil.hpp"
38e5c31af7Sopenharmony_ci#include "deRandom.hpp"
39e5c31af7Sopenharmony_ci#include "tcuTexture.hpp"
40e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp"
41e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
42e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp"
43e5c31af7Sopenharmony_ci
44e5c31af7Sopenharmony_ci#include "vkRayTracingUtil.hpp"
45e5c31af7Sopenharmony_ci
46e5c31af7Sopenharmony_cinamespace vkt
47e5c31af7Sopenharmony_ci{
48e5c31af7Sopenharmony_cinamespace RayTracing
49e5c31af7Sopenharmony_ci{
50e5c31af7Sopenharmony_cinamespace
51e5c31af7Sopenharmony_ci{
52e5c31af7Sopenharmony_ciusing namespace vk;
53e5c31af7Sopenharmony_ciusing namespace vkt;
54e5c31af7Sopenharmony_ci
55e5c31af7Sopenharmony_cistatic const VkFlags	ALL_RAY_TRACING_STAGES	= VK_SHADER_STAGE_RAYGEN_BIT_KHR
56e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_ANY_HIT_BIT_KHR
57e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
58e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_MISS_BIT_KHR
59e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_INTERSECTION_BIT_KHR
60e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_CALLABLE_BIT_KHR;
61e5c31af7Sopenharmony_ci
62e5c31af7Sopenharmony_cienum ShaderTestType
63e5c31af7Sopenharmony_ci{
64e5c31af7Sopenharmony_ci	STT_HIT		= 0,
65e5c31af7Sopenharmony_ci	STT_MISS	= 1,
66e5c31af7Sopenharmony_ci	STT_CALL	= 2,
67e5c31af7Sopenharmony_ci	STT_COUNT	= 3
68e5c31af7Sopenharmony_ci};
69e5c31af7Sopenharmony_ci
70e5c31af7Sopenharmony_ciconst deUint32			CHECKERBOARD_WIDTH			= 8;
71e5c31af7Sopenharmony_ciconst deUint32			CHECKERBOARD_HEIGHT			= 8;
72e5c31af7Sopenharmony_ciconst deUint32			HIT_GEOMETRY_COUNT			= 3;
73e5c31af7Sopenharmony_ciconst deUint32			HIT_INSTANCE_COUNT			= 1 + CHECKERBOARD_WIDTH * CHECKERBOARD_HEIGHT / ( 2 * HIT_GEOMETRY_COUNT );
74e5c31af7Sopenharmony_ci
75e5c31af7Sopenharmony_ciconst deUint32			MAX_SBT_RECORD_OFFSET		= 3;
76e5c31af7Sopenharmony_ciconst deUint32			MAX_HIT_SBT_RECORD_STRIDE	= HIT_GEOMETRY_COUNT + 1;
77e5c31af7Sopenharmony_ciconst deUint32			SBT_RANDOM_SEED				= 1410;
78e5c31af7Sopenharmony_ci
79e5c31af7Sopenharmony_cistruct TestParams;
80e5c31af7Sopenharmony_ci
81e5c31af7Sopenharmony_ciclass TestConfiguration
82e5c31af7Sopenharmony_ci{
83e5c31af7Sopenharmony_cipublic:
84e5c31af7Sopenharmony_ci	virtual std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	initBottomAccelerationStructures	(Context&							context,
85e5c31af7Sopenharmony_ci																												 TestParams&						testParams) = 0;
86e5c31af7Sopenharmony_ci	virtual de::MovePtr<TopLevelAccelerationStructure>						initTopAccelerationStructure		(Context&							context,
87e5c31af7Sopenharmony_ci																												 TestParams&						testParams,
88e5c31af7Sopenharmony_ci																												 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >&	bottomLevelAccelerationStructures) = 0;
89e5c31af7Sopenharmony_ci	virtual de::MovePtr<BufferWithMemory>									initUniformBuffer					(Context&							context,
90e5c31af7Sopenharmony_ci																												 TestParams&						testParams) = 0;
91e5c31af7Sopenharmony_ci	virtual void															initRayTracingShaders				(de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
92e5c31af7Sopenharmony_ci																												 Context&							context,
93e5c31af7Sopenharmony_ci																												TestParams&							testParams) = 0;
94e5c31af7Sopenharmony_ci	virtual void															initShaderBindingTables				(de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
95e5c31af7Sopenharmony_ci																												 Context&							context,
96e5c31af7Sopenharmony_ci																												 TestParams&						testParams,
97e5c31af7Sopenharmony_ci																												 VkPipeline							pipeline,
98e5c31af7Sopenharmony_ci																												 deUint32							shaderGroupHandleSize,
99e5c31af7Sopenharmony_ci																												 deUint32							shaderGroupBaseAlignment,
100e5c31af7Sopenharmony_ci																												 de::MovePtr<BufferWithMemory>&		raygenShaderBindingTable,
101e5c31af7Sopenharmony_ci																												 de::MovePtr<BufferWithMemory>&		hitShaderBindingTable,
102e5c31af7Sopenharmony_ci																												 de::MovePtr<BufferWithMemory>&		missShaderBindingTable,
103e5c31af7Sopenharmony_ci																												 de::MovePtr<BufferWithMemory>&		callableShaderBindingTable,
104e5c31af7Sopenharmony_ci																												 VkStridedDeviceAddressRegionKHR&	raygenShaderBindingTableRegion,
105e5c31af7Sopenharmony_ci																												 VkStridedDeviceAddressRegionKHR&	hitShaderBindingTableRegion,
106e5c31af7Sopenharmony_ci																												 VkStridedDeviceAddressRegionKHR&	missShaderBindingTableRegion,
107e5c31af7Sopenharmony_ci																												 VkStridedDeviceAddressRegionKHR&	callableShaderBindingTableRegion) = 0;
108e5c31af7Sopenharmony_ci	virtual bool															verifyImage							(BufferWithMemory*					resultBuffer,
109e5c31af7Sopenharmony_ci																												 Context&							context,
110e5c31af7Sopenharmony_ci																												 TestParams&						testParams) = 0;
111e5c31af7Sopenharmony_ci	virtual VkFormat														getResultImageFormat				() = 0;
112e5c31af7Sopenharmony_ci	virtual size_t															getResultImageFormatSize			() = 0;
113e5c31af7Sopenharmony_ci	virtual VkClearValue													getClearValue						() = 0;
114e5c31af7Sopenharmony_ci};
115e5c31af7Sopenharmony_ci
116e5c31af7Sopenharmony_cistruct TestParams
117e5c31af7Sopenharmony_ci{
118e5c31af7Sopenharmony_ci	deUint32							width;
119e5c31af7Sopenharmony_ci	deUint32							height;
120e5c31af7Sopenharmony_ci	ShaderTestType						shaderTestType;
121e5c31af7Sopenharmony_ci	deUint32							sbtOffset;
122e5c31af7Sopenharmony_ci	bool								shaderRecordPresent;
123e5c31af7Sopenharmony_ci	deUint32							sbtRecordOffset;
124e5c31af7Sopenharmony_ci	deUint32							sbtRecordOffsetPassedToTraceRay;
125e5c31af7Sopenharmony_ci	deUint32							sbtRecordStride;
126e5c31af7Sopenharmony_ci	deUint32							sbtRecordStridePassedToTraceRay;
127e5c31af7Sopenharmony_ci	de::SharedPtr<TestConfiguration>	testConfiguration;
128e5c31af7Sopenharmony_ci
129e5c31af7Sopenharmony_ci};
130e5c31af7Sopenharmony_ci
131e5c31af7Sopenharmony_cistd::vector<deUint32> getShaderCounts ()
132e5c31af7Sopenharmony_ci{
133e5c31af7Sopenharmony_ci	std::vector<deUint32> shaderCount(STT_COUNT);
134e5c31af7Sopenharmony_ci	shaderCount[STT_HIT]	= HIT_INSTANCE_COUNT + HIT_GEOMETRY_COUNT * MAX_HIT_SBT_RECORD_STRIDE + MAX_SBT_RECORD_OFFSET + 1;
135e5c31af7Sopenharmony_ci	shaderCount[STT_MISS]	= MAX_SBT_RECORD_OFFSET + HIT_INSTANCE_COUNT + 1;
136e5c31af7Sopenharmony_ci	shaderCount[STT_CALL]	= MAX_SBT_RECORD_OFFSET + HIT_INSTANCE_COUNT + 1;
137e5c31af7Sopenharmony_ci	return shaderCount;
138e5c31af7Sopenharmony_ci}
139e5c31af7Sopenharmony_ci
140e5c31af7Sopenharmony_cideUint32 getShaderGroupHandleSize (const InstanceInterface&	vki,
141e5c31af7Sopenharmony_ci								   const VkPhysicalDevice	physicalDevice)
142e5c31af7Sopenharmony_ci{
143e5c31af7Sopenharmony_ci	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
144e5c31af7Sopenharmony_ci
145e5c31af7Sopenharmony_ci	rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physicalDevice);
146e5c31af7Sopenharmony_ci	return rayTracingPropertiesKHR->getShaderGroupHandleSize();
147e5c31af7Sopenharmony_ci}
148e5c31af7Sopenharmony_ci
149e5c31af7Sopenharmony_cideUint32 getShaderGroupBaseAlignment (const InstanceInterface&	vki,
150e5c31af7Sopenharmony_ci									  const VkPhysicalDevice	physicalDevice)
151e5c31af7Sopenharmony_ci{
152e5c31af7Sopenharmony_ci	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
153e5c31af7Sopenharmony_ci
154e5c31af7Sopenharmony_ci	rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
155e5c31af7Sopenharmony_ci	return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
156e5c31af7Sopenharmony_ci}
157e5c31af7Sopenharmony_ci
158e5c31af7Sopenharmony_ciVkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, VkFormat format)
159e5c31af7Sopenharmony_ci{
160e5c31af7Sopenharmony_ci	const VkImageCreateInfo			imageCreateInfo			=
161e5c31af7Sopenharmony_ci	{
162e5c31af7Sopenharmony_ci		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,																// VkStructureType			sType;
163e5c31af7Sopenharmony_ci		DE_NULL,																							// const void*				pNext;
164e5c31af7Sopenharmony_ci		(VkImageCreateFlags)0u,																				// VkImageCreateFlags		flags;
165e5c31af7Sopenharmony_ci		VK_IMAGE_TYPE_2D,																					// VkImageType				imageType;
166e5c31af7Sopenharmony_ci		format,																								// VkFormat					format;
167e5c31af7Sopenharmony_ci		makeExtent3D(width, height, 1),																		// VkExtent3D				extent;
168e5c31af7Sopenharmony_ci		1u,																									// deUint32					mipLevels;
169e5c31af7Sopenharmony_ci		1u,																									// deUint32					arrayLayers;
170e5c31af7Sopenharmony_ci		VK_SAMPLE_COUNT_1_BIT,																				// VkSampleCountFlagBits	samples;
171e5c31af7Sopenharmony_ci		VK_IMAGE_TILING_OPTIMAL,																			// VkImageTiling			tiling;
172e5c31af7Sopenharmony_ci		VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,		// VkImageUsageFlags		usage;
173e5c31af7Sopenharmony_ci		VK_SHARING_MODE_EXCLUSIVE,																			// VkSharingMode			sharingMode;
174e5c31af7Sopenharmony_ci		0u,																									// deUint32					queueFamilyIndexCount;
175e5c31af7Sopenharmony_ci		DE_NULL,																							// const deUint32*			pQueueFamilyIndices;
176e5c31af7Sopenharmony_ci		VK_IMAGE_LAYOUT_UNDEFINED																			// VkImageLayout			initialLayout;
177e5c31af7Sopenharmony_ci	};
178e5c31af7Sopenharmony_ci
179e5c31af7Sopenharmony_ci	return imageCreateInfo;
180e5c31af7Sopenharmony_ci}
181e5c31af7Sopenharmony_ci
182e5c31af7Sopenharmony_ciclass CheckerboardConfiguration : public TestConfiguration
183e5c31af7Sopenharmony_ci{
184e5c31af7Sopenharmony_cipublic:
185e5c31af7Sopenharmony_ci	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	initBottomAccelerationStructures	(Context&							context,
186e5c31af7Sopenharmony_ci																										 TestParams&						testParams) override;
187e5c31af7Sopenharmony_ci	de::MovePtr<TopLevelAccelerationStructure>						initTopAccelerationStructure		(Context&							context,
188e5c31af7Sopenharmony_ci																										 TestParams&						testParams,
189e5c31af7Sopenharmony_ci																										 std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >&	bottomLevelAccelerationStructures) override;
190e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>									initUniformBuffer					(Context&							context,
191e5c31af7Sopenharmony_ci																										 TestParams&						testParams) override;
192e5c31af7Sopenharmony_ci	void															initRayTracingShaders				(de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
193e5c31af7Sopenharmony_ci																										 Context&							context,
194e5c31af7Sopenharmony_ci																										 TestParams&						testParams) override;
195e5c31af7Sopenharmony_ci	void															initShaderBindingTables				(de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
196e5c31af7Sopenharmony_ci																										 Context&							context,
197e5c31af7Sopenharmony_ci																										 TestParams&						testParams,
198e5c31af7Sopenharmony_ci																										 VkPipeline							pipeline,
199e5c31af7Sopenharmony_ci																										 deUint32							shaderGroupHandleSize,
200e5c31af7Sopenharmony_ci																										 deUint32							shaderGroupBaseAlignment,
201e5c31af7Sopenharmony_ci																										 de::MovePtr<BufferWithMemory>&		raygenShaderBindingTable,
202e5c31af7Sopenharmony_ci																										 de::MovePtr<BufferWithMemory>&		hitShaderBindingTable,
203e5c31af7Sopenharmony_ci																										 de::MovePtr<BufferWithMemory>&		missShaderBindingTable,
204e5c31af7Sopenharmony_ci																										 de::MovePtr<BufferWithMemory>&		callableShaderBindingTable,
205e5c31af7Sopenharmony_ci																										 VkStridedDeviceAddressRegionKHR&	raygenShaderBindingTableRegion,
206e5c31af7Sopenharmony_ci																										 VkStridedDeviceAddressRegionKHR&	hitShaderBindingTableRegion,
207e5c31af7Sopenharmony_ci																										 VkStridedDeviceAddressRegionKHR&	missShaderBindingTableRegion,
208e5c31af7Sopenharmony_ci																										 VkStridedDeviceAddressRegionKHR&	callableShaderBindingTableRegion) override;
209e5c31af7Sopenharmony_ci	bool															verifyImage							(BufferWithMemory*					resultBuffer,
210e5c31af7Sopenharmony_ci																										 Context&							context,
211e5c31af7Sopenharmony_ci																										 TestParams&						testParams) override;
212e5c31af7Sopenharmony_ci	VkFormat														getResultImageFormat				() override;
213e5c31af7Sopenharmony_ci	size_t															getResultImageFormatSize			() override;
214e5c31af7Sopenharmony_ci	VkClearValue													getClearValue						() override;
215e5c31af7Sopenharmony_ci};
216e5c31af7Sopenharmony_ci
217e5c31af7Sopenharmony_cistd::vector<de::SharedPtr<BottomLevelAccelerationStructure> > CheckerboardConfiguration::initBottomAccelerationStructures (Context&			context,
218e5c31af7Sopenharmony_ci																														   TestParams&		testParams)
219e5c31af7Sopenharmony_ci{
220e5c31af7Sopenharmony_ci	DE_UNREF(context);
221e5c31af7Sopenharmony_ci
222e5c31af7Sopenharmony_ci	std::vector<tcu::Vec3> corners;
223e5c31af7Sopenharmony_ci	for (deUint32 y = 0; y < testParams.height; ++y)
224e5c31af7Sopenharmony_ci	for (deUint32 x = 0; x < testParams.width; ++x)
225e5c31af7Sopenharmony_ci	{
226e5c31af7Sopenharmony_ci		if (((x + y) % 2) == 0)
227e5c31af7Sopenharmony_ci			continue;
228e5c31af7Sopenharmony_ci		corners.push_back(tcu::Vec3((float)x, (float)y, 0.0f));
229e5c31af7Sopenharmony_ci	}
230e5c31af7Sopenharmony_ci
231e5c31af7Sopenharmony_ci	de::Random	rnd(SBT_RANDOM_SEED);
232e5c31af7Sopenharmony_ci	rnd.shuffle(begin(corners), end(corners));
233e5c31af7Sopenharmony_ci
234e5c31af7Sopenharmony_ci	tcu::Vec3 v0(0.0, 1.0, 0.0);
235e5c31af7Sopenharmony_ci	tcu::Vec3 v1(0.0, 0.0, 0.0);
236e5c31af7Sopenharmony_ci	tcu::Vec3 v2(1.0, 1.0, 0.0);
237e5c31af7Sopenharmony_ci	tcu::Vec3 v3(1.0, 0.0, 0.0);
238e5c31af7Sopenharmony_ci	std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >	result;
239e5c31af7Sopenharmony_ci
240e5c31af7Sopenharmony_ci	for (size_t cornerNdx = 0; cornerNdx < corners.size(); cornerNdx += HIT_GEOMETRY_COUNT)
241e5c31af7Sopenharmony_ci	{
242e5c31af7Sopenharmony_ci		de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure	= makeBottomLevelAccelerationStructure();
243e5c31af7Sopenharmony_ci		size_t											geometryCount						= std::min(corners.size() - cornerNdx, size_t(HIT_GEOMETRY_COUNT));
244e5c31af7Sopenharmony_ci		bottomLevelAccelerationStructure->setGeometryCount(geometryCount);
245e5c31af7Sopenharmony_ci		for (size_t idx = cornerNdx; idx < cornerNdx + geometryCount; ++idx)
246e5c31af7Sopenharmony_ci		{
247e5c31af7Sopenharmony_ci			de::SharedPtr<RaytracedGeometryBase> geometry = makeRaytracedGeometry(VK_GEOMETRY_TYPE_TRIANGLES_KHR, VK_FORMAT_R32G32B32_SFLOAT, VK_INDEX_TYPE_NONE_KHR);
248e5c31af7Sopenharmony_ci			geometry->addVertex(corners[idx] + v0);
249e5c31af7Sopenharmony_ci			geometry->addVertex(corners[idx] + v1);
250e5c31af7Sopenharmony_ci			geometry->addVertex(corners[idx] + v2);
251e5c31af7Sopenharmony_ci			geometry->addVertex(corners[idx] + v2);
252e5c31af7Sopenharmony_ci			geometry->addVertex(corners[idx] + v1);
253e5c31af7Sopenharmony_ci			geometry->addVertex(corners[idx] + v3);
254e5c31af7Sopenharmony_ci			bottomLevelAccelerationStructure->addGeometry(geometry);
255e5c31af7Sopenharmony_ci		}
256e5c31af7Sopenharmony_ci		result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
257e5c31af7Sopenharmony_ci	}
258e5c31af7Sopenharmony_ci	return result;
259e5c31af7Sopenharmony_ci}
260e5c31af7Sopenharmony_ci
261e5c31af7Sopenharmony_cide::MovePtr<TopLevelAccelerationStructure> CheckerboardConfiguration::initTopAccelerationStructure (Context&		context,
262e5c31af7Sopenharmony_ci																									TestParams&		testParams,
263e5c31af7Sopenharmony_ci																									std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >& bottomLevelAccelerationStructures)
264e5c31af7Sopenharmony_ci{
265e5c31af7Sopenharmony_ci	DE_UNREF(context);
266e5c31af7Sopenharmony_ci	DE_UNREF(testParams);
267e5c31af7Sopenharmony_ci
268e5c31af7Sopenharmony_ci	de::MovePtr<TopLevelAccelerationStructure>	result						= makeTopLevelAccelerationStructure();
269e5c31af7Sopenharmony_ci	deUint32									instanceCount				= deUint32(bottomLevelAccelerationStructures.size());
270e5c31af7Sopenharmony_ci	result->setInstanceCount(instanceCount);
271e5c31af7Sopenharmony_ci
272e5c31af7Sopenharmony_ci	VkTransformMatrixKHR						identityMatrix				= { { { 1.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f, 0.0f } } };
273e5c31af7Sopenharmony_ci	for (deUint32 i = 0; i < instanceCount; ++i)
274e5c31af7Sopenharmony_ci		result->addInstance(bottomLevelAccelerationStructures[i], identityMatrix, 0u, 0xFF, (testParams.shaderTestType == STT_MISS) ? 0 : i);
275e5c31af7Sopenharmony_ci
276e5c31af7Sopenharmony_ci	return result;
277e5c31af7Sopenharmony_ci}
278e5c31af7Sopenharmony_ci
279e5c31af7Sopenharmony_cide::MovePtr<BufferWithMemory> CheckerboardConfiguration::initUniformBuffer (Context&		context,
280e5c31af7Sopenharmony_ci																			TestParams&		testParams)
281e5c31af7Sopenharmony_ci{
282e5c31af7Sopenharmony_ci	const DeviceInterface&						vkd			= context.getDeviceInterface();
283e5c31af7Sopenharmony_ci	const VkDevice								device		= context.getDevice();
284e5c31af7Sopenharmony_ci	Allocator&									allocator	= context.getDefaultAllocator();
285e5c31af7Sopenharmony_ci
286e5c31af7Sopenharmony_ci	const VkBufferCreateInfo		uniformBufferCreateInfo	= makeBufferCreateInfo(sizeof(tcu::UVec4), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
287e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	uniformBuffer			= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, uniformBufferCreateInfo, MemoryRequirement::HostVisible));
288e5c31af7Sopenharmony_ci	tcu::UVec4						uniformValue;			// x = sbtRecordOffset, y = sbtRecordStride, z = missIndex
289e5c31af7Sopenharmony_ci	switch (testParams.shaderTestType)
290e5c31af7Sopenharmony_ci	{
291e5c31af7Sopenharmony_ci		case STT_HIT:
292e5c31af7Sopenharmony_ci		{
293e5c31af7Sopenharmony_ci			uniformValue = tcu::UVec4(testParams.sbtRecordOffsetPassedToTraceRay, testParams.sbtRecordStride, 0, 0);
294e5c31af7Sopenharmony_ci			break;
295e5c31af7Sopenharmony_ci		}
296e5c31af7Sopenharmony_ci		case STT_MISS:
297e5c31af7Sopenharmony_ci		{
298e5c31af7Sopenharmony_ci			uniformValue = tcu::UVec4(0, 0, testParams.sbtRecordOffsetPassedToTraceRay, 0);
299e5c31af7Sopenharmony_ci			break;
300e5c31af7Sopenharmony_ci		}
301e5c31af7Sopenharmony_ci		case STT_CALL:
302e5c31af7Sopenharmony_ci		{
303e5c31af7Sopenharmony_ci			uniformValue = tcu::UVec4(testParams.sbtRecordOffsetPassedToTraceRay, testParams.sbtRecordStride, 0, 0);
304e5c31af7Sopenharmony_ci			break;
305e5c31af7Sopenharmony_ci		}
306e5c31af7Sopenharmony_ci		default:
307e5c31af7Sopenharmony_ci			TCU_THROW(InternalError, "Wrong shader test type");
308e5c31af7Sopenharmony_ci	}
309e5c31af7Sopenharmony_ci	deMemcpy(uniformBuffer->getAllocation().getHostPtr(), &uniformValue, sizeof(tcu::UVec4));
310e5c31af7Sopenharmony_ci	flushMappedMemoryRange(vkd, device, uniformBuffer->getAllocation().getMemory(), uniformBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
311e5c31af7Sopenharmony_ci
312e5c31af7Sopenharmony_ci	return uniformBuffer;
313e5c31af7Sopenharmony_ci}
314e5c31af7Sopenharmony_ci
315e5c31af7Sopenharmony_civoid CheckerboardConfiguration::initRayTracingShaders (de::MovePtr<RayTracingPipeline>&		rayTracingPipeline,
316e5c31af7Sopenharmony_ci													   Context&								context,
317e5c31af7Sopenharmony_ci													   TestParams&							testParams)
318e5c31af7Sopenharmony_ci{
319e5c31af7Sopenharmony_ci	const DeviceInterface&						vkd						= context.getDeviceInterface();
320e5c31af7Sopenharmony_ci	const VkDevice								device					= context.getDevice();
321e5c31af7Sopenharmony_ci
322e5c31af7Sopenharmony_ci	std::vector<deUint32>						shaderCount				= getShaderCounts();
323e5c31af7Sopenharmony_ci
324e5c31af7Sopenharmony_ci	switch (testParams.shaderTestType)
325e5c31af7Sopenharmony_ci	{
326e5c31af7Sopenharmony_ci		case STT_HIT:
327e5c31af7Sopenharmony_ci		{
328e5c31af7Sopenharmony_ci			if (testParams.shaderRecordPresent)
329e5c31af7Sopenharmony_ci			{
330e5c31af7Sopenharmony_ci				// shaders: rgen, chit_shaderRecord (N times), miss_0
331e5c31af7Sopenharmony_ci				rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("rgen"), 0), 0);
332e5c31af7Sopenharmony_ci				for (deUint32 idx = 0; idx < shaderCount[STT_HIT]; ++idx)
333e5c31af7Sopenharmony_ci					rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("chit_shaderRecord"), 0), 1+idx);
334e5c31af7Sopenharmony_ci				rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("miss_0"), 0), 1 + shaderCount[STT_HIT]);
335e5c31af7Sopenharmony_ci			}
336e5c31af7Sopenharmony_ci			else
337e5c31af7Sopenharmony_ci			{
338e5c31af7Sopenharmony_ci				// shaders: rgen, chit_0 .. chit_N, miss_0
339e5c31af7Sopenharmony_ci				rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("rgen"), 0), 0);
340e5c31af7Sopenharmony_ci				for (deUint32 idx = 0; idx < shaderCount[STT_HIT]; ++idx)
341e5c31af7Sopenharmony_ci				{
342e5c31af7Sopenharmony_ci					std::stringstream csname;
343e5c31af7Sopenharmony_ci					csname << "chit_" << idx;
344e5c31af7Sopenharmony_ci					rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get(csname.str()), 0), 1 + idx);
345e5c31af7Sopenharmony_ci				}
346e5c31af7Sopenharmony_ci				rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("miss_0"), 0), 1 + shaderCount[STT_HIT]);
347e5c31af7Sopenharmony_ci			}
348e5c31af7Sopenharmony_ci			rayTracingPipeline->setMaxPayloadSize(16u);
349e5c31af7Sopenharmony_ci			break;
350e5c31af7Sopenharmony_ci		}
351e5c31af7Sopenharmony_ci		case STT_MISS:
352e5c31af7Sopenharmony_ci		{
353e5c31af7Sopenharmony_ci			if (testParams.shaderRecordPresent)
354e5c31af7Sopenharmony_ci			{
355e5c31af7Sopenharmony_ci				// shaders: rgen, chit_0, miss_shaderRecord ( N times )
356e5c31af7Sopenharmony_ci				rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("rgen"), 0), 0);
357e5c31af7Sopenharmony_ci				rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("chit_0"), 0), 1);
358e5c31af7Sopenharmony_ci				for (deUint32 idx = 0; idx < shaderCount[STT_MISS]; ++idx)
359e5c31af7Sopenharmony_ci					rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("miss_shaderRecord"), 0), 2 + idx);
360e5c31af7Sopenharmony_ci			}
361e5c31af7Sopenharmony_ci			else
362e5c31af7Sopenharmony_ci			{
363e5c31af7Sopenharmony_ci				// shaders: rgen, chit_0, miss_0 .. miss_N
364e5c31af7Sopenharmony_ci				rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("rgen"), 0), 0);
365e5c31af7Sopenharmony_ci				rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("chit_0"), 0), 1);
366e5c31af7Sopenharmony_ci				for (deUint32 idx = 0; idx < shaderCount[STT_MISS]; ++idx)
367e5c31af7Sopenharmony_ci				{
368e5c31af7Sopenharmony_ci					std::stringstream csname;
369e5c31af7Sopenharmony_ci					csname << "miss_" << idx;
370e5c31af7Sopenharmony_ci					rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get(csname.str()), 0), 2 + idx);
371e5c31af7Sopenharmony_ci				}
372e5c31af7Sopenharmony_ci			}
373e5c31af7Sopenharmony_ci			rayTracingPipeline->setMaxPayloadSize(16u);
374e5c31af7Sopenharmony_ci			break;
375e5c31af7Sopenharmony_ci		}
376e5c31af7Sopenharmony_ci		case STT_CALL:
377e5c31af7Sopenharmony_ci		{
378e5c31af7Sopenharmony_ci			if (testParams.shaderRecordPresent)
379e5c31af7Sopenharmony_ci			{
380e5c31af7Sopenharmony_ci				// shaders: rgen, chit_call_0 .. chit_call_N, miss_0, call_shaderRecord ( N times )
381e5c31af7Sopenharmony_ci				rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("rgen"), 0), 0);
382e5c31af7Sopenharmony_ci				for (deUint32 idx = 0; idx < shaderCount[STT_CALL]; ++idx)
383e5c31af7Sopenharmony_ci				{
384e5c31af7Sopenharmony_ci					std::stringstream csname;
385e5c31af7Sopenharmony_ci					csname << "chit_call_" << idx;
386e5c31af7Sopenharmony_ci					rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get(csname.str()), 0), 1 + idx);
387e5c31af7Sopenharmony_ci				}
388e5c31af7Sopenharmony_ci				rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("miss_0"), 0), 1 + shaderCount[STT_CALL]);
389e5c31af7Sopenharmony_ci				for (deUint32 idx = 0; idx < shaderCount[STT_CALL]; ++idx)
390e5c31af7Sopenharmony_ci					rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("call_shaderRecord"), 0), 2 + shaderCount[STT_CALL] + idx);
391e5c31af7Sopenharmony_ci			}
392e5c31af7Sopenharmony_ci			else
393e5c31af7Sopenharmony_ci			{
394e5c31af7Sopenharmony_ci				// shaders: rgen, chit_call_0 .. chit_call_N, miss_0, call_0 .. call_N
395e5c31af7Sopenharmony_ci				rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("rgen"), 0), 0);
396e5c31af7Sopenharmony_ci				for (deUint32 idx = 0; idx < shaderCount[STT_CALL]; ++idx)
397e5c31af7Sopenharmony_ci				{
398e5c31af7Sopenharmony_ci					std::stringstream csname;
399e5c31af7Sopenharmony_ci					csname << "chit_call_" << idx;
400e5c31af7Sopenharmony_ci					rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get(csname.str()), 0), 1 + idx);
401e5c31af7Sopenharmony_ci				}
402e5c31af7Sopenharmony_ci				rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get("miss_0"), 0), 1 + shaderCount[STT_CALL]);
403e5c31af7Sopenharmony_ci				for (deUint32 idx = 0; idx < shaderCount[STT_CALL]; ++idx)
404e5c31af7Sopenharmony_ci				{
405e5c31af7Sopenharmony_ci					std::stringstream csname;
406e5c31af7Sopenharmony_ci					csname << "call_" << idx;
407e5c31af7Sopenharmony_ci					rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get(csname.str()), 0), 2 + shaderCount[STT_CALL] + idx);
408e5c31af7Sopenharmony_ci				}
409e5c31af7Sopenharmony_ci			}
410e5c31af7Sopenharmony_ci			rayTracingPipeline->setMaxPayloadSize(16u);
411e5c31af7Sopenharmony_ci			break;
412e5c31af7Sopenharmony_ci		}
413e5c31af7Sopenharmony_ci		default:
414e5c31af7Sopenharmony_ci			TCU_THROW(InternalError, "Wrong shader test type");
415e5c31af7Sopenharmony_ci	}
416e5c31af7Sopenharmony_ci}
417e5c31af7Sopenharmony_ci
418e5c31af7Sopenharmony_civoid CheckerboardConfiguration::initShaderBindingTables (de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
419e5c31af7Sopenharmony_ci														 Context&							context,
420e5c31af7Sopenharmony_ci														 TestParams&						testParams,
421e5c31af7Sopenharmony_ci														 VkPipeline							pipeline,
422e5c31af7Sopenharmony_ci														 deUint32							shaderGroupHandleSize,
423e5c31af7Sopenharmony_ci														 deUint32							shaderGroupBaseAlignment,
424e5c31af7Sopenharmony_ci														 de::MovePtr<BufferWithMemory>&		raygenShaderBindingTable,
425e5c31af7Sopenharmony_ci														 de::MovePtr<BufferWithMemory>&		hitShaderBindingTable,
426e5c31af7Sopenharmony_ci														 de::MovePtr<BufferWithMemory>&		missShaderBindingTable,
427e5c31af7Sopenharmony_ci														 de::MovePtr<BufferWithMemory>&		callableShaderBindingTable,
428e5c31af7Sopenharmony_ci														 VkStridedDeviceAddressRegionKHR&	raygenShaderBindingTableRegion,
429e5c31af7Sopenharmony_ci														 VkStridedDeviceAddressRegionKHR&	hitShaderBindingTableRegion,
430e5c31af7Sopenharmony_ci														 VkStridedDeviceAddressRegionKHR&	missShaderBindingTableRegion,
431e5c31af7Sopenharmony_ci														 VkStridedDeviceAddressRegionKHR&	callableShaderBindingTableRegion)
432e5c31af7Sopenharmony_ci{
433e5c31af7Sopenharmony_ci	const DeviceInterface&						vkd							= context.getDeviceInterface();
434e5c31af7Sopenharmony_ci	const VkDevice								device						= context.getDevice();
435e5c31af7Sopenharmony_ci	Allocator&									allocator					= context.getDefaultAllocator();
436e5c31af7Sopenharmony_ci
437e5c31af7Sopenharmony_ci	std::vector<deUint32>						shaderCount					= getShaderCounts();
438e5c31af7Sopenharmony_ci
439e5c31af7Sopenharmony_ci	// shaderBindingTableOffset must be multiple of shaderGroupBaseAlignment
440e5c31af7Sopenharmony_ci	deUint32									shaderBindingTableOffset	= testParams.sbtOffset * shaderGroupBaseAlignment;
441e5c31af7Sopenharmony_ci
442e5c31af7Sopenharmony_ci	// ShaderRecordKHR size must be multiple of shaderGroupHandleSize
443e5c31af7Sopenharmony_ci	deUint32									shaderRecordAlignedSize		= deAlign32(shaderGroupHandleSize + deUint32(sizeof(tcu::UVec4)), shaderGroupHandleSize);
444e5c31af7Sopenharmony_ci	switch (testParams.shaderTestType)
445e5c31af7Sopenharmony_ci	{
446e5c31af7Sopenharmony_ci		case STT_HIT:
447e5c31af7Sopenharmony_ci		{
448e5c31af7Sopenharmony_ci			raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1 );
449e5c31af7Sopenharmony_ci			if(testParams.shaderRecordPresent)
450e5c31af7Sopenharmony_ci				hitShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, shaderCount[STT_HIT], 0u, 0u, MemoryRequirement::Any, 0u, shaderBindingTableOffset, sizeof(tcu::UVec4));
451e5c31af7Sopenharmony_ci			else
452e5c31af7Sopenharmony_ci				hitShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, shaderCount[STT_HIT], 0u, 0u, MemoryRequirement::Any, 0u, shaderBindingTableOffset);
453e5c31af7Sopenharmony_ci			missShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1 + shaderCount[STT_HIT], 1 );
454e5c31af7Sopenharmony_ci
455e5c31af7Sopenharmony_ci			raygenShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
456e5c31af7Sopenharmony_ci			if (testParams.shaderRecordPresent)
457e5c31af7Sopenharmony_ci				hitShaderBindingTableRegion			= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), shaderBindingTableOffset), shaderRecordAlignedSize, shaderCount[STT_HIT] * shaderRecordAlignedSize);
458e5c31af7Sopenharmony_ci			else
459e5c31af7Sopenharmony_ci				hitShaderBindingTableRegion			= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), shaderBindingTableOffset), shaderGroupHandleSize, shaderCount[STT_HIT] * shaderGroupHandleSize);
460e5c31af7Sopenharmony_ci			missShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
461e5c31af7Sopenharmony_ci			callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
462e5c31af7Sopenharmony_ci
463e5c31af7Sopenharmony_ci			// fill ShaderRecordKHR data
464e5c31af7Sopenharmony_ci			if (testParams.shaderRecordPresent)
465e5c31af7Sopenharmony_ci			{
466e5c31af7Sopenharmony_ci				deUint8* hitAddressBegin = (deUint8*)hitShaderBindingTable->getAllocation().getHostPtr() + shaderBindingTableOffset;
467e5c31af7Sopenharmony_ci
468e5c31af7Sopenharmony_ci				for (size_t idx = 0; idx < shaderCount[STT_HIT]; ++idx)
469e5c31af7Sopenharmony_ci				{
470e5c31af7Sopenharmony_ci					deUint8* shaderRecordAddress = hitAddressBegin + idx * shaderRecordAlignedSize + size_t(shaderGroupHandleSize);
471e5c31af7Sopenharmony_ci					tcu::UVec4 shaderRecord(deUint32(idx), 0, 0, 0);
472e5c31af7Sopenharmony_ci					deMemcpy(shaderRecordAddress, &shaderRecord, sizeof(tcu::UVec4));
473e5c31af7Sopenharmony_ci				}
474e5c31af7Sopenharmony_ci
475e5c31af7Sopenharmony_ci				flushMappedMemoryRange(vkd, device, hitShaderBindingTable->getAllocation().getMemory(), hitShaderBindingTable->getAllocation().getOffset(), VK_WHOLE_SIZE);
476e5c31af7Sopenharmony_ci			}
477e5c31af7Sopenharmony_ci			break;
478e5c31af7Sopenharmony_ci		}
479e5c31af7Sopenharmony_ci		case STT_MISS:
480e5c31af7Sopenharmony_ci		{
481e5c31af7Sopenharmony_ci			raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1 );
482e5c31af7Sopenharmony_ci			hitShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1 );
483e5c31af7Sopenharmony_ci			if (testParams.shaderRecordPresent)
484e5c31af7Sopenharmony_ci				missShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, shaderCount[STT_MISS], 0u, 0u, MemoryRequirement::Any, 0u, shaderBindingTableOffset, sizeof(tcu::UVec4));
485e5c31af7Sopenharmony_ci			else
486e5c31af7Sopenharmony_ci				missShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, shaderCount[STT_MISS], 0u, 0u, MemoryRequirement::Any, 0u, shaderBindingTableOffset);
487e5c31af7Sopenharmony_ci
488e5c31af7Sopenharmony_ci			raygenShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
489e5c31af7Sopenharmony_ci			hitShaderBindingTableRegion			= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), 0, shaderGroupHandleSize);
490e5c31af7Sopenharmony_ci			if (testParams.shaderRecordPresent)
491e5c31af7Sopenharmony_ci				missShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), shaderBindingTableOffset), shaderRecordAlignedSize, shaderCount[STT_MISS] * shaderRecordAlignedSize);
492e5c31af7Sopenharmony_ci			else
493e5c31af7Sopenharmony_ci				missShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), shaderBindingTableOffset), shaderGroupHandleSize, shaderCount[STT_MISS] * shaderGroupHandleSize);
494e5c31af7Sopenharmony_ci			callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
495e5c31af7Sopenharmony_ci
496e5c31af7Sopenharmony_ci			if (testParams.shaderRecordPresent)
497e5c31af7Sopenharmony_ci			{
498e5c31af7Sopenharmony_ci				deUint8* missAddressBegin = (deUint8*)missShaderBindingTable->getAllocation().getHostPtr() + shaderBindingTableOffset;
499e5c31af7Sopenharmony_ci
500e5c31af7Sopenharmony_ci				for (size_t idx = 0; idx < shaderCount[STT_MISS]; ++idx)
501e5c31af7Sopenharmony_ci				{
502e5c31af7Sopenharmony_ci					deUint8* shaderRecordAddress = missAddressBegin + idx * shaderRecordAlignedSize + size_t(shaderGroupHandleSize);
503e5c31af7Sopenharmony_ci					tcu::UVec4 shaderRecord(deUint32(idx), 0, 0, 0);
504e5c31af7Sopenharmony_ci					deMemcpy(shaderRecordAddress, &shaderRecord, sizeof(tcu::UVec4));
505e5c31af7Sopenharmony_ci				}
506e5c31af7Sopenharmony_ci
507e5c31af7Sopenharmony_ci				flushMappedMemoryRange(vkd, device, missShaderBindingTable->getAllocation().getMemory(), missShaderBindingTable->getAllocation().getOffset(), VK_WHOLE_SIZE);
508e5c31af7Sopenharmony_ci			}
509e5c31af7Sopenharmony_ci			break;
510e5c31af7Sopenharmony_ci		}
511e5c31af7Sopenharmony_ci		case STT_CALL:
512e5c31af7Sopenharmony_ci		{
513e5c31af7Sopenharmony_ci			raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1 );
514e5c31af7Sopenharmony_ci			hitShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, shaderCount[STT_CALL]);
515e5c31af7Sopenharmony_ci			missShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1 + shaderCount[STT_CALL], 1 );
516e5c31af7Sopenharmony_ci			if (testParams.shaderRecordPresent)
517e5c31af7Sopenharmony_ci				callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2 + shaderCount[STT_CALL], shaderCount[STT_CALL], 0u, 0u, MemoryRequirement::Any, 0u, shaderBindingTableOffset, sizeof(tcu::UVec4));
518e5c31af7Sopenharmony_ci			else
519e5c31af7Sopenharmony_ci				callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2 + shaderCount[STT_CALL], shaderCount[STT_CALL], 0u, 0u, MemoryRequirement::Any, 0u, shaderBindingTableOffset);
520e5c31af7Sopenharmony_ci
521e5c31af7Sopenharmony_ci			raygenShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
522e5c31af7Sopenharmony_ci			hitShaderBindingTableRegion			= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderCount[STT_CALL] * shaderGroupHandleSize);
523e5c31af7Sopenharmony_ci			missShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
524e5c31af7Sopenharmony_ci			if (testParams.shaderRecordPresent)
525e5c31af7Sopenharmony_ci				callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), shaderBindingTableOffset), shaderRecordAlignedSize, shaderCount[STT_CALL] * shaderRecordAlignedSize);
526e5c31af7Sopenharmony_ci			else
527e5c31af7Sopenharmony_ci				callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), shaderBindingTableOffset), shaderGroupHandleSize, shaderCount[STT_CALL] * shaderGroupHandleSize);
528e5c31af7Sopenharmony_ci
529e5c31af7Sopenharmony_ci			if (testParams.shaderRecordPresent)
530e5c31af7Sopenharmony_ci			{
531e5c31af7Sopenharmony_ci				deUint8* callAddressBegin	= (deUint8*)callableShaderBindingTable->getAllocation().getHostPtr() + shaderBindingTableOffset;
532e5c31af7Sopenharmony_ci
533e5c31af7Sopenharmony_ci				for (size_t idx = 0; idx < shaderCount[STT_CALL]; ++idx)
534e5c31af7Sopenharmony_ci				{
535e5c31af7Sopenharmony_ci					deUint8* shaderRecordAddress = callAddressBegin + idx * shaderRecordAlignedSize + size_t(shaderGroupHandleSize);
536e5c31af7Sopenharmony_ci					tcu::UVec4 shaderRecord(deUint32(idx), 0, 0, 0);
537e5c31af7Sopenharmony_ci					deMemcpy(shaderRecordAddress, &shaderRecord, sizeof(tcu::UVec4));
538e5c31af7Sopenharmony_ci				}
539e5c31af7Sopenharmony_ci				flushMappedMemoryRange(vkd, device, callableShaderBindingTable->getAllocation().getMemory(), callableShaderBindingTable->getAllocation().getOffset(), VK_WHOLE_SIZE);
540e5c31af7Sopenharmony_ci			}
541e5c31af7Sopenharmony_ci			break;
542e5c31af7Sopenharmony_ci		}
543e5c31af7Sopenharmony_ci		default:
544e5c31af7Sopenharmony_ci			TCU_THROW(InternalError, "Wrong shader test type");
545e5c31af7Sopenharmony_ci	}
546e5c31af7Sopenharmony_ci}
547e5c31af7Sopenharmony_ci
548e5c31af7Sopenharmony_cibool CheckerboardConfiguration::verifyImage (BufferWithMemory* resultBuffer, Context& context, TestParams& testParams)
549e5c31af7Sopenharmony_ci{
550e5c31af7Sopenharmony_ci	// create result image
551e5c31af7Sopenharmony_ci	tcu::TextureFormat			imageFormat						= vk::mapVkFormat(getResultImageFormat());
552e5c31af7Sopenharmony_ci	tcu::ConstPixelBufferAccess	resultAccess(imageFormat, testParams.width, testParams.height, 1, resultBuffer->getAllocation().getHostPtr());
553e5c31af7Sopenharmony_ci
554e5c31af7Sopenharmony_ci	// recreate geometry indices and instance offsets
555e5c31af7Sopenharmony_ci	std::vector<tcu::UVec4> corners;
556e5c31af7Sopenharmony_ci	for (deUint32 y = 0; y < testParams.height; ++y)
557e5c31af7Sopenharmony_ci	for (deUint32 x = 0; x < testParams.width; ++x)
558e5c31af7Sopenharmony_ci	{
559e5c31af7Sopenharmony_ci		if (((x + y) % 2) == 0)
560e5c31af7Sopenharmony_ci			continue;
561e5c31af7Sopenharmony_ci		corners.push_back(tcu::UVec4(x, y, 0, 0));
562e5c31af7Sopenharmony_ci	}
563e5c31af7Sopenharmony_ci	de::Random					rnd(SBT_RANDOM_SEED);
564e5c31af7Sopenharmony_ci	rnd.shuffle(begin(corners), end(corners));
565e5c31af7Sopenharmony_ci
566e5c31af7Sopenharmony_ci	deUint32					instanceOffset	= 0;
567e5c31af7Sopenharmony_ci	for (size_t cornerNdx = 0; cornerNdx < corners.size(); cornerNdx += HIT_GEOMETRY_COUNT, ++instanceOffset)
568e5c31af7Sopenharmony_ci	{
569e5c31af7Sopenharmony_ci		size_t											geometryCount = std::min(corners.size() - cornerNdx, size_t(HIT_GEOMETRY_COUNT));
570e5c31af7Sopenharmony_ci		deUint32 geometryIndex = 0;
571e5c31af7Sopenharmony_ci		for (size_t idx = cornerNdx; idx < cornerNdx + geometryCount; ++idx, ++geometryIndex)
572e5c31af7Sopenharmony_ci		{
573e5c31af7Sopenharmony_ci			corners[idx].z() = instanceOffset;
574e5c31af7Sopenharmony_ci			corners[idx].w() = geometryIndex;
575e5c31af7Sopenharmony_ci		}
576e5c31af7Sopenharmony_ci	}
577e5c31af7Sopenharmony_ci
578e5c31af7Sopenharmony_ci	std::vector<deUint32>		reference(testParams.width * testParams.height);
579e5c31af7Sopenharmony_ci	tcu::PixelBufferAccess		referenceAccess(imageFormat, testParams.width, testParams.height, 1, reference.data());
580e5c31af7Sopenharmony_ci	// clear image with miss values
581e5c31af7Sopenharmony_ci	tcu::UVec4 missValue((testParams.shaderTestType == STT_MISS) ? testParams.sbtRecordOffset : 0, 0, 0, 0);
582e5c31af7Sopenharmony_ci	tcu::clear(referenceAccess, missValue);
583e5c31af7Sopenharmony_ci
584e5c31af7Sopenharmony_ci	// for each pixel - set its color to proper value
585e5c31af7Sopenharmony_ci	for (const auto& pixel : corners)
586e5c31af7Sopenharmony_ci	{
587e5c31af7Sopenharmony_ci		deUint32 shaderIndex;
588e5c31af7Sopenharmony_ci		switch (testParams.shaderTestType)
589e5c31af7Sopenharmony_ci		{
590e5c31af7Sopenharmony_ci		case STT_HIT:
591e5c31af7Sopenharmony_ci		{
592e5c31af7Sopenharmony_ci			shaderIndex = testParams.sbtRecordOffset + pixel.z() + pixel.w() * testParams.sbtRecordStride;
593e5c31af7Sopenharmony_ci			break;
594e5c31af7Sopenharmony_ci		}
595e5c31af7Sopenharmony_ci		case STT_MISS:
596e5c31af7Sopenharmony_ci		{
597e5c31af7Sopenharmony_ci			shaderIndex = 0;// pixel.z();
598e5c31af7Sopenharmony_ci			break;
599e5c31af7Sopenharmony_ci		}
600e5c31af7Sopenharmony_ci		case STT_CALL:
601e5c31af7Sopenharmony_ci		{
602e5c31af7Sopenharmony_ci			shaderIndex = testParams.sbtRecordOffset + pixel.z() + pixel.w() * testParams.sbtRecordStride;
603e5c31af7Sopenharmony_ci			break;
604e5c31af7Sopenharmony_ci		}
605e5c31af7Sopenharmony_ci		default:
606e5c31af7Sopenharmony_ci			TCU_THROW(InternalError, "Wrong shader test type");
607e5c31af7Sopenharmony_ci		}
608e5c31af7Sopenharmony_ci
609e5c31af7Sopenharmony_ci		referenceAccess.setPixel(tcu::UVec4(shaderIndex, 0, 0, 0), pixel.x(), pixel.y());
610e5c31af7Sopenharmony_ci	}
611e5c31af7Sopenharmony_ci
612e5c31af7Sopenharmony_ci	// compare result and reference
613e5c31af7Sopenharmony_ci	return tcu::intThresholdCompare(context.getTestContext().getLog(), "Result comparison", "", referenceAccess, resultAccess, tcu::UVec4(0), tcu::COMPARE_LOG_RESULT);
614e5c31af7Sopenharmony_ci}
615e5c31af7Sopenharmony_ci
616e5c31af7Sopenharmony_ciVkFormat CheckerboardConfiguration::getResultImageFormat ()
617e5c31af7Sopenharmony_ci{
618e5c31af7Sopenharmony_ci	return VK_FORMAT_R32_UINT;
619e5c31af7Sopenharmony_ci}
620e5c31af7Sopenharmony_ci
621e5c31af7Sopenharmony_cisize_t CheckerboardConfiguration::getResultImageFormatSize ()
622e5c31af7Sopenharmony_ci{
623e5c31af7Sopenharmony_ci	return sizeof(deUint32);
624e5c31af7Sopenharmony_ci}
625e5c31af7Sopenharmony_ci
626e5c31af7Sopenharmony_ciVkClearValue CheckerboardConfiguration::getClearValue ()
627e5c31af7Sopenharmony_ci{
628e5c31af7Sopenharmony_ci	return makeClearValueColorU32(0xFF, 0u, 0u, 0u);
629e5c31af7Sopenharmony_ci}
630e5c31af7Sopenharmony_ci
631e5c31af7Sopenharmony_ciclass ShaderBindingTableIndexingTestCase : public TestCase
632e5c31af7Sopenharmony_ci{
633e5c31af7Sopenharmony_ci	public:
634e5c31af7Sopenharmony_ci							ShaderBindingTableIndexingTestCase			(tcu::TestContext& context, const char* name, const TestParams data);
635e5c31af7Sopenharmony_ci							~ShaderBindingTableIndexingTestCase			(void);
636e5c31af7Sopenharmony_ci
637e5c31af7Sopenharmony_ci	virtual void			checkSupport								(Context& context) const;
638e5c31af7Sopenharmony_ci	virtual	void			initPrograms								(SourceCollections& programCollection) const;
639e5c31af7Sopenharmony_ci	virtual TestInstance*	createInstance								(Context& context) const;
640e5c31af7Sopenharmony_ciprivate:
641e5c31af7Sopenharmony_ci	TestParams				m_data;
642e5c31af7Sopenharmony_ci};
643e5c31af7Sopenharmony_ci
644e5c31af7Sopenharmony_ciclass ShaderBindingTableIndexingTestInstance : public TestInstance
645e5c31af7Sopenharmony_ci{
646e5c31af7Sopenharmony_cipublic:
647e5c31af7Sopenharmony_ci																	ShaderBindingTableIndexingTestInstance	(Context& context, const TestParams& data);
648e5c31af7Sopenharmony_ci																	~ShaderBindingTableIndexingTestInstance	(void);
649e5c31af7Sopenharmony_ci	tcu::TestStatus													iterate									(void);
650e5c31af7Sopenharmony_ci
651e5c31af7Sopenharmony_ciprotected:
652e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>									runTest									();
653e5c31af7Sopenharmony_ciprivate:
654e5c31af7Sopenharmony_ci	TestParams														m_data;
655e5c31af7Sopenharmony_ci};
656e5c31af7Sopenharmony_ci
657e5c31af7Sopenharmony_ciShaderBindingTableIndexingTestCase::ShaderBindingTableIndexingTestCase (tcu::TestContext& context, const char* name, const TestParams data)
658e5c31af7Sopenharmony_ci	: vkt::TestCase	(context, name)
659e5c31af7Sopenharmony_ci	, m_data		(data)
660e5c31af7Sopenharmony_ci{
661e5c31af7Sopenharmony_ci}
662e5c31af7Sopenharmony_ci
663e5c31af7Sopenharmony_ciShaderBindingTableIndexingTestCase::~ShaderBindingTableIndexingTestCase (void)
664e5c31af7Sopenharmony_ci{
665e5c31af7Sopenharmony_ci}
666e5c31af7Sopenharmony_ci
667e5c31af7Sopenharmony_civoid ShaderBindingTableIndexingTestCase::checkSupport (Context& context) const
668e5c31af7Sopenharmony_ci{
669e5c31af7Sopenharmony_ci	context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
670e5c31af7Sopenharmony_ci	context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
671e5c31af7Sopenharmony_ci
672e5c31af7Sopenharmony_ci	const VkPhysicalDeviceRayTracingPipelineFeaturesKHR&	rayTracingPipelineFeaturesKHR		= context.getRayTracingPipelineFeatures();
673e5c31af7Sopenharmony_ci	if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE )
674e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
675e5c31af7Sopenharmony_ci
676e5c31af7Sopenharmony_ci	const VkPhysicalDeviceAccelerationStructureFeaturesKHR&	accelerationStructureFeaturesKHR	= context.getAccelerationStructureFeatures();
677e5c31af7Sopenharmony_ci	if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
678e5c31af7Sopenharmony_ci		TCU_THROW(TestError, "VK_KHR_ray_tracing_pipeline requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
679e5c31af7Sopenharmony_ci}
680e5c31af7Sopenharmony_ci
681e5c31af7Sopenharmony_civoid ShaderBindingTableIndexingTestCase::initPrograms (SourceCollections& programCollection) const
682e5c31af7Sopenharmony_ci{
683e5c31af7Sopenharmony_ci	const vk::ShaderBuildOptions	buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
684e5c31af7Sopenharmony_ci
685e5c31af7Sopenharmony_ci	std::vector<deUint32>	shaderCount	= getShaderCounts();
686e5c31af7Sopenharmony_ci
687e5c31af7Sopenharmony_ci	{
688e5c31af7Sopenharmony_ci		std::stringstream css;
689e5c31af7Sopenharmony_ci		css <<
690e5c31af7Sopenharmony_ci			"#version 460 core\n"
691e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
692e5c31af7Sopenharmony_ci			"layout(location = 0) rayPayloadEXT uvec4 hitValue;\n"
693e5c31af7Sopenharmony_ci			"layout(r32ui, set = 0, binding = 0) uniform uimage2D result;\n"
694e5c31af7Sopenharmony_ci			"layout(set = 0, binding = 1) uniform TraceRaysParamsUBO\n"
695e5c31af7Sopenharmony_ci			"{\n"
696e5c31af7Sopenharmony_ci			"	uvec4 trParams; // x = sbtRecordOffset, y = sbtRecordStride, z = missIndex\n"
697e5c31af7Sopenharmony_ci			"};\n"
698e5c31af7Sopenharmony_ci			"layout(set = 0, binding = 2) uniform accelerationStructureEXT topLevelAS;\n"
699e5c31af7Sopenharmony_ci			"\n"
700e5c31af7Sopenharmony_ci			"void main()\n"
701e5c31af7Sopenharmony_ci			"{\n"
702e5c31af7Sopenharmony_ci			"  float tmin     = 0.0;\n"
703e5c31af7Sopenharmony_ci			"  float tmax     = 1.0;\n"
704e5c31af7Sopenharmony_ci			"  vec3  origin   = vec3(float(gl_LaunchIDEXT.x) + 0.5f, float(gl_LaunchIDEXT.y) + 0.5f, 0.5f);\n"
705e5c31af7Sopenharmony_ci			"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
706e5c31af7Sopenharmony_ci			"  hitValue       = uvec4(0,0,0,0);\n"
707e5c31af7Sopenharmony_ci			"  traceRayEXT(topLevelAS, 0, 0xFF, trParams.x, trParams.y, trParams.z, origin, tmin, direct, tmax, 0);\n"
708e5c31af7Sopenharmony_ci			"  imageStore(result, ivec2(gl_LaunchIDEXT.xy), hitValue);\n"
709e5c31af7Sopenharmony_ci			"}\n";
710e5c31af7Sopenharmony_ci		programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
711e5c31af7Sopenharmony_ci	}
712e5c31af7Sopenharmony_ci
713e5c31af7Sopenharmony_ci	for(deUint32 idx = 0; idx < shaderCount[STT_HIT]; ++idx)
714e5c31af7Sopenharmony_ci	{
715e5c31af7Sopenharmony_ci		std::stringstream css;
716e5c31af7Sopenharmony_ci		css <<
717e5c31af7Sopenharmony_ci			"#version 460 core\n"
718e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
719e5c31af7Sopenharmony_ci			"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
720e5c31af7Sopenharmony_ci			"void main()\n"
721e5c31af7Sopenharmony_ci			"{\n"
722e5c31af7Sopenharmony_ci			"  hitValue = uvec4("<< idx << ",0,0,1);\n"
723e5c31af7Sopenharmony_ci			"}\n";
724e5c31af7Sopenharmony_ci		std::stringstream csname;
725e5c31af7Sopenharmony_ci		csname << "chit_" << idx;
726e5c31af7Sopenharmony_ci
727e5c31af7Sopenharmony_ci		programCollection.glslSources.add(csname.str()) << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
728e5c31af7Sopenharmony_ci	}
729e5c31af7Sopenharmony_ci
730e5c31af7Sopenharmony_ci	{
731e5c31af7Sopenharmony_ci		std::stringstream css;
732e5c31af7Sopenharmony_ci		css <<
733e5c31af7Sopenharmony_ci			"#version 460 core\n"
734e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
735e5c31af7Sopenharmony_ci			"layout(shaderRecordEXT) buffer block\n"
736e5c31af7Sopenharmony_ci			"{\n"
737e5c31af7Sopenharmony_ci			"  uvec4 info;\n"
738e5c31af7Sopenharmony_ci			"};\n"
739e5c31af7Sopenharmony_ci			"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
740e5c31af7Sopenharmony_ci			"void main()\n"
741e5c31af7Sopenharmony_ci			"{\n"
742e5c31af7Sopenharmony_ci			"  hitValue = info;\n"
743e5c31af7Sopenharmony_ci			"}\n";
744e5c31af7Sopenharmony_ci		programCollection.glslSources.add("chit_shaderRecord") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
745e5c31af7Sopenharmony_ci	}
746e5c31af7Sopenharmony_ci
747e5c31af7Sopenharmony_ci	for (deUint32 idx = 0; idx < shaderCount[STT_CALL]; ++idx)
748e5c31af7Sopenharmony_ci	{
749e5c31af7Sopenharmony_ci		std::stringstream css;
750e5c31af7Sopenharmony_ci		css <<
751e5c31af7Sopenharmony_ci			"#version 460 core\n"
752e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
753e5c31af7Sopenharmony_ci			"layout(location = 0) callableDataEXT uvec4 value;\n"
754e5c31af7Sopenharmony_ci			"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
755e5c31af7Sopenharmony_ci			"void main()\n"
756e5c31af7Sopenharmony_ci			"{\n"
757e5c31af7Sopenharmony_ci			"  executeCallableEXT(" << idx << ", 0);\n"
758e5c31af7Sopenharmony_ci			"  hitValue = value;\n"
759e5c31af7Sopenharmony_ci			"}\n";
760e5c31af7Sopenharmony_ci		std::stringstream csname;
761e5c31af7Sopenharmony_ci		csname << "chit_call_" << idx;
762e5c31af7Sopenharmony_ci
763e5c31af7Sopenharmony_ci		programCollection.glslSources.add(csname.str()) << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
764e5c31af7Sopenharmony_ci	}
765e5c31af7Sopenharmony_ci
766e5c31af7Sopenharmony_ci	for (deUint32 idx = 0; idx < shaderCount[STT_MISS]; ++idx)
767e5c31af7Sopenharmony_ci	{
768e5c31af7Sopenharmony_ci		std::stringstream css;
769e5c31af7Sopenharmony_ci		css <<
770e5c31af7Sopenharmony_ci			"#version 460 core\n"
771e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
772e5c31af7Sopenharmony_ci			"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
773e5c31af7Sopenharmony_ci			"void main()\n"
774e5c31af7Sopenharmony_ci			"{\n"
775e5c31af7Sopenharmony_ci			"  hitValue = uvec4(" << idx <<",0,0,1);\n"
776e5c31af7Sopenharmony_ci			"}\n";
777e5c31af7Sopenharmony_ci		std::stringstream csname;
778e5c31af7Sopenharmony_ci		csname << "miss_" << idx;
779e5c31af7Sopenharmony_ci
780e5c31af7Sopenharmony_ci		programCollection.glslSources.add(csname.str()) << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
781e5c31af7Sopenharmony_ci	}
782e5c31af7Sopenharmony_ci
783e5c31af7Sopenharmony_ci	{
784e5c31af7Sopenharmony_ci		std::stringstream css;
785e5c31af7Sopenharmony_ci		css <<
786e5c31af7Sopenharmony_ci			"#version 460 core\n"
787e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
788e5c31af7Sopenharmony_ci			"layout(shaderRecordEXT) buffer block\n"
789e5c31af7Sopenharmony_ci			"{\n"
790e5c31af7Sopenharmony_ci			"  uvec4 info;\n"
791e5c31af7Sopenharmony_ci			"};\n"
792e5c31af7Sopenharmony_ci			"layout(location = 0) rayPayloadInEXT uvec4 hitValue;\n"
793e5c31af7Sopenharmony_ci			"void main()\n"
794e5c31af7Sopenharmony_ci			"{\n"
795e5c31af7Sopenharmony_ci			"  hitValue = info;\n"
796e5c31af7Sopenharmony_ci			"}\n";
797e5c31af7Sopenharmony_ci
798e5c31af7Sopenharmony_ci		programCollection.glslSources.add("miss_shaderRecord") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
799e5c31af7Sopenharmony_ci	}
800e5c31af7Sopenharmony_ci
801e5c31af7Sopenharmony_ci	for (deUint32 idx = 0; idx < shaderCount[STT_CALL]; ++idx)
802e5c31af7Sopenharmony_ci	{
803e5c31af7Sopenharmony_ci		std::stringstream css;
804e5c31af7Sopenharmony_ci		css <<
805e5c31af7Sopenharmony_ci			"#version 460 core\n"
806e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
807e5c31af7Sopenharmony_ci			"layout(location = 0) callableDataInEXT uvec4 result;\n"
808e5c31af7Sopenharmony_ci			"void main()\n"
809e5c31af7Sopenharmony_ci			"{\n"
810e5c31af7Sopenharmony_ci			"  result = uvec4(" << idx << ",0,0,1);\n"
811e5c31af7Sopenharmony_ci			"}\n";
812e5c31af7Sopenharmony_ci		std::stringstream csname;
813e5c31af7Sopenharmony_ci		csname << "call_" << idx;
814e5c31af7Sopenharmony_ci
815e5c31af7Sopenharmony_ci		programCollection.glslSources.add(csname.str()) << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
816e5c31af7Sopenharmony_ci	}
817e5c31af7Sopenharmony_ci
818e5c31af7Sopenharmony_ci	{
819e5c31af7Sopenharmony_ci		std::stringstream css;
820e5c31af7Sopenharmony_ci		css <<
821e5c31af7Sopenharmony_ci			"#version 460 core\n"
822e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
823e5c31af7Sopenharmony_ci			"layout(shaderRecordEXT) buffer block\n"
824e5c31af7Sopenharmony_ci			"{\n"
825e5c31af7Sopenharmony_ci			"  uvec4 info;\n"
826e5c31af7Sopenharmony_ci			"};\n"
827e5c31af7Sopenharmony_ci			"layout(location = 0) callableDataInEXT uvec4 result;\n"
828e5c31af7Sopenharmony_ci			"void main()\n"
829e5c31af7Sopenharmony_ci			"{\n"
830e5c31af7Sopenharmony_ci			"  result = info;\n"
831e5c31af7Sopenharmony_ci			"}\n";
832e5c31af7Sopenharmony_ci
833e5c31af7Sopenharmony_ci		programCollection.glslSources.add("call_shaderRecord") << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
834e5c31af7Sopenharmony_ci	}
835e5c31af7Sopenharmony_ci}
836e5c31af7Sopenharmony_ci
837e5c31af7Sopenharmony_ciTestInstance* ShaderBindingTableIndexingTestCase::createInstance (Context& context) const
838e5c31af7Sopenharmony_ci{
839e5c31af7Sopenharmony_ci	return new ShaderBindingTableIndexingTestInstance(context, m_data);
840e5c31af7Sopenharmony_ci}
841e5c31af7Sopenharmony_ci
842e5c31af7Sopenharmony_ciShaderBindingTableIndexingTestInstance::ShaderBindingTableIndexingTestInstance (Context& context, const TestParams& data)
843e5c31af7Sopenharmony_ci	: vkt::TestInstance		(context)
844e5c31af7Sopenharmony_ci	, m_data				(data)
845e5c31af7Sopenharmony_ci{
846e5c31af7Sopenharmony_ci}
847e5c31af7Sopenharmony_ci
848e5c31af7Sopenharmony_ciShaderBindingTableIndexingTestInstance::~ShaderBindingTableIndexingTestInstance (void)
849e5c31af7Sopenharmony_ci{
850e5c31af7Sopenharmony_ci}
851e5c31af7Sopenharmony_ci
852e5c31af7Sopenharmony_cide::MovePtr<BufferWithMemory> ShaderBindingTableIndexingTestInstance::runTest ()
853e5c31af7Sopenharmony_ci{
854e5c31af7Sopenharmony_ci	const InstanceInterface&			vki									= m_context.getInstanceInterface();
855e5c31af7Sopenharmony_ci	const DeviceInterface&				vkd									= m_context.getDeviceInterface();
856e5c31af7Sopenharmony_ci	const VkDevice						device								= m_context.getDevice();
857e5c31af7Sopenharmony_ci	const VkPhysicalDevice				physicalDevice						= m_context.getPhysicalDevice();
858e5c31af7Sopenharmony_ci	const deUint32						queueFamilyIndex					= m_context.getUniversalQueueFamilyIndex();
859e5c31af7Sopenharmony_ci	const VkQueue						queue								= m_context.getUniversalQueue();
860e5c31af7Sopenharmony_ci	Allocator&							allocator							= m_context.getDefaultAllocator();
861e5c31af7Sopenharmony_ci	const deUint32						pixelCount							= m_data.width * m_data.height * 1;
862e5c31af7Sopenharmony_ci
863e5c31af7Sopenharmony_ci	const Move<VkDescriptorSetLayout>	descriptorSetLayout					= DescriptorSetLayoutBuilder()
864e5c31af7Sopenharmony_ci																					.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
865e5c31af7Sopenharmony_ci																					.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, ALL_RAY_TRACING_STAGES)
866e5c31af7Sopenharmony_ci																					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
867e5c31af7Sopenharmony_ci																					.build(vkd, device);
868e5c31af7Sopenharmony_ci	const Move<VkDescriptorPool>		descriptorPool						= DescriptorPoolBuilder()
869e5c31af7Sopenharmony_ci																					.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
870e5c31af7Sopenharmony_ci																					.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
871e5c31af7Sopenharmony_ci																					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
872e5c31af7Sopenharmony_ci																					.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
873e5c31af7Sopenharmony_ci	const Move<VkDescriptorSet>			descriptorSet						= makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
874e5c31af7Sopenharmony_ci	const Move<VkPipelineLayout>		pipelineLayout						= makePipelineLayout(vkd, device, descriptorSetLayout.get());
875e5c31af7Sopenharmony_ci
876e5c31af7Sopenharmony_ci	de::MovePtr<RayTracingPipeline>		rayTracingPipeline					= de::newMovePtr<RayTracingPipeline>();
877e5c31af7Sopenharmony_ci	m_data.testConfiguration->initRayTracingShaders(rayTracingPipeline, m_context, m_data);
878e5c31af7Sopenharmony_ci	Move<VkPipeline>					pipeline							= rayTracingPipeline->createPipeline(vkd, device, *pipelineLayout);
879e5c31af7Sopenharmony_ci
880e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>		raygenShaderBindingTable;
881e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>		hitShaderBindingTable;
882e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>		missShaderBindingTable;
883e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>		callableShaderBindingTable;
884e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR		raygenShaderBindingTableRegion;
885e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR		hitShaderBindingTableRegion;
886e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR		missShaderBindingTableRegion;
887e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR		callableShaderBindingTableRegion;
888e5c31af7Sopenharmony_ci	m_data.testConfiguration->initShaderBindingTables(rayTracingPipeline, m_context, m_data, *pipeline, getShaderGroupHandleSize(vki, physicalDevice), getShaderGroupBaseAlignment(vki, physicalDevice), raygenShaderBindingTable, hitShaderBindingTable, missShaderBindingTable, callableShaderBindingTable, raygenShaderBindingTableRegion, hitShaderBindingTableRegion, missShaderBindingTableRegion, callableShaderBindingTableRegion);
889e5c31af7Sopenharmony_ci
890e5c31af7Sopenharmony_ci	const VkFormat						imageFormat							= m_data.testConfiguration->getResultImageFormat();
891e5c31af7Sopenharmony_ci	const VkImageCreateInfo				imageCreateInfo						= makeImageCreateInfo(m_data.width, m_data.height, imageFormat);
892e5c31af7Sopenharmony_ci	const VkImageSubresourceRange		imageSubresourceRange				= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
893e5c31af7Sopenharmony_ci	const de::MovePtr<ImageWithMemory>	image								= de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
894e5c31af7Sopenharmony_ci	const Move<VkImageView>				imageView							= makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_2D, imageFormat, imageSubresourceRange);
895e5c31af7Sopenharmony_ci
896e5c31af7Sopenharmony_ci	const VkBufferCreateInfo			resultBufferCreateInfo				= makeBufferCreateInfo(pixelCount*m_data.testConfiguration->getResultImageFormatSize(), VK_BUFFER_USAGE_TRANSFER_DST_BIT);
897e5c31af7Sopenharmony_ci	const VkImageSubresourceLayers		resultBufferImageSubresourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
898e5c31af7Sopenharmony_ci	const VkBufferImageCopy				resultBufferImageRegion				= makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, 1), resultBufferImageSubresourceLayers);
899e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>		resultBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
900e5c31af7Sopenharmony_ci
901e5c31af7Sopenharmony_ci	const VkDescriptorImageInfo			descriptorImageInfo					= makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
902e5c31af7Sopenharmony_ci
903e5c31af7Sopenharmony_ci	const Move<VkCommandPool>			cmdPool								= createCommandPool(vkd, device, 0, queueFamilyIndex);
904e5c31af7Sopenharmony_ci	const Move<VkCommandBuffer>			cmdBuffer							= allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
905e5c31af7Sopenharmony_ci
906e5c31af7Sopenharmony_ci	std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >	bottomLevelAccelerationStructures;
907e5c31af7Sopenharmony_ci	de::MovePtr<TopLevelAccelerationStructure>						topLevelAccelerationStructure;
908e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>									uniformBuffer;
909e5c31af7Sopenharmony_ci
910e5c31af7Sopenharmony_ci	beginCommandBuffer(vkd, *cmdBuffer, 0u);
911e5c31af7Sopenharmony_ci	{
912e5c31af7Sopenharmony_ci		const VkImageMemoryBarrier			preImageBarrier						= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
913e5c31af7Sopenharmony_ci																					VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
914e5c31af7Sopenharmony_ci																					**image, imageSubresourceRange);
915e5c31af7Sopenharmony_ci		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
916e5c31af7Sopenharmony_ci
917e5c31af7Sopenharmony_ci		const VkClearValue					clearValue							= m_data.testConfiguration->getClearValue();
918e5c31af7Sopenharmony_ci		vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
919e5c31af7Sopenharmony_ci
920e5c31af7Sopenharmony_ci		const VkImageMemoryBarrier			postImageBarrier					= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
921e5c31af7Sopenharmony_ci																					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
922e5c31af7Sopenharmony_ci																					**image, imageSubresourceRange);
923e5c31af7Sopenharmony_ci		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
924e5c31af7Sopenharmony_ci
925e5c31af7Sopenharmony_ci		bottomLevelAccelerationStructures										= m_data.testConfiguration->initBottomAccelerationStructures(m_context, m_data);
926e5c31af7Sopenharmony_ci		for (auto& blas : bottomLevelAccelerationStructures)
927e5c31af7Sopenharmony_ci			blas->createAndBuild(vkd, device, *cmdBuffer, allocator);
928e5c31af7Sopenharmony_ci		topLevelAccelerationStructure											= m_data.testConfiguration->initTopAccelerationStructure(m_context, m_data, bottomLevelAccelerationStructures);
929e5c31af7Sopenharmony_ci		topLevelAccelerationStructure->createAndBuild(vkd, device, *cmdBuffer, allocator);
930e5c31af7Sopenharmony_ci
931e5c31af7Sopenharmony_ci		uniformBuffer															= m_data.testConfiguration->initUniformBuffer(m_context, m_data);
932e5c31af7Sopenharmony_ci		VkDescriptorBufferInfo							uniformBufferInfo		= makeDescriptorBufferInfo(uniformBuffer->get(), 0ull, sizeof(tcu::UVec4));
933e5c31af7Sopenharmony_ci
934e5c31af7Sopenharmony_ci		const TopLevelAccelerationStructure*			topLevelAccelerationStructurePtr		= topLevelAccelerationStructure.get();
935e5c31af7Sopenharmony_ci		VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet	=
936e5c31af7Sopenharmony_ci		{
937e5c31af7Sopenharmony_ci			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
938e5c31af7Sopenharmony_ci			DE_NULL,															//  const void*							pNext;
939e5c31af7Sopenharmony_ci			1u,																	//  deUint32							accelerationStructureCount;
940e5c31af7Sopenharmony_ci			topLevelAccelerationStructurePtr->getPtr(),							//  const VkAccelerationStructureKHR*	pAccelerationStructures;
941e5c31af7Sopenharmony_ci		};
942e5c31af7Sopenharmony_ci
943e5c31af7Sopenharmony_ci		DescriptorSetUpdateBuilder()
944e5c31af7Sopenharmony_ci			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
945e5c31af7Sopenharmony_ci			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &uniformBufferInfo)
946e5c31af7Sopenharmony_ci			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
947e5c31af7Sopenharmony_ci			.update(vkd, device);
948e5c31af7Sopenharmony_ci
949e5c31af7Sopenharmony_ci		vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
950e5c31af7Sopenharmony_ci
951e5c31af7Sopenharmony_ci		vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipeline);
952e5c31af7Sopenharmony_ci
953e5c31af7Sopenharmony_ci		cmdTraceRays(vkd,
954e5c31af7Sopenharmony_ci			*cmdBuffer,
955e5c31af7Sopenharmony_ci			&raygenShaderBindingTableRegion,
956e5c31af7Sopenharmony_ci			&missShaderBindingTableRegion,
957e5c31af7Sopenharmony_ci			&hitShaderBindingTableRegion,
958e5c31af7Sopenharmony_ci			&callableShaderBindingTableRegion,
959e5c31af7Sopenharmony_ci			m_data.width, m_data.height, 1);
960e5c31af7Sopenharmony_ci
961e5c31af7Sopenharmony_ci		const VkMemoryBarrier							postTraceMemoryBarrier					= makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
962e5c31af7Sopenharmony_ci		const VkMemoryBarrier							postCopyMemoryBarrier					= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
963e5c31af7Sopenharmony_ci		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier);
964e5c31af7Sopenharmony_ci
965e5c31af7Sopenharmony_ci		vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
966e5c31af7Sopenharmony_ci
967e5c31af7Sopenharmony_ci		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
968e5c31af7Sopenharmony_ci	}
969e5c31af7Sopenharmony_ci	endCommandBuffer(vkd, *cmdBuffer);
970e5c31af7Sopenharmony_ci
971e5c31af7Sopenharmony_ci	submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
972e5c31af7Sopenharmony_ci
973e5c31af7Sopenharmony_ci	invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
974e5c31af7Sopenharmony_ci
975e5c31af7Sopenharmony_ci	return resultBuffer;
976e5c31af7Sopenharmony_ci}
977e5c31af7Sopenharmony_ci
978e5c31af7Sopenharmony_citcu::TestStatus ShaderBindingTableIndexingTestInstance::iterate (void)
979e5c31af7Sopenharmony_ci{
980e5c31af7Sopenharmony_ci	// run test using arrays of pointers
981e5c31af7Sopenharmony_ci	const de::MovePtr<BufferWithMemory>	buffer		= runTest();
982e5c31af7Sopenharmony_ci
983e5c31af7Sopenharmony_ci	if (!m_data.testConfiguration->verifyImage(buffer.get(), m_context, m_data))
984e5c31af7Sopenharmony_ci		return tcu::TestStatus::fail("Fail");
985e5c31af7Sopenharmony_ci	return tcu::TestStatus::pass("Pass");
986e5c31af7Sopenharmony_ci}
987e5c31af7Sopenharmony_ci
988e5c31af7Sopenharmony_ci/*
989e5c31af7Sopenharmony_ci
990e5c31af7Sopenharmony_ciTest the advertised shader group handle alignment requirements work as expected. The tests will prepare shader binding tables using
991e5c31af7Sopenharmony_cishader record buffers for padding and achieving the desired alignments.
992e5c31af7Sopenharmony_ci
993e5c31af7Sopenharmony_ci+-------------------------------------------
994e5c31af7Sopenharmony_ci| Shader | Shader    | Aligned |
995e5c31af7Sopenharmony_ci| Group  | Record    | Shader  | ...
996e5c31af7Sopenharmony_ci| Handle | Buffer    | Group   |
997e5c31af7Sopenharmony_ci|        | (padding) | Handle  |
998e5c31af7Sopenharmony_ci+-------------------------------------------
999e5c31af7Sopenharmony_ci
1000e5c31af7Sopenharmony_ciThe number of geometries to try (hence the number of alignments and shader record buffers to try) is 32/align + 1, so 33 in the case
1001e5c31af7Sopenharmony_ciof align=1, and 2 in the case of align=32. This allows us to test all possible alignment values.
1002e5c31af7Sopenharmony_ci
1003e5c31af7Sopenharmony_ciGeometries are triangles put alongside the X axis. The base triangle is:
1004e5c31af7Sopenharmony_ci
1005e5c31af7Sopenharmony_ci0,1|      x
1006e5c31af7Sopenharmony_ci   |     x x
1007e5c31af7Sopenharmony_ci   |    x  0.5,0.5
1008e5c31af7Sopenharmony_ci   |   x  x  x
1009e5c31af7Sopenharmony_ci   |  x       x
1010e5c31af7Sopenharmony_ci   | xxxxxxxxxxx
1011e5c31af7Sopenharmony_ci   +-------------
1012e5c31af7Sopenharmony_ci 0,0             1,0
1013e5c31af7Sopenharmony_ci
1014e5c31af7Sopenharmony_ciA triangle surrounding point (0.5, 0.5), in the [0, 1] range of both the X and Y axis.
1015e5c31af7Sopenharmony_ci
1016e5c31af7Sopenharmony_ciAs more than one triangle is needed, each triangle is translated one more unit in the X axis, so each triangle is in the [i, i+1]
1017e5c31af7Sopenharmony_cirange. The Y axis doesn't change, triangles are always in the [0,1] range.
1018e5c31af7Sopenharmony_ci
1019e5c31af7Sopenharmony_ciTriangles have Z=5, and one ray is traced per triangle, origin (i+0.5, 0.5, 0) direction (0, 0, 1), where i is gl_LaunchIDEXT.x.
1020e5c31af7Sopenharmony_ci
1021e5c31af7Sopenharmony_ciFor each geometry, the shader record buffer contents vary depending on the geometry index and the desired alignment (padding).
1022e5c31af7Sopenharmony_ci
1023e5c31af7Sopenharmony_ciAlignment	Element Type	Element Count			Data
1024e5c31af7Sopenharmony_ci1			uint8_t			1						0x80 | geometryID
1025e5c31af7Sopenharmony_ci2			uint16_t		1						0xABC0 | geometryID
1026e5c31af7Sopenharmony_ci4+			uint32_t		alignment/4				For each element: 0xABCDE0F0 | (element << 8) | geometryID
1027e5c31af7Sopenharmony_ci
1028e5c31af7Sopenharmony_ciThe test will try to verify everything works properly and all shader record buffers can be read with the right values.
1029e5c31af7Sopenharmony_ci
1030e5c31af7Sopenharmony_ci */
1031e5c31af7Sopenharmony_cistruct ShaderGroupHandleAlignmentParams
1032e5c31af7Sopenharmony_ci{
1033e5c31af7Sopenharmony_ci	const uint32_t alignment;
1034e5c31af7Sopenharmony_ci
1035e5c31af7Sopenharmony_ci	ShaderGroupHandleAlignmentParams (uint32_t alignment_)
1036e5c31af7Sopenharmony_ci		: alignment (alignment_)
1037e5c31af7Sopenharmony_ci	{
1038e5c31af7Sopenharmony_ci		DE_ASSERT(alignment >= 1u && alignment <= 32u);
1039e5c31af7Sopenharmony_ci		DE_ASSERT(deIsPowerOfTwo32(static_cast<int>(alignment)));
1040e5c31af7Sopenharmony_ci	}
1041e5c31af7Sopenharmony_ci
1042e5c31af7Sopenharmony_ci	uint32_t geometryCount () const
1043e5c31af7Sopenharmony_ci	{
1044e5c31af7Sopenharmony_ci		return (32u / alignment + 1u);
1045e5c31af7Sopenharmony_ci	}
1046e5c31af7Sopenharmony_ci
1047e5c31af7Sopenharmony_ci	uint32_t shaderRecordElementCount () const
1048e5c31af7Sopenharmony_ci	{
1049e5c31af7Sopenharmony_ci		return ((alignment <= 4u) ? 1u : (alignment / 4u));
1050e5c31af7Sopenharmony_ci	}
1051e5c31af7Sopenharmony_ci
1052e5c31af7Sopenharmony_ci	std::string glslElementType () const
1053e5c31af7Sopenharmony_ci	{
1054e5c31af7Sopenharmony_ci		if (alignment == 1u)
1055e5c31af7Sopenharmony_ci			return "uint8_t";
1056e5c31af7Sopenharmony_ci		if (alignment == 2u)
1057e5c31af7Sopenharmony_ci			return "uint16_t";
1058e5c31af7Sopenharmony_ci		return "uint32_t";
1059e5c31af7Sopenharmony_ci	}
1060e5c31af7Sopenharmony_ci
1061e5c31af7Sopenharmony_ci	std::string glslExtension () const
1062e5c31af7Sopenharmony_ci	{
1063e5c31af7Sopenharmony_ci		if (alignment == 1u)
1064e5c31af7Sopenharmony_ci			return "GL_EXT_shader_explicit_arithmetic_types_int8";
1065e5c31af7Sopenharmony_ci		if (alignment == 2u)
1066e5c31af7Sopenharmony_ci			return "GL_EXT_shader_explicit_arithmetic_types_int16";
1067e5c31af7Sopenharmony_ci		return "GL_EXT_shader_explicit_arithmetic_types_int32";
1068e5c31af7Sopenharmony_ci	}
1069e5c31af7Sopenharmony_ci
1070e5c31af7Sopenharmony_ci	std::vector<uint8_t> getRecordData (uint32_t geometryID) const
1071e5c31af7Sopenharmony_ci	{
1072e5c31af7Sopenharmony_ci		std::vector<uint8_t> recordData;
1073e5c31af7Sopenharmony_ci		switch (alignment)
1074e5c31af7Sopenharmony_ci		{
1075e5c31af7Sopenharmony_ci		case 1u:
1076e5c31af7Sopenharmony_ci			recordData.push_back(static_cast<uint8_t>(0x80u | geometryID));
1077e5c31af7Sopenharmony_ci			break;
1078e5c31af7Sopenharmony_ci		case 2u:
1079e5c31af7Sopenharmony_ci			recordData.push_back(uint8_t{0xABu});
1080e5c31af7Sopenharmony_ci			recordData.push_back(static_cast<uint8_t>(0xC0u | geometryID));
1081e5c31af7Sopenharmony_ci			break;
1082e5c31af7Sopenharmony_ci		default:
1083e5c31af7Sopenharmony_ci			{
1084e5c31af7Sopenharmony_ci				const auto elemCount = shaderRecordElementCount();
1085e5c31af7Sopenharmony_ci				for (uint32_t i = 0u; i < elemCount; ++i)
1086e5c31af7Sopenharmony_ci				{
1087e5c31af7Sopenharmony_ci					recordData.push_back(uint8_t{0xABu});
1088e5c31af7Sopenharmony_ci					recordData.push_back(uint8_t{0xCDu});
1089e5c31af7Sopenharmony_ci					recordData.push_back(static_cast<uint8_t>(0xE0u | i));
1090e5c31af7Sopenharmony_ci					recordData.push_back(static_cast<uint8_t>(0xF0u | geometryID));
1091e5c31af7Sopenharmony_ci				}
1092e5c31af7Sopenharmony_ci			}
1093e5c31af7Sopenharmony_ci			break;
1094e5c31af7Sopenharmony_ci		}
1095e5c31af7Sopenharmony_ci		return recordData;
1096e5c31af7Sopenharmony_ci	}
1097e5c31af7Sopenharmony_ci};
1098e5c31af7Sopenharmony_ci
1099e5c31af7Sopenharmony_ciclass ShaderGroupHandleAlignmentCase : public TestCase
1100e5c31af7Sopenharmony_ci{
1101e5c31af7Sopenharmony_cipublic:
1102e5c31af7Sopenharmony_ci					ShaderGroupHandleAlignmentCase		(tcu::TestContext& testCtx, const std::string& name, const ShaderGroupHandleAlignmentParams& params)
1103e5c31af7Sopenharmony_ci						: TestCase	(testCtx, name)
1104e5c31af7Sopenharmony_ci						, m_params	(params)
1105e5c31af7Sopenharmony_ci						{
1106e5c31af7Sopenharmony_ci						}
1107e5c31af7Sopenharmony_ci	virtual			~ShaderGroupHandleAlignmentCase		(void) {}
1108e5c31af7Sopenharmony_ci
1109e5c31af7Sopenharmony_ci	void			checkSupport						(Context& context) const override;
1110e5c31af7Sopenharmony_ci	void			initPrograms						(vk::SourceCollections& programCollection) const override;
1111e5c31af7Sopenharmony_ci	TestInstance*	createInstance						(Context& context) const override;
1112e5c31af7Sopenharmony_ci
1113e5c31af7Sopenharmony_ciprotected:
1114e5c31af7Sopenharmony_ci	ShaderGroupHandleAlignmentParams					m_params;
1115e5c31af7Sopenharmony_ci};
1116e5c31af7Sopenharmony_ci
1117e5c31af7Sopenharmony_ciclass ShaderGroupHandleAlignmentInstance : public TestInstance
1118e5c31af7Sopenharmony_ci{
1119e5c31af7Sopenharmony_cipublic:
1120e5c31af7Sopenharmony_ci						ShaderGroupHandleAlignmentInstance	(Context& context, const ShaderGroupHandleAlignmentParams& params)
1121e5c31af7Sopenharmony_ci							: TestInstance	(context)
1122e5c31af7Sopenharmony_ci							, m_params		(params)
1123e5c31af7Sopenharmony_ci							{}
1124e5c31af7Sopenharmony_ci	virtual				~ShaderGroupHandleAlignmentInstance	(void) {}
1125e5c31af7Sopenharmony_ci
1126e5c31af7Sopenharmony_ci	tcu::TestStatus		iterate								(void) override;
1127e5c31af7Sopenharmony_ci
1128e5c31af7Sopenharmony_ciprotected:
1129e5c31af7Sopenharmony_ci	ShaderGroupHandleAlignmentParams							m_params;
1130e5c31af7Sopenharmony_ci};
1131e5c31af7Sopenharmony_ci
1132e5c31af7Sopenharmony_civoid ShaderGroupHandleAlignmentCase::checkSupport (Context& context) const
1133e5c31af7Sopenharmony_ci{
1134e5c31af7Sopenharmony_ci	context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
1135e5c31af7Sopenharmony_ci	context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
1136e5c31af7Sopenharmony_ci
1137e5c31af7Sopenharmony_ci	const auto&	vki				= context.getInstanceInterface();
1138e5c31af7Sopenharmony_ci	const auto	physicalDevice	= context.getPhysicalDevice();
1139e5c31af7Sopenharmony_ci	const auto	rtProperties	= makeRayTracingProperties(vki, physicalDevice);
1140e5c31af7Sopenharmony_ci
1141e5c31af7Sopenharmony_ci	if (m_params.alignment < rtProperties->getShaderGroupHandleAlignment())
1142e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Required shader group handle alignment not supported");
1143e5c31af7Sopenharmony_ci
1144e5c31af7Sopenharmony_ci	switch (m_params.alignment)
1145e5c31af7Sopenharmony_ci	{
1146e5c31af7Sopenharmony_ci	case 1u:
1147e5c31af7Sopenharmony_ci		{
1148e5c31af7Sopenharmony_ci			const auto& int8Features = context.getShaderFloat16Int8Features();
1149e5c31af7Sopenharmony_ci			if (!int8Features.shaderInt8)
1150e5c31af7Sopenharmony_ci				TCU_THROW(NotSupportedError, "shaderInt8 not supported");
1151e5c31af7Sopenharmony_ci
1152e5c31af7Sopenharmony_ci			const auto& int8StorageFeatures = context.get8BitStorageFeatures();
1153e5c31af7Sopenharmony_ci			if (!int8StorageFeatures.storageBuffer8BitAccess)
1154e5c31af7Sopenharmony_ci				TCU_THROW(NotSupportedError, "storageBuffer8BitAccess not supported");
1155e5c31af7Sopenharmony_ci		}
1156e5c31af7Sopenharmony_ci		break;
1157e5c31af7Sopenharmony_ci
1158e5c31af7Sopenharmony_ci	case 2u:
1159e5c31af7Sopenharmony_ci		{
1160e5c31af7Sopenharmony_ci			context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_INT16);
1161e5c31af7Sopenharmony_ci
1162e5c31af7Sopenharmony_ci			const auto& int16StorageFeatures = context.get16BitStorageFeatures();
1163e5c31af7Sopenharmony_ci			if (!int16StorageFeatures.storageBuffer16BitAccess)
1164e5c31af7Sopenharmony_ci				TCU_THROW(NotSupportedError, "storageBuffer16BitAccess not supported");
1165e5c31af7Sopenharmony_ci		}
1166e5c31af7Sopenharmony_ci		break;
1167e5c31af7Sopenharmony_ci
1168e5c31af7Sopenharmony_ci	default:
1169e5c31af7Sopenharmony_ci		break;
1170e5c31af7Sopenharmony_ci	}
1171e5c31af7Sopenharmony_ci}
1172e5c31af7Sopenharmony_ci
1173e5c31af7Sopenharmony_civoid ShaderGroupHandleAlignmentCase::initPrograms (vk::SourceCollections& programCollection) const
1174e5c31af7Sopenharmony_ci{
1175e5c31af7Sopenharmony_ci	const ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
1176e5c31af7Sopenharmony_ci
1177e5c31af7Sopenharmony_ci	const auto elemType			= m_params.glslElementType();
1178e5c31af7Sopenharmony_ci	const auto geometryCount	= m_params.geometryCount();
1179e5c31af7Sopenharmony_ci	const auto elementCount		= m_params.shaderRecordElementCount();
1180e5c31af7Sopenharmony_ci	const auto extension		= m_params.glslExtension();
1181e5c31af7Sopenharmony_ci
1182e5c31af7Sopenharmony_ci	std::ostringstream descriptors;
1183e5c31af7Sopenharmony_ci	descriptors
1184e5c31af7Sopenharmony_ci		<< "layout(set=0, binding=0) uniform accelerationStructureEXT topLevelAS;\n"
1185e5c31af7Sopenharmony_ci		<< "layout(set=0, binding=1, std430) buffer SSBOBlock {\n"
1186e5c31af7Sopenharmony_ci		<< "  " << elemType << " data[" << geometryCount << "][" << elementCount << "];\n"
1187e5c31af7Sopenharmony_ci		<< "} ssbo;\n"
1188e5c31af7Sopenharmony_ci		;
1189e5c31af7Sopenharmony_ci	const auto descriptorsStr = descriptors.str();
1190e5c31af7Sopenharmony_ci
1191e5c31af7Sopenharmony_ci	std::ostringstream commonHeader;
1192e5c31af7Sopenharmony_ci	commonHeader
1193e5c31af7Sopenharmony_ci		<< "#version 460 core\n"
1194e5c31af7Sopenharmony_ci		<< "#extension GL_EXT_ray_tracing : require\n"
1195e5c31af7Sopenharmony_ci		<< "#extension " << extension << " : require\n"
1196e5c31af7Sopenharmony_ci		;
1197e5c31af7Sopenharmony_ci	const auto commontHeaderStr = commonHeader.str();
1198e5c31af7Sopenharmony_ci
1199e5c31af7Sopenharmony_ci	std::ostringstream rgen;
1200e5c31af7Sopenharmony_ci	rgen
1201e5c31af7Sopenharmony_ci		<< commontHeaderStr
1202e5c31af7Sopenharmony_ci		<< "\n"
1203e5c31af7Sopenharmony_ci		<< descriptorsStr
1204e5c31af7Sopenharmony_ci		<< "layout(location=0) rayPayloadEXT vec4 unused;\n"
1205e5c31af7Sopenharmony_ci		<< "\n"
1206e5c31af7Sopenharmony_ci		<< "void main()\n"
1207e5c31af7Sopenharmony_ci		<< "{\n"
1208e5c31af7Sopenharmony_ci		<< "  const uint  rayFlags  = 0;\n"
1209e5c31af7Sopenharmony_ci		<< "  const uint  cullMask  = 0xFF;\n"
1210e5c31af7Sopenharmony_ci		<< "  const float tMin      = 0.0;\n"
1211e5c31af7Sopenharmony_ci		<< "  const float tMax      = 10.0;\n"
1212e5c31af7Sopenharmony_ci		<< "  const vec3  origin    = vec3(float(gl_LaunchIDEXT.x) + 0.5, 0.5, 0.0);\n"
1213e5c31af7Sopenharmony_ci		<< "  const vec3  direction = vec3(0.0, 0.0, 1.0);\n"
1214e5c31af7Sopenharmony_ci		<< "  const uint  sbtOffset = 0;\n"
1215e5c31af7Sopenharmony_ci		<< "  const uint  sbtStride = 1;\n"
1216e5c31af7Sopenharmony_ci		<< "  const uint  missIndex = 0;\n"
1217e5c31af7Sopenharmony_ci		<< "  traceRayEXT(topLevelAS, rayFlags, cullMask, sbtOffset, sbtStride, missIndex, origin, tMin, direction, tMax, 0);\n"
1218e5c31af7Sopenharmony_ci		<< "}\n"
1219e5c31af7Sopenharmony_ci		;
1220e5c31af7Sopenharmony_ci
1221e5c31af7Sopenharmony_ci	std::ostringstream chit;
1222e5c31af7Sopenharmony_ci	chit
1223e5c31af7Sopenharmony_ci		<< commontHeaderStr
1224e5c31af7Sopenharmony_ci		<< "\n"
1225e5c31af7Sopenharmony_ci		<< descriptorsStr
1226e5c31af7Sopenharmony_ci		<< "layout(location=0) rayPayloadInEXT vec4 unused;\n"
1227e5c31af7Sopenharmony_ci		<< "layout(shaderRecordEXT, std430) buffer srbBlock {\n"
1228e5c31af7Sopenharmony_ci		<< "  " << elemType << " data[" << elementCount << "];\n"
1229e5c31af7Sopenharmony_ci		<< "} srb;\n"
1230e5c31af7Sopenharmony_ci		<< "\n"
1231e5c31af7Sopenharmony_ci		<< "void main()\n"
1232e5c31af7Sopenharmony_ci		<< "{\n"
1233e5c31af7Sopenharmony_ci		<< "  for (uint i = 0; i < " << elementCount << "; ++i) {\n"
1234e5c31af7Sopenharmony_ci		<< "    ssbo.data[gl_LaunchIDEXT.x][i] = srb.data[i];\n"
1235e5c31af7Sopenharmony_ci		<< "  }\n"
1236e5c31af7Sopenharmony_ci		<< "}\n"
1237e5c31af7Sopenharmony_ci		;
1238e5c31af7Sopenharmony_ci
1239e5c31af7Sopenharmony_ci	std::ostringstream miss;
1240e5c31af7Sopenharmony_ci	miss
1241e5c31af7Sopenharmony_ci		<< commontHeaderStr
1242e5c31af7Sopenharmony_ci		<< "\n"
1243e5c31af7Sopenharmony_ci		<< descriptorsStr
1244e5c31af7Sopenharmony_ci		<< "layout(location=0) rayPayloadInEXT vec4 unused;\n"
1245e5c31af7Sopenharmony_ci		<< "\n"
1246e5c31af7Sopenharmony_ci		<< "void main()\n"
1247e5c31af7Sopenharmony_ci		<< "{\n"
1248e5c31af7Sopenharmony_ci		<< "}\n"
1249e5c31af7Sopenharmony_ci		;
1250e5c31af7Sopenharmony_ci
1251e5c31af7Sopenharmony_ci	programCollection.glslSources.add("rgen") << glu::RaygenSource(rgen.str()) << buildOptions;
1252e5c31af7Sopenharmony_ci	programCollection.glslSources.add("chit") << glu::ClosestHitSource(chit.str()) << buildOptions;
1253e5c31af7Sopenharmony_ci	programCollection.glslSources.add("miss") << glu::MissSource(miss.str()) << buildOptions;
1254e5c31af7Sopenharmony_ci}
1255e5c31af7Sopenharmony_ci
1256e5c31af7Sopenharmony_ciTestInstance* ShaderGroupHandleAlignmentCase::createInstance (Context& context) const
1257e5c31af7Sopenharmony_ci{
1258e5c31af7Sopenharmony_ci	return new ShaderGroupHandleAlignmentInstance(context, m_params);
1259e5c31af7Sopenharmony_ci}
1260e5c31af7Sopenharmony_ci
1261e5c31af7Sopenharmony_citcu::TestStatus ShaderGroupHandleAlignmentInstance::iterate (void)
1262e5c31af7Sopenharmony_ci{
1263e5c31af7Sopenharmony_ci	const auto&	vki			= m_context.getInstanceInterface();
1264e5c31af7Sopenharmony_ci	const auto	physDev		= m_context.getPhysicalDevice();
1265e5c31af7Sopenharmony_ci	const auto&	vkd			= m_context.getDeviceInterface();
1266e5c31af7Sopenharmony_ci	const auto	device		= m_context.getDevice();
1267e5c31af7Sopenharmony_ci	auto&		alloc		= m_context.getDefaultAllocator();
1268e5c31af7Sopenharmony_ci	const auto	qIndex		= m_context.getUniversalQueueFamilyIndex();
1269e5c31af7Sopenharmony_ci	const auto	queue		= m_context.getUniversalQueue();
1270e5c31af7Sopenharmony_ci	const auto	stages		= (VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR);
1271e5c31af7Sopenharmony_ci	const auto	geoCount	= m_params.geometryCount();
1272e5c31af7Sopenharmony_ci	const auto	triangleZ	= 5.0f;
1273e5c31af7Sopenharmony_ci
1274e5c31af7Sopenharmony_ci	// Command pool and buffer.
1275e5c31af7Sopenharmony_ci	const auto cmdPool		= makeCommandPool(vkd, device, qIndex);
1276e5c31af7Sopenharmony_ci	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1277e5c31af7Sopenharmony_ci	const auto cmdBuffer	= cmdBufferPtr.get();
1278e5c31af7Sopenharmony_ci
1279e5c31af7Sopenharmony_ci	beginCommandBuffer(vkd, cmdBuffer);
1280e5c31af7Sopenharmony_ci
1281e5c31af7Sopenharmony_ci	// Build acceleration structures.
1282e5c31af7Sopenharmony_ci	auto topLevelAS		= makeTopLevelAccelerationStructure();
1283e5c31af7Sopenharmony_ci	auto bottomLevelAS	= makeBottomLevelAccelerationStructure();
1284e5c31af7Sopenharmony_ci
1285e5c31af7Sopenharmony_ci	// Create the needed amount of geometries (triangles) with the right coordinates.
1286e5c31af7Sopenharmony_ci	const tcu::Vec3	baseLocation	(0.5f, 0.5f, triangleZ);
1287e5c31af7Sopenharmony_ci	const float		vertexOffset	= 0.25f; // From base location, to build a triangle around it.
1288e5c31af7Sopenharmony_ci
1289e5c31af7Sopenharmony_ci	for (uint32_t i = 0; i < geoCount; ++i)
1290e5c31af7Sopenharmony_ci	{
1291e5c31af7Sopenharmony_ci		// Triangle "center" or base location.
1292e5c31af7Sopenharmony_ci		const tcu::Vec3					triangleLocation (baseLocation.x() + static_cast<float>(i), baseLocation.y(), baseLocation.z());
1293e5c31af7Sopenharmony_ci
1294e5c31af7Sopenharmony_ci		// Actual triangle.
1295e5c31af7Sopenharmony_ci		const std::vector<tcu::Vec3>	triangle
1296e5c31af7Sopenharmony_ci		{
1297e5c31af7Sopenharmony_ci			tcu::Vec3(triangleLocation.x() - vertexOffset, triangleLocation.y() - vertexOffset, triangleLocation.z()),
1298e5c31af7Sopenharmony_ci			tcu::Vec3(triangleLocation.x() + vertexOffset, triangleLocation.y() - vertexOffset, triangleLocation.z()),
1299e5c31af7Sopenharmony_ci			tcu::Vec3(triangleLocation.x(),                triangleLocation.y() + vertexOffset, triangleLocation.z()),
1300e5c31af7Sopenharmony_ci		};
1301e5c31af7Sopenharmony_ci
1302e5c31af7Sopenharmony_ci		bottomLevelAS->addGeometry(triangle, true/*triangles*/);
1303e5c31af7Sopenharmony_ci	}
1304e5c31af7Sopenharmony_ci
1305e5c31af7Sopenharmony_ci	bottomLevelAS->createAndBuild(vkd, device, cmdBuffer, alloc);
1306e5c31af7Sopenharmony_ci
1307e5c31af7Sopenharmony_ci	de::SharedPtr<BottomLevelAccelerationStructure> blasSharedPtr (bottomLevelAS.release());
1308e5c31af7Sopenharmony_ci	topLevelAS->setInstanceCount(1);
1309e5c31af7Sopenharmony_ci	topLevelAS->addInstance(blasSharedPtr, identityMatrix3x4, 0u, 0xFF, 0u, VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR);
1310e5c31af7Sopenharmony_ci	topLevelAS->createAndBuild(vkd, device, cmdBuffer, alloc);
1311e5c31af7Sopenharmony_ci
1312e5c31af7Sopenharmony_ci	// Get some ray tracing properties.
1313e5c31af7Sopenharmony_ci	uint32_t shaderGroupHandleSize		= 0u;
1314e5c31af7Sopenharmony_ci	uint32_t shaderGroupBaseAlignment	= 1u;
1315e5c31af7Sopenharmony_ci	{
1316e5c31af7Sopenharmony_ci		const auto rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physDev);
1317e5c31af7Sopenharmony_ci		shaderGroupHandleSize				= rayTracingPropertiesKHR->getShaderGroupHandleSize();
1318e5c31af7Sopenharmony_ci		shaderGroupBaseAlignment			= rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
1319e5c31af7Sopenharmony_ci	}
1320e5c31af7Sopenharmony_ci
1321e5c31af7Sopenharmony_ci	// SSBO to copy results over from the shaders.
1322e5c31af7Sopenharmony_ci	const auto			shaderRecordSize	= m_params.alignment;
1323e5c31af7Sopenharmony_ci	const auto			hitSBTStride		= shaderGroupHandleSize + shaderRecordSize;
1324e5c31af7Sopenharmony_ci	const auto			ssboSize			= static_cast<VkDeviceSize>(geoCount * hitSBTStride);
1325e5c31af7Sopenharmony_ci	const auto			ssboInfo			= makeBufferCreateInfo(ssboSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1326e5c31af7Sopenharmony_ci	BufferWithMemory	ssbo				(vkd, device, alloc, ssboInfo, MemoryRequirement::HostVisible);
1327e5c31af7Sopenharmony_ci	auto&				ssboAlloc			= ssbo.getAllocation();
1328e5c31af7Sopenharmony_ci	void*				ssboData			= ssboAlloc.getHostPtr();
1329e5c31af7Sopenharmony_ci
1330e5c31af7Sopenharmony_ci	deMemset(ssboData, 0, static_cast<size_t>(ssboSize));
1331e5c31af7Sopenharmony_ci
1332e5c31af7Sopenharmony_ci	// Descriptor set layout and pipeline layout.
1333e5c31af7Sopenharmony_ci	DescriptorSetLayoutBuilder setLayoutBuilder;
1334e5c31af7Sopenharmony_ci	setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, stages);
1335e5c31af7Sopenharmony_ci	setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, stages);
1336e5c31af7Sopenharmony_ci	const auto setLayout		= setLayoutBuilder.build(vkd, device);
1337e5c31af7Sopenharmony_ci	const auto pipelineLayout	= makePipelineLayout(vkd, device, setLayout.get());
1338e5c31af7Sopenharmony_ci
1339e5c31af7Sopenharmony_ci	// Descriptor pool and set.
1340e5c31af7Sopenharmony_ci	DescriptorPoolBuilder poolBuilder;
1341e5c31af7Sopenharmony_ci	poolBuilder.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR);
1342e5c31af7Sopenharmony_ci	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u);
1343e5c31af7Sopenharmony_ci	const auto descriptorPool	= poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1344e5c31af7Sopenharmony_ci	const auto descriptorSet	= makeDescriptorSet(vkd, device, descriptorPool.get(), setLayout.get());
1345e5c31af7Sopenharmony_ci
1346e5c31af7Sopenharmony_ci	// Update descriptor set.
1347e5c31af7Sopenharmony_ci	{
1348e5c31af7Sopenharmony_ci		const VkWriteDescriptorSetAccelerationStructureKHR accelDescInfo =
1349e5c31af7Sopenharmony_ci		{
1350e5c31af7Sopenharmony_ci			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,
1351e5c31af7Sopenharmony_ci			nullptr,
1352e5c31af7Sopenharmony_ci			1u,
1353e5c31af7Sopenharmony_ci			topLevelAS.get()->getPtr(),
1354e5c31af7Sopenharmony_ci		};
1355e5c31af7Sopenharmony_ci
1356e5c31af7Sopenharmony_ci		const auto ssboDescInfo = makeDescriptorBufferInfo(ssbo.get(), 0ull, ssboSize);
1357e5c31af7Sopenharmony_ci
1358e5c31af7Sopenharmony_ci		DescriptorSetUpdateBuilder updateBuilder;
1359e5c31af7Sopenharmony_ci		updateBuilder.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelDescInfo);
1360e5c31af7Sopenharmony_ci		updateBuilder.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &ssboDescInfo);
1361e5c31af7Sopenharmony_ci		updateBuilder.update(vkd, device);
1362e5c31af7Sopenharmony_ci	}
1363e5c31af7Sopenharmony_ci
1364e5c31af7Sopenharmony_ci	// Shader modules.
1365e5c31af7Sopenharmony_ci	auto rgenModule = makeVkSharedPtr(createShaderModule(vkd, device, m_context.getBinaryCollection().get("rgen"), 0));
1366e5c31af7Sopenharmony_ci	auto missModule = makeVkSharedPtr(createShaderModule(vkd, device, m_context.getBinaryCollection().get("miss"), 0));
1367e5c31af7Sopenharmony_ci	auto chitModule = makeVkSharedPtr(createShaderModule(vkd, device, m_context.getBinaryCollection().get("chit"), 0));
1368e5c31af7Sopenharmony_ci
1369e5c31af7Sopenharmony_ci	// Create raytracing pipeline and shader binding tables.
1370e5c31af7Sopenharmony_ci	Move<VkPipeline>				pipeline;
1371e5c31af7Sopenharmony_ci
1372e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	raygenSBT;
1373e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	missSBT;
1374e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	hitSBT;
1375e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	callableSBT;
1376e5c31af7Sopenharmony_ci
1377e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR	raygenSBTRegion		= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1378e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR	missSBTRegion		= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1379e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR	hitSBTRegion		= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1380e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR	callableSBTRegion	= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1381e5c31af7Sopenharmony_ci
1382e5c31af7Sopenharmony_ci	// Create shader record buffer data.
1383e5c31af7Sopenharmony_ci	using DataVec = std::vector<uint8_t>;
1384e5c31af7Sopenharmony_ci
1385e5c31af7Sopenharmony_ci	std::vector<DataVec> srbData;
1386e5c31af7Sopenharmony_ci	for (uint32_t i = 0; i < geoCount; ++i)
1387e5c31af7Sopenharmony_ci	{
1388e5c31af7Sopenharmony_ci		srbData.emplace_back(m_params.getRecordData(i));
1389e5c31af7Sopenharmony_ci	}
1390e5c31af7Sopenharmony_ci
1391e5c31af7Sopenharmony_ci	std::vector<const void*> srbDataPtrs;
1392e5c31af7Sopenharmony_ci	srbDataPtrs.reserve(srbData.size());
1393e5c31af7Sopenharmony_ci	std::transform(begin(srbData), end(srbData), std::back_inserter(srbDataPtrs), [](const DataVec& data) { return data.data(); });
1394e5c31af7Sopenharmony_ci
1395e5c31af7Sopenharmony_ci	// Generate ids for the closest hit and miss shaders according to the test parameters.
1396e5c31af7Sopenharmony_ci	{
1397e5c31af7Sopenharmony_ci		const auto rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
1398e5c31af7Sopenharmony_ci
1399e5c31af7Sopenharmony_ci		rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, rgenModule, 0u);
1400e5c31af7Sopenharmony_ci		rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, missModule, 1u);
1401e5c31af7Sopenharmony_ci
1402e5c31af7Sopenharmony_ci		for (uint32_t i = 0; i < geoCount; ++i)
1403e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, chitModule, 2u + i);
1404e5c31af7Sopenharmony_ci
1405e5c31af7Sopenharmony_ci		pipeline = rayTracingPipeline->createPipeline(vkd, device, pipelineLayout.get());
1406e5c31af7Sopenharmony_ci
1407e5c31af7Sopenharmony_ci		raygenSBT		= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 0u, 1u);
1408e5c31af7Sopenharmony_ci		raygenSBTRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenSBT->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
1409e5c31af7Sopenharmony_ci
1410e5c31af7Sopenharmony_ci		missSBT			= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 1u, 1u);
1411e5c31af7Sopenharmony_ci		missSBTRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missSBT->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
1412e5c31af7Sopenharmony_ci
1413e5c31af7Sopenharmony_ci		hitSBT			= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 2u, geoCount,
1414e5c31af7Sopenharmony_ci																	   0u, 0u, MemoryRequirement::Any, 0u, 0u, shaderRecordSize, srbDataPtrs.data(), false/*autoalign*/);
1415e5c31af7Sopenharmony_ci		hitSBTRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitSBT->get(), 0), hitSBTStride, hitSBTStride*geoCount);
1416e5c31af7Sopenharmony_ci	}
1417e5c31af7Sopenharmony_ci
1418e5c31af7Sopenharmony_ci	// Trace rays and verify ssbo contents.
1419e5c31af7Sopenharmony_ci	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline.get());
1420e5c31af7Sopenharmony_ci	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr);
1421e5c31af7Sopenharmony_ci	vkd.cmdTraceRaysKHR(cmdBuffer, &raygenSBTRegion, &missSBTRegion, &hitSBTRegion, &callableSBTRegion, geoCount, 1u, 1u);
1422e5c31af7Sopenharmony_ci	const auto shaderToHostBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
1423e5c31af7Sopenharmony_ci	cmdPipelineMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_HOST_BIT, &shaderToHostBarrier);
1424e5c31af7Sopenharmony_ci
1425e5c31af7Sopenharmony_ci	endCommandBuffer(vkd, cmdBuffer);
1426e5c31af7Sopenharmony_ci	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
1427e5c31af7Sopenharmony_ci
1428e5c31af7Sopenharmony_ci	invalidateAlloc(vkd, device, ssboAlloc);
1429e5c31af7Sopenharmony_ci
1430e5c31af7Sopenharmony_ci	// Verify SSBO.
1431e5c31af7Sopenharmony_ci	const auto	ssboDataAsBytes	= reinterpret_cast<const uint8_t*>(ssboData);
1432e5c31af7Sopenharmony_ci	size_t		ssboDataIdx		= 0u;
1433e5c31af7Sopenharmony_ci	bool		fail			= false;
1434e5c31af7Sopenharmony_ci	auto&		log				= m_context.getTestContext().getLog();
1435e5c31af7Sopenharmony_ci
1436e5c31af7Sopenharmony_ci	for (const auto& dataVec : srbData)
1437e5c31af7Sopenharmony_ci		for (const uint8_t byte : dataVec)
1438e5c31af7Sopenharmony_ci		{
1439e5c31af7Sopenharmony_ci			const uint8_t outputByte = ssboDataAsBytes[ssboDataIdx++];
1440e5c31af7Sopenharmony_ci			if (byte != outputByte)
1441e5c31af7Sopenharmony_ci			{
1442e5c31af7Sopenharmony_ci				std::ostringstream msg;
1443e5c31af7Sopenharmony_ci				msg
1444e5c31af7Sopenharmony_ci					<< std::hex << std::setfill('0')
1445e5c31af7Sopenharmony_ci					<< "Unexpectd output data: "
1446e5c31af7Sopenharmony_ci					<< "0x" << std::setw(2) << static_cast<int>(outputByte)
1447e5c31af7Sopenharmony_ci					<< " vs "
1448e5c31af7Sopenharmony_ci					<< "0x" << std::setw(2) << static_cast<int>(byte)
1449e5c31af7Sopenharmony_ci					;
1450e5c31af7Sopenharmony_ci				log << tcu::TestLog::Message << msg.str() << tcu::TestLog::EndMessage;
1451e5c31af7Sopenharmony_ci				fail = true;
1452e5c31af7Sopenharmony_ci			}
1453e5c31af7Sopenharmony_ci		}
1454e5c31af7Sopenharmony_ci
1455e5c31af7Sopenharmony_ci	if (fail)
1456e5c31af7Sopenharmony_ci		return tcu::TestStatus::fail("Unexpected output data found; check log for details");
1457e5c31af7Sopenharmony_ci	return tcu::TestStatus::pass("Pass");
1458e5c31af7Sopenharmony_ci}
1459e5c31af7Sopenharmony_ci
1460e5c31af7Sopenharmony_ci}	// anonymous
1461e5c31af7Sopenharmony_ci
1462e5c31af7Sopenharmony_citcu::TestCaseGroup*	createShaderBindingTableTests (tcu::TestContext& testCtx)
1463e5c31af7Sopenharmony_ci{
1464e5c31af7Sopenharmony_ci	// Tests veryfying shader binding tables
1465e5c31af7Sopenharmony_ci	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "shader_binding_table"));
1466e5c31af7Sopenharmony_ci
1467e5c31af7Sopenharmony_ci	struct ShaderTestTypeData
1468e5c31af7Sopenharmony_ci	{
1469e5c31af7Sopenharmony_ci		ShaderTestType							shaderTestType;
1470e5c31af7Sopenharmony_ci		const char*								name;
1471e5c31af7Sopenharmony_ci	} shaderTestTypes[] =
1472e5c31af7Sopenharmony_ci	{
1473e5c31af7Sopenharmony_ci		{ STT_HIT,		"indexing_hit"	},
1474e5c31af7Sopenharmony_ci		{ STT_MISS,		"indexing_miss"	},
1475e5c31af7Sopenharmony_ci		{ STT_CALL,		"indexing_call"	},
1476e5c31af7Sopenharmony_ci	};
1477e5c31af7Sopenharmony_ci
1478e5c31af7Sopenharmony_ci	struct ShaderBufferOffsetData
1479e5c31af7Sopenharmony_ci	{
1480e5c31af7Sopenharmony_ci		deUint32								sbtOffset;
1481e5c31af7Sopenharmony_ci		const char*								name;
1482e5c31af7Sopenharmony_ci	} shaderBufferOffsets[] =
1483e5c31af7Sopenharmony_ci	{
1484e5c31af7Sopenharmony_ci		{ 0u,	"sbt_offset_0"	},
1485e5c31af7Sopenharmony_ci		{ 4u,	"sbt_offset_4"	},
1486e5c31af7Sopenharmony_ci		{ 7u,	"sbt_offset_7"	},
1487e5c31af7Sopenharmony_ci		{ 16u,	"sbt_offset_16"	},
1488e5c31af7Sopenharmony_ci	};
1489e5c31af7Sopenharmony_ci
1490e5c31af7Sopenharmony_ci	struct ShaderRecordData
1491e5c31af7Sopenharmony_ci	{
1492e5c31af7Sopenharmony_ci		bool									present;
1493e5c31af7Sopenharmony_ci		const char*								name;
1494e5c31af7Sopenharmony_ci	} shaderRecords[] =
1495e5c31af7Sopenharmony_ci	{
1496e5c31af7Sopenharmony_ci		{ false,	"no_shaderrecord"	},
1497e5c31af7Sopenharmony_ci		{ true,		"shaderrecord"		},
1498e5c31af7Sopenharmony_ci	};
1499e5c31af7Sopenharmony_ci
1500e5c31af7Sopenharmony_ci	for (size_t shaderTestNdx = 0; shaderTestNdx < DE_LENGTH_OF_ARRAY(shaderTestTypes); ++shaderTestNdx)
1501e5c31af7Sopenharmony_ci	{
1502e5c31af7Sopenharmony_ci		de::MovePtr<tcu::TestCaseGroup> shaderTestGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderTestTypes[shaderTestNdx].name));
1503e5c31af7Sopenharmony_ci
1504e5c31af7Sopenharmony_ci		for (size_t sbtOffsetNdx = 0; sbtOffsetNdx < DE_LENGTH_OF_ARRAY(shaderBufferOffsets); ++sbtOffsetNdx)
1505e5c31af7Sopenharmony_ci		{
1506e5c31af7Sopenharmony_ci			de::MovePtr<tcu::TestCaseGroup> sbtOffsetGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderBufferOffsets[sbtOffsetNdx].name));
1507e5c31af7Sopenharmony_ci
1508e5c31af7Sopenharmony_ci			for (size_t shaderRecordNdx = 0; shaderRecordNdx < DE_LENGTH_OF_ARRAY(shaderRecords); ++shaderRecordNdx)
1509e5c31af7Sopenharmony_ci			{
1510e5c31af7Sopenharmony_ci				de::MovePtr<tcu::TestCaseGroup> shaderRecordGroup(new tcu::TestCaseGroup(group->getTestContext(), shaderRecords[shaderRecordNdx].name));
1511e5c31af7Sopenharmony_ci
1512e5c31af7Sopenharmony_ci				deUint32		maxSbtRecordStride				= (shaderTestTypes[shaderTestNdx].shaderTestType == STT_HIT) ? MAX_HIT_SBT_RECORD_STRIDE + 1 : 1;
1513e5c31af7Sopenharmony_ci				deUint32		maxSbtRecordOffset				= MAX_SBT_RECORD_OFFSET;
1514e5c31af7Sopenharmony_ci				const deUint32	maxSbtRecordOffsetWithExtraBits = (shaderTestTypes[shaderTestNdx].shaderTestType == STT_MISS)	? MAX_SBT_RECORD_OFFSET | (~((1u << 16) - 1))  //< Only 16 least significant bits matter for miss indices
1515e5c31af7Sopenharmony_ci																																: MAX_SBT_RECORD_OFFSET | (~((1u << 4)  - 1)); //< Only 4 least significant bits matter for SBT record offsets
1516e5c31af7Sopenharmony_ci
1517e5c31af7Sopenharmony_ci				for (deUint32 sbtRecordOffset = 0; sbtRecordOffset <= maxSbtRecordOffset; ++sbtRecordOffset)
1518e5c31af7Sopenharmony_ci					for (deUint32 sbtRecordStride = 0; sbtRecordStride <= maxSbtRecordStride; ++sbtRecordStride)
1519e5c31af7Sopenharmony_ci					{
1520e5c31af7Sopenharmony_ci						if ((shaderTestTypes[shaderTestNdx].shaderTestType	!= STT_HIT)				&&
1521e5c31af7Sopenharmony_ci							(sbtRecordStride								== maxSbtRecordStride))
1522e5c31af7Sopenharmony_ci						{
1523e5c31af7Sopenharmony_ci							continue;
1524e5c31af7Sopenharmony_ci						}
1525e5c31af7Sopenharmony_ci
1526e5c31af7Sopenharmony_ci						TestParams testParams
1527e5c31af7Sopenharmony_ci						{
1528e5c31af7Sopenharmony_ci							CHECKERBOARD_WIDTH,
1529e5c31af7Sopenharmony_ci							CHECKERBOARD_HEIGHT,
1530e5c31af7Sopenharmony_ci							shaderTestTypes[shaderTestNdx].shaderTestType,
1531e5c31af7Sopenharmony_ci							shaderBufferOffsets[sbtOffsetNdx].sbtOffset,
1532e5c31af7Sopenharmony_ci							shaderRecords[shaderRecordNdx].present,
1533e5c31af7Sopenharmony_ci							sbtRecordOffset,
1534e5c31af7Sopenharmony_ci							(sbtRecordOffset == maxSbtRecordOffset)	? maxSbtRecordOffsetWithExtraBits
1535e5c31af7Sopenharmony_ci																	: sbtRecordOffset,
1536e5c31af7Sopenharmony_ci							//< Only first 4 least significant bits matter for SBT record stride
1537e5c31af7Sopenharmony_ci							sbtRecordStride,
1538e5c31af7Sopenharmony_ci							(sbtRecordStride == maxSbtRecordStride)	? maxSbtRecordStride | (~((1u << 4) - 1))
1539e5c31af7Sopenharmony_ci																	: sbtRecordStride,
1540e5c31af7Sopenharmony_ci							de::SharedPtr<TestConfiguration>(new CheckerboardConfiguration())
1541e5c31af7Sopenharmony_ci						};
1542e5c31af7Sopenharmony_ci
1543e5c31af7Sopenharmony_ci						std::stringstream str;
1544e5c31af7Sopenharmony_ci						str << sbtRecordOffset << "_" << sbtRecordStride;
1545e5c31af7Sopenharmony_ci
1546e5c31af7Sopenharmony_ci						if (testParams.sbtRecordStride != testParams.sbtRecordStridePassedToTraceRay)
1547e5c31af7Sopenharmony_ci						{
1548e5c31af7Sopenharmony_ci							str << "_extraSBTRecordStrideBits";
1549e5c31af7Sopenharmony_ci						}
1550e5c31af7Sopenharmony_ci
1551e5c31af7Sopenharmony_ci						if (testParams.sbtRecordOffset != testParams.sbtRecordOffsetPassedToTraceRay)
1552e5c31af7Sopenharmony_ci						{
1553e5c31af7Sopenharmony_ci							str << "_extrabits";
1554e5c31af7Sopenharmony_ci						}
1555e5c31af7Sopenharmony_ci
1556e5c31af7Sopenharmony_ci						shaderRecordGroup->addChild(new ShaderBindingTableIndexingTestCase(group->getTestContext(), str.str().c_str(), testParams));
1557e5c31af7Sopenharmony_ci					}
1558e5c31af7Sopenharmony_ci
1559e5c31af7Sopenharmony_ci				sbtOffsetGroup->addChild(shaderRecordGroup.release());
1560e5c31af7Sopenharmony_ci			}
1561e5c31af7Sopenharmony_ci
1562e5c31af7Sopenharmony_ci			shaderTestGroup->addChild(sbtOffsetGroup.release());
1563e5c31af7Sopenharmony_ci		}
1564e5c31af7Sopenharmony_ci
1565e5c31af7Sopenharmony_ci		group->addChild(shaderTestGroup.release());
1566e5c31af7Sopenharmony_ci	}
1567e5c31af7Sopenharmony_ci
1568e5c31af7Sopenharmony_ci	{
1569e5c31af7Sopenharmony_ci		const uint32_t					kAlignments[]			= { 1u, 2u, 4u, 8u, 16u, 32u };
1570e5c31af7Sopenharmony_ci		de::MovePtr<tcu::TestCaseGroup>	handleAlignmentGroup	(new tcu::TestCaseGroup(testCtx, "handle_alignment", "Test allowed handle alignments"));
1571e5c31af7Sopenharmony_ci
1572e5c31af7Sopenharmony_ci		for (const auto alignment : kAlignments)
1573e5c31af7Sopenharmony_ci		{
1574e5c31af7Sopenharmony_ci			const auto alignStr = std::to_string(alignment);
1575e5c31af7Sopenharmony_ci			const auto testName = "alignment_" + alignStr;
1576e5c31af7Sopenharmony_ci			// Check aligning shader group handles
1577e5c31af7Sopenharmony_ci			handleAlignmentGroup->addChild(new ShaderGroupHandleAlignmentCase(testCtx, testName, ShaderGroupHandleAlignmentParams{alignment}));
1578e5c31af7Sopenharmony_ci		}
1579e5c31af7Sopenharmony_ci
1580e5c31af7Sopenharmony_ci		group->addChild(handleAlignmentGroup.release());
1581e5c31af7Sopenharmony_ci	}
1582e5c31af7Sopenharmony_ci
1583e5c31af7Sopenharmony_ci	return group.release();
1584e5c31af7Sopenharmony_ci}
1585e5c31af7Sopenharmony_ci
1586e5c31af7Sopenharmony_ci}	// RayTracing
1587e5c31af7Sopenharmony_ci
1588e5c31af7Sopenharmony_ci}	// vkt
1589