1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests
3e5c31af7Sopenharmony_ci * ------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2020 The Khronos Group Inc.
6e5c31af7Sopenharmony_ci * Copyright (c) 2020 Valve Corporation.
7e5c31af7Sopenharmony_ci *
8e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
9e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
10e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
11e5c31af7Sopenharmony_ci *
12e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
13e5c31af7Sopenharmony_ci *
14e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
15e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
16e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
18e5c31af7Sopenharmony_ci * limitations under the License.
19e5c31af7Sopenharmony_ci *
20e5c31af7Sopenharmony_ci *//*!
21e5c31af7Sopenharmony_ci * \file
22e5c31af7Sopenharmony_ci * \brief Ray Tracing Data Spill tests
23e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
24e5c31af7Sopenharmony_ci#include "vktRayTracingDataSpillTests.hpp"
25e5c31af7Sopenharmony_ci#include "vktTestCase.hpp"
26e5c31af7Sopenharmony_ci
27e5c31af7Sopenharmony_ci#include "vkRayTracingUtil.hpp"
28e5c31af7Sopenharmony_ci#include "vkObjUtil.hpp"
29e5c31af7Sopenharmony_ci#include "vkBufferWithMemory.hpp"
30e5c31af7Sopenharmony_ci#include "vkImageWithMemory.hpp"
31e5c31af7Sopenharmony_ci#include "vkBuilderUtil.hpp"
32e5c31af7Sopenharmony_ci#include "vkCmdUtil.hpp"
33e5c31af7Sopenharmony_ci#include "vkTypeUtil.hpp"
34e5c31af7Sopenharmony_ci#include "vkBarrierUtil.hpp"
35e5c31af7Sopenharmony_ci
36e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp"
37e5c31af7Sopenharmony_ci#include "tcuFloat.hpp"
38e5c31af7Sopenharmony_ci
39e5c31af7Sopenharmony_ci#include "deUniquePtr.hpp"
40e5c31af7Sopenharmony_ci#include "deSTLUtil.hpp"
41e5c31af7Sopenharmony_ci
42e5c31af7Sopenharmony_ci#include <sstream>
43e5c31af7Sopenharmony_ci#include <string>
44e5c31af7Sopenharmony_ci#include <map>
45e5c31af7Sopenharmony_ci#include <vector>
46e5c31af7Sopenharmony_ci#include <array>
47e5c31af7Sopenharmony_ci#include <utility>
48e5c31af7Sopenharmony_ci
49e5c31af7Sopenharmony_ciusing namespace vk;
50e5c31af7Sopenharmony_ci
51e5c31af7Sopenharmony_cinamespace vkt
52e5c31af7Sopenharmony_ci{
53e5c31af7Sopenharmony_cinamespace RayTracing
54e5c31af7Sopenharmony_ci{
55e5c31af7Sopenharmony_ci
56e5c31af7Sopenharmony_cinamespace
57e5c31af7Sopenharmony_ci{
58e5c31af7Sopenharmony_ci
59e5c31af7Sopenharmony_ci// The type of shader call that will be used.
60e5c31af7Sopenharmony_cienum class CallType
61e5c31af7Sopenharmony_ci{
62e5c31af7Sopenharmony_ci	TRACE_RAY = 0,
63e5c31af7Sopenharmony_ci	EXECUTE_CALLABLE,
64e5c31af7Sopenharmony_ci	REPORT_INTERSECTION,
65e5c31af7Sopenharmony_ci};
66e5c31af7Sopenharmony_ci
67e5c31af7Sopenharmony_ci// The type of data that will be checked.
68e5c31af7Sopenharmony_cienum class DataType
69e5c31af7Sopenharmony_ci{
70e5c31af7Sopenharmony_ci	// These can be made an array or vector.
71e5c31af7Sopenharmony_ci	INT32 = 0,
72e5c31af7Sopenharmony_ci	UINT32,
73e5c31af7Sopenharmony_ci	INT64,
74e5c31af7Sopenharmony_ci	UINT64,
75e5c31af7Sopenharmony_ci	INT16,
76e5c31af7Sopenharmony_ci	UINT16,
77e5c31af7Sopenharmony_ci	INT8,
78e5c31af7Sopenharmony_ci	UINT8,
79e5c31af7Sopenharmony_ci	FLOAT32,
80e5c31af7Sopenharmony_ci	FLOAT64,
81e5c31af7Sopenharmony_ci	FLOAT16,
82e5c31af7Sopenharmony_ci
83e5c31af7Sopenharmony_ci	// These are standalone, so the vector type should be scalar.
84e5c31af7Sopenharmony_ci	STRUCT,
85e5c31af7Sopenharmony_ci	IMAGE,
86e5c31af7Sopenharmony_ci	SAMPLER,
87e5c31af7Sopenharmony_ci	SAMPLED_IMAGE,
88e5c31af7Sopenharmony_ci	PTR_IMAGE,
89e5c31af7Sopenharmony_ci	PTR_SAMPLER,
90e5c31af7Sopenharmony_ci	PTR_SAMPLED_IMAGE,
91e5c31af7Sopenharmony_ci	PTR_TEXEL,
92e5c31af7Sopenharmony_ci	OP_NULL,
93e5c31af7Sopenharmony_ci	OP_UNDEF,
94e5c31af7Sopenharmony_ci};
95e5c31af7Sopenharmony_ci
96e5c31af7Sopenharmony_ci// The type of vector in use.
97e5c31af7Sopenharmony_cienum class VectorType
98e5c31af7Sopenharmony_ci{
99e5c31af7Sopenharmony_ci	SCALAR	= 1,
100e5c31af7Sopenharmony_ci	V2		= 2,
101e5c31af7Sopenharmony_ci	V3		= 3,
102e5c31af7Sopenharmony_ci	V4		= 4,
103e5c31af7Sopenharmony_ci	A5		= 5,
104e5c31af7Sopenharmony_ci};
105e5c31af7Sopenharmony_ci
106e5c31af7Sopenharmony_cistruct InputStruct
107e5c31af7Sopenharmony_ci{
108e5c31af7Sopenharmony_ci	deUint32	uintPart;
109e5c31af7Sopenharmony_ci	float		floatPart;
110e5c31af7Sopenharmony_ci};
111e5c31af7Sopenharmony_ci
112e5c31af7Sopenharmony_ciconstexpr auto			kImageFormat		= VK_FORMAT_R32_UINT;
113e5c31af7Sopenharmony_ciconst auto				kImageExtent		= makeExtent3D(1u, 1u, 1u);
114e5c31af7Sopenharmony_ci
115e5c31af7Sopenharmony_ci// For samplers.
116e5c31af7Sopenharmony_ciconst VkImageUsageFlags	kSampledImageUsage	= (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
117e5c31af7Sopenharmony_ciconstexpr size_t		kNumImages			= 4u;
118e5c31af7Sopenharmony_ciconstexpr size_t		kNumSamplers		= 4u;
119e5c31af7Sopenharmony_ciconstexpr size_t		kNumCombined		= 2u;
120e5c31af7Sopenharmony_ciconstexpr size_t		kNumAloneImages		= kNumImages - kNumCombined;
121e5c31af7Sopenharmony_ciconstexpr size_t		kNumAloneSamplers	= kNumSamplers - kNumCombined;
122e5c31af7Sopenharmony_ci
123e5c31af7Sopenharmony_ci// For storage images.
124e5c31af7Sopenharmony_ciconst VkImageUsageFlags	kStorageImageUsage	= (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT);
125e5c31af7Sopenharmony_ci
126e5c31af7Sopenharmony_ci// For the pipeline interface tests.
127e5c31af7Sopenharmony_ciconstexpr size_t		kNumStorageValues	= 6u;
128e5c31af7Sopenharmony_ciconstexpr deUint32		kShaderRecordSize	= sizeof(tcu::UVec4);
129e5c31af7Sopenharmony_ci
130e5c31af7Sopenharmony_ci// Get the effective vector length in memory.
131e5c31af7Sopenharmony_cisize_t getEffectiveVectorLength (VectorType vectorType)
132e5c31af7Sopenharmony_ci{
133e5c31af7Sopenharmony_ci	return ((vectorType == VectorType::V3) ? static_cast<size_t>(4) : static_cast<size_t>(vectorType));
134e5c31af7Sopenharmony_ci}
135e5c31af7Sopenharmony_ci
136e5c31af7Sopenharmony_ci// Get the corresponding element size.
137e5c31af7Sopenharmony_ciVkDeviceSize getElementSize(DataType dataType, VectorType vectorType)
138e5c31af7Sopenharmony_ci{
139e5c31af7Sopenharmony_ci	const size_t	length		= getEffectiveVectorLength(vectorType);
140e5c31af7Sopenharmony_ci	size_t			dataSize	= 0u;
141e5c31af7Sopenharmony_ci
142e5c31af7Sopenharmony_ci	switch (dataType)
143e5c31af7Sopenharmony_ci	{
144e5c31af7Sopenharmony_ci	case DataType::INT32:			dataSize = sizeof(deInt32);			break;
145e5c31af7Sopenharmony_ci	case DataType::UINT32:			dataSize = sizeof(deUint32);		break;
146e5c31af7Sopenharmony_ci	case DataType::INT64:			dataSize = sizeof(deInt64);			break;
147e5c31af7Sopenharmony_ci	case DataType::UINT64:			dataSize = sizeof(deUint64);		break;
148e5c31af7Sopenharmony_ci	case DataType::INT16:			dataSize = sizeof(deInt16);			break;
149e5c31af7Sopenharmony_ci	case DataType::UINT16:			dataSize = sizeof(deUint16);		break;
150e5c31af7Sopenharmony_ci	case DataType::INT8:			dataSize = sizeof(deInt8);			break;
151e5c31af7Sopenharmony_ci	case DataType::UINT8:			dataSize = sizeof(deUint8);			break;
152e5c31af7Sopenharmony_ci	case DataType::FLOAT32:			dataSize = sizeof(tcu::Float32);	break;
153e5c31af7Sopenharmony_ci	case DataType::FLOAT64:			dataSize = sizeof(tcu::Float64);	break;
154e5c31af7Sopenharmony_ci	case DataType::FLOAT16:			dataSize = sizeof(tcu::Float16);	break;
155e5c31af7Sopenharmony_ci	case DataType::STRUCT:			dataSize = sizeof(InputStruct);		break;
156e5c31af7Sopenharmony_ci	case DataType::IMAGE:				// fallthrough.
157e5c31af7Sopenharmony_ci	case DataType::SAMPLER:				// fallthrough.
158e5c31af7Sopenharmony_ci	case DataType::SAMPLED_IMAGE:		// fallthrough.
159e5c31af7Sopenharmony_ci	case DataType::PTR_IMAGE:			// fallthrough.
160e5c31af7Sopenharmony_ci	case DataType::PTR_SAMPLER:			// fallthrough.
161e5c31af7Sopenharmony_ci	case DataType::PTR_SAMPLED_IMAGE:	// fallthrough.
162e5c31af7Sopenharmony_ci									dataSize = sizeof(tcu::Float32);	break;
163e5c31af7Sopenharmony_ci	case DataType::PTR_TEXEL:		dataSize = sizeof(deInt32);			break;
164e5c31af7Sopenharmony_ci	case DataType::OP_NULL:				// fallthrough.
165e5c31af7Sopenharmony_ci	case DataType::OP_UNDEF:			// fallthrough.
166e5c31af7Sopenharmony_ci									dataSize = sizeof(deUint32);		break;
167e5c31af7Sopenharmony_ci	default: DE_ASSERT(false); break;
168e5c31af7Sopenharmony_ci	}
169e5c31af7Sopenharmony_ci
170e5c31af7Sopenharmony_ci	return static_cast<VkDeviceSize>(dataSize * length);
171e5c31af7Sopenharmony_ci}
172e5c31af7Sopenharmony_ci
173e5c31af7Sopenharmony_ci// Proper stage for generating default geometry.
174e5c31af7Sopenharmony_ciVkShaderStageFlagBits getShaderStageForGeometry (CallType type_)
175e5c31af7Sopenharmony_ci{
176e5c31af7Sopenharmony_ci	VkShaderStageFlagBits bits = VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM;
177e5c31af7Sopenharmony_ci
178e5c31af7Sopenharmony_ci	switch (type_)
179e5c31af7Sopenharmony_ci	{
180e5c31af7Sopenharmony_ci	case CallType::TRACE_RAY:			bits = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;		break;
181e5c31af7Sopenharmony_ci	case CallType::EXECUTE_CALLABLE:	bits = VK_SHADER_STAGE_CALLABLE_BIT_KHR;		break;
182e5c31af7Sopenharmony_ci	case CallType::REPORT_INTERSECTION:	bits = VK_SHADER_STAGE_INTERSECTION_BIT_KHR;	break;
183e5c31af7Sopenharmony_ci	default: DE_ASSERT(false); break;
184e5c31af7Sopenharmony_ci	}
185e5c31af7Sopenharmony_ci
186e5c31af7Sopenharmony_ci	DE_ASSERT(bits != VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM);
187e5c31af7Sopenharmony_ci	return bits;
188e5c31af7Sopenharmony_ci}
189e5c31af7Sopenharmony_ci
190e5c31af7Sopenharmony_ciVkShaderStageFlags getShaderStages (CallType type_)
191e5c31af7Sopenharmony_ci{
192e5c31af7Sopenharmony_ci	VkShaderStageFlags flags = VK_SHADER_STAGE_RAYGEN_BIT_KHR;
193e5c31af7Sopenharmony_ci
194e5c31af7Sopenharmony_ci	switch (type_)
195e5c31af7Sopenharmony_ci	{
196e5c31af7Sopenharmony_ci	case CallType::EXECUTE_CALLABLE:
197e5c31af7Sopenharmony_ci		flags |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
198e5c31af7Sopenharmony_ci		break;
199e5c31af7Sopenharmony_ci	case CallType::TRACE_RAY:
200e5c31af7Sopenharmony_ci		flags |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
201e5c31af7Sopenharmony_ci		break;
202e5c31af7Sopenharmony_ci	case CallType::REPORT_INTERSECTION:
203e5c31af7Sopenharmony_ci		flags |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
204e5c31af7Sopenharmony_ci		flags |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
205e5c31af7Sopenharmony_ci		break;
206e5c31af7Sopenharmony_ci	default:
207e5c31af7Sopenharmony_ci		DE_ASSERT(false);
208e5c31af7Sopenharmony_ci		break;
209e5c31af7Sopenharmony_ci	}
210e5c31af7Sopenharmony_ci
211e5c31af7Sopenharmony_ci	return flags;
212e5c31af7Sopenharmony_ci}
213e5c31af7Sopenharmony_ci
214e5c31af7Sopenharmony_ci// Some test types need additional descriptors with samplers, images and combined image samplers.
215e5c31af7Sopenharmony_cibool samplersNeeded (DataType dataType)
216e5c31af7Sopenharmony_ci{
217e5c31af7Sopenharmony_ci	bool needed = false;
218e5c31af7Sopenharmony_ci
219e5c31af7Sopenharmony_ci	switch (dataType)
220e5c31af7Sopenharmony_ci	{
221e5c31af7Sopenharmony_ci	case DataType::IMAGE:
222e5c31af7Sopenharmony_ci	case DataType::SAMPLER:
223e5c31af7Sopenharmony_ci	case DataType::SAMPLED_IMAGE:
224e5c31af7Sopenharmony_ci	case DataType::PTR_IMAGE:
225e5c31af7Sopenharmony_ci	case DataType::PTR_SAMPLER:
226e5c31af7Sopenharmony_ci	case DataType::PTR_SAMPLED_IMAGE:
227e5c31af7Sopenharmony_ci		needed = true;
228e5c31af7Sopenharmony_ci		break;
229e5c31af7Sopenharmony_ci	default:
230e5c31af7Sopenharmony_ci		break;
231e5c31af7Sopenharmony_ci	}
232e5c31af7Sopenharmony_ci
233e5c31af7Sopenharmony_ci	return needed;
234e5c31af7Sopenharmony_ci}
235e5c31af7Sopenharmony_ci
236e5c31af7Sopenharmony_ci// Some test types need an additional descriptor with a storage image.
237e5c31af7Sopenharmony_cibool storageImageNeeded (DataType dataType)
238e5c31af7Sopenharmony_ci{
239e5c31af7Sopenharmony_ci	return (dataType == DataType::PTR_TEXEL);
240e5c31af7Sopenharmony_ci}
241e5c31af7Sopenharmony_ci
242e5c31af7Sopenharmony_ci// Returns two strings:
243e5c31af7Sopenharmony_ci//		.first is an optional GLSL additional type declaration (for structs, basically).
244e5c31af7Sopenharmony_ci//		.second is the value declaration inside the input block.
245e5c31af7Sopenharmony_cistd::pair<std::string, std::string> getGLSLInputValDecl (DataType dataType, VectorType vectorType)
246e5c31af7Sopenharmony_ci{
247e5c31af7Sopenharmony_ci	using TypePair	= std::pair<DataType, VectorType>;
248e5c31af7Sopenharmony_ci	using TypeMap	= std::map<TypePair, std::string>;
249e5c31af7Sopenharmony_ci
250e5c31af7Sopenharmony_ci	const std::string	varName		= "val";
251e5c31af7Sopenharmony_ci	const auto			dataTypeIdx	= static_cast<int>(dataType);
252e5c31af7Sopenharmony_ci
253e5c31af7Sopenharmony_ci	if (dataTypeIdx >= static_cast<int>(DataType::INT32) && dataTypeIdx <= static_cast<int>(DataType::FLOAT16))
254e5c31af7Sopenharmony_ci	{
255e5c31af7Sopenharmony_ci		// Note: A5 uses the same type as the scalar version. The array suffix will be added below.
256e5c31af7Sopenharmony_ci		const TypeMap map =
257e5c31af7Sopenharmony_ci		{
258e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT32,		VectorType::SCALAR),	"int32_t"),
259e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT32,		VectorType::V2),		"i32vec2"),
260e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT32,		VectorType::V3),		"i32vec3"),
261e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT32,		VectorType::V4),		"i32vec4"),
262e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT32,		VectorType::A5),		"int32_t"),
263e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT32,		VectorType::SCALAR),	"uint32_t"),
264e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT32,		VectorType::V2),		"u32vec2"),
265e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT32,		VectorType::V3),		"u32vec3"),
266e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT32,		VectorType::V4),		"u32vec4"),
267e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT32,		VectorType::A5),		"uint32_t"),
268e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT64,		VectorType::SCALAR),	"int64_t"),
269e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT64,		VectorType::V2),		"i64vec2"),
270e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT64,		VectorType::V3),		"i64vec3"),
271e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT64,		VectorType::V4),		"i64vec4"),
272e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT64,		VectorType::A5),		"int64_t"),
273e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT64,		VectorType::SCALAR),	"uint64_t"),
274e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT64,		VectorType::V2),		"u64vec2"),
275e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT64,		VectorType::V3),		"u64vec3"),
276e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT64,		VectorType::V4),		"u64vec4"),
277e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT64,		VectorType::A5),		"uint64_t"),
278e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT16,		VectorType::SCALAR),	"int16_t"),
279e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT16,		VectorType::V2),		"i16vec2"),
280e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT16,		VectorType::V3),		"i16vec3"),
281e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT16,		VectorType::V4),		"i16vec4"),
282e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT16,		VectorType::A5),		"int16_t"),
283e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT16,		VectorType::SCALAR),	"uint16_t"),
284e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT16,		VectorType::V2),		"u16vec2"),
285e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT16,		VectorType::V3),		"u16vec3"),
286e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT16,		VectorType::V4),		"u16vec4"),
287e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT16,		VectorType::A5),		"uint16_t"),
288e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT8,		VectorType::SCALAR),	"int8_t"),
289e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT8,		VectorType::V2),		"i8vec2"),
290e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT8,		VectorType::V3),		"i8vec3"),
291e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT8,		VectorType::V4),		"i8vec4"),
292e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::INT8,		VectorType::A5),		"int8_t"),
293e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT8,		VectorType::SCALAR),	"uint8_t"),
294e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT8,		VectorType::V2),		"u8vec2"),
295e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT8,		VectorType::V3),		"u8vec3"),
296e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT8,		VectorType::V4),		"u8vec4"),
297e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::UINT8,		VectorType::A5),		"uint8_t"),
298e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT32,	VectorType::SCALAR),	"float32_t"),
299e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT32,	VectorType::V2),		"f32vec2"),
300e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT32,	VectorType::V3),		"f32vec3"),
301e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT32,	VectorType::V4),		"f32vec4"),
302e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT32,	VectorType::A5),		"float32_t"),
303e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT64,	VectorType::SCALAR),	"float64_t"),
304e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT64,	VectorType::V2),		"f64vec2"),
305e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT64,	VectorType::V3),		"f64vec3"),
306e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT64,	VectorType::V4),		"f64vec4"),
307e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT64,	VectorType::A5),		"float64_t"),
308e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT16,	VectorType::SCALAR),	"float16_t"),
309e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT16,	VectorType::V2),		"f16vec2"),
310e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT16,	VectorType::V3),		"f16vec3"),
311e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT16,	VectorType::V4),		"f16vec4"),
312e5c31af7Sopenharmony_ci			std::make_pair(std::make_pair(DataType::FLOAT16,	VectorType::A5),		"float16_t"),
313e5c31af7Sopenharmony_ci		};
314e5c31af7Sopenharmony_ci
315e5c31af7Sopenharmony_ci		const auto key		= std::make_pair(dataType, vectorType);
316e5c31af7Sopenharmony_ci		const auto found	= map.find(key);
317e5c31af7Sopenharmony_ci
318e5c31af7Sopenharmony_ci		DE_ASSERT(found != end(map));
319e5c31af7Sopenharmony_ci
320e5c31af7Sopenharmony_ci		const auto baseType		= found->second;
321e5c31af7Sopenharmony_ci		const std::string decl	= baseType + " " + varName + ((vectorType == VectorType::A5) ? "[5]" : "") + ";";
322e5c31af7Sopenharmony_ci
323e5c31af7Sopenharmony_ci		return std::make_pair(std::string(), decl);
324e5c31af7Sopenharmony_ci	}
325e5c31af7Sopenharmony_ci	else if (dataType == DataType::STRUCT)
326e5c31af7Sopenharmony_ci	{
327e5c31af7Sopenharmony_ci		return std::make_pair(std::string("struct InputStruct { uint val1; float val2; };\n"), std::string("InputStruct val;"));
328e5c31af7Sopenharmony_ci	}
329e5c31af7Sopenharmony_ci	else if (samplersNeeded(dataType))
330e5c31af7Sopenharmony_ci	{
331e5c31af7Sopenharmony_ci		return std::make_pair(std::string(), std::string("float val;"));
332e5c31af7Sopenharmony_ci	}
333e5c31af7Sopenharmony_ci	else if (storageImageNeeded(dataType))
334e5c31af7Sopenharmony_ci	{
335e5c31af7Sopenharmony_ci		return std::make_pair(std::string(), std::string("int val;"));
336e5c31af7Sopenharmony_ci	}
337e5c31af7Sopenharmony_ci	else if (dataType == DataType::OP_NULL || dataType == DataType::OP_UNDEF)
338e5c31af7Sopenharmony_ci	{
339e5c31af7Sopenharmony_ci		return std::make_pair(std::string(), std::string("uint val;"));
340e5c31af7Sopenharmony_ci	}
341e5c31af7Sopenharmony_ci
342e5c31af7Sopenharmony_ci	// Unreachable.
343e5c31af7Sopenharmony_ci	DE_ASSERT(false);
344e5c31af7Sopenharmony_ci	return std::make_pair(std::string(), std::string());
345e5c31af7Sopenharmony_ci}
346e5c31af7Sopenharmony_ci
347e5c31af7Sopenharmony_ciclass DataSpillTestCase : public vkt::TestCase
348e5c31af7Sopenharmony_ci{
349e5c31af7Sopenharmony_cipublic:
350e5c31af7Sopenharmony_ci	struct TestParams
351e5c31af7Sopenharmony_ci	{
352e5c31af7Sopenharmony_ci		CallType	callType;
353e5c31af7Sopenharmony_ci		DataType	dataType;
354e5c31af7Sopenharmony_ci		VectorType	vectorType;
355e5c31af7Sopenharmony_ci	};
356e5c31af7Sopenharmony_ci
357e5c31af7Sopenharmony_ci							DataSpillTestCase		(tcu::TestContext& testCtx, const std::string& name, const TestParams& testParams);
358e5c31af7Sopenharmony_ci	virtual					~DataSpillTestCase		(void) {}
359e5c31af7Sopenharmony_ci
360e5c31af7Sopenharmony_ci	virtual void			initPrograms			(vk::SourceCollections& programCollection) const;
361e5c31af7Sopenharmony_ci	virtual TestInstance*	createInstance			(Context& context) const;
362e5c31af7Sopenharmony_ci	virtual void			checkSupport			(Context& context) const;
363e5c31af7Sopenharmony_ci
364e5c31af7Sopenharmony_ciprivate:
365e5c31af7Sopenharmony_ci	TestParams				m_params;
366e5c31af7Sopenharmony_ci};
367e5c31af7Sopenharmony_ci
368e5c31af7Sopenharmony_ciclass DataSpillTestInstance : public vkt::TestInstance
369e5c31af7Sopenharmony_ci{
370e5c31af7Sopenharmony_cipublic:
371e5c31af7Sopenharmony_ci	using TestParams = DataSpillTestCase::TestParams;
372e5c31af7Sopenharmony_ci
373e5c31af7Sopenharmony_ci								DataSpillTestInstance	(Context& context, const TestParams& testParams);
374e5c31af7Sopenharmony_ci	virtual						~DataSpillTestInstance	(void) {}
375e5c31af7Sopenharmony_ci
376e5c31af7Sopenharmony_ci	virtual tcu::TestStatus		iterate					(void);
377e5c31af7Sopenharmony_ci
378e5c31af7Sopenharmony_ciprivate:
379e5c31af7Sopenharmony_ci	TestParams					m_params;
380e5c31af7Sopenharmony_ci};
381e5c31af7Sopenharmony_ci
382e5c31af7Sopenharmony_ci
383e5c31af7Sopenharmony_ciDataSpillTestCase::DataSpillTestCase (tcu::TestContext& testCtx, const std::string& name, const TestParams& testParams)
384e5c31af7Sopenharmony_ci	: vkt::TestCase	(testCtx, name)
385e5c31af7Sopenharmony_ci	, m_params		(testParams)
386e5c31af7Sopenharmony_ci{
387e5c31af7Sopenharmony_ci	switch (m_params.dataType)
388e5c31af7Sopenharmony_ci	{
389e5c31af7Sopenharmony_ci	case DataType::STRUCT:
390e5c31af7Sopenharmony_ci	case DataType::IMAGE:
391e5c31af7Sopenharmony_ci	case DataType::SAMPLER:
392e5c31af7Sopenharmony_ci	case DataType::SAMPLED_IMAGE:
393e5c31af7Sopenharmony_ci	case DataType::PTR_IMAGE:
394e5c31af7Sopenharmony_ci	case DataType::PTR_SAMPLER:
395e5c31af7Sopenharmony_ci	case DataType::PTR_SAMPLED_IMAGE:
396e5c31af7Sopenharmony_ci	case DataType::PTR_TEXEL:
397e5c31af7Sopenharmony_ci	case DataType::OP_NULL:
398e5c31af7Sopenharmony_ci	case DataType::OP_UNDEF:
399e5c31af7Sopenharmony_ci		DE_ASSERT(m_params.vectorType == VectorType::SCALAR);
400e5c31af7Sopenharmony_ci		break;
401e5c31af7Sopenharmony_ci	default:
402e5c31af7Sopenharmony_ci		break;
403e5c31af7Sopenharmony_ci	}
404e5c31af7Sopenharmony_ci
405e5c31af7Sopenharmony_ci	// The code assumes at most one of these is needed.
406e5c31af7Sopenharmony_ci	DE_ASSERT(!(samplersNeeded(m_params.dataType) && storageImageNeeded(m_params.dataType)));
407e5c31af7Sopenharmony_ci}
408e5c31af7Sopenharmony_ci
409e5c31af7Sopenharmony_ciTestInstance* DataSpillTestCase::createInstance (Context& context) const
410e5c31af7Sopenharmony_ci{
411e5c31af7Sopenharmony_ci	return new DataSpillTestInstance(context, m_params);
412e5c31af7Sopenharmony_ci}
413e5c31af7Sopenharmony_ci
414e5c31af7Sopenharmony_ciDataSpillTestInstance::DataSpillTestInstance (Context& context, const TestParams& testParams)
415e5c31af7Sopenharmony_ci	: vkt::TestInstance	(context)
416e5c31af7Sopenharmony_ci	, m_params			(testParams)
417e5c31af7Sopenharmony_ci{
418e5c31af7Sopenharmony_ci}
419e5c31af7Sopenharmony_ci
420e5c31af7Sopenharmony_ci// General checks for all tests.
421e5c31af7Sopenharmony_civoid commonCheckSupport (Context& context)
422e5c31af7Sopenharmony_ci{
423e5c31af7Sopenharmony_ci	context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
424e5c31af7Sopenharmony_ci	context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
425e5c31af7Sopenharmony_ci
426e5c31af7Sopenharmony_ci	const auto& rtFeatures = context.getRayTracingPipelineFeatures();
427e5c31af7Sopenharmony_ci	if (!rtFeatures.rayTracingPipeline)
428e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Ray Tracing pipelines not supported");
429e5c31af7Sopenharmony_ci
430e5c31af7Sopenharmony_ci	const auto& asFeatures = context.getAccelerationStructureFeatures();
431e5c31af7Sopenharmony_ci	if (!asFeatures.accelerationStructure)
432e5c31af7Sopenharmony_ci		TCU_FAIL("VK_KHR_acceleration_structure supported without accelerationStructure support");
433e5c31af7Sopenharmony_ci
434e5c31af7Sopenharmony_ci}
435e5c31af7Sopenharmony_ci
436e5c31af7Sopenharmony_civoid DataSpillTestCase::checkSupport (Context& context) const
437e5c31af7Sopenharmony_ci{
438e5c31af7Sopenharmony_ci	// General checks first.
439e5c31af7Sopenharmony_ci	commonCheckSupport(context);
440e5c31af7Sopenharmony_ci
441e5c31af7Sopenharmony_ci	const auto& features			= context.getDeviceFeatures();
442e5c31af7Sopenharmony_ci	const auto& featuresStorage16	= context.get16BitStorageFeatures();
443e5c31af7Sopenharmony_ci	const auto& featuresF16I8		= context.getShaderFloat16Int8Features();
444e5c31af7Sopenharmony_ci	const auto& featuresStorage8	= context.get8BitStorageFeatures();
445e5c31af7Sopenharmony_ci
446e5c31af7Sopenharmony_ci	if (m_params.dataType == DataType::INT64 || m_params.dataType == DataType::UINT64)
447e5c31af7Sopenharmony_ci	{
448e5c31af7Sopenharmony_ci		if (!features.shaderInt64)
449e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "64-bit integers not supported");
450e5c31af7Sopenharmony_ci	}
451e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::INT16 || m_params.dataType == DataType::UINT16)
452e5c31af7Sopenharmony_ci	{
453e5c31af7Sopenharmony_ci		context.requireDeviceFunctionality("VK_KHR_16bit_storage");
454e5c31af7Sopenharmony_ci
455e5c31af7Sopenharmony_ci		if (!features.shaderInt16)
456e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "16-bit integers not supported");
457e5c31af7Sopenharmony_ci
458e5c31af7Sopenharmony_ci		if (!featuresStorage16.storageBuffer16BitAccess)
459e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "16-bit storage buffer access not supported");
460e5c31af7Sopenharmony_ci	}
461e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::INT8 || m_params.dataType == DataType::UINT8)
462e5c31af7Sopenharmony_ci	{
463e5c31af7Sopenharmony_ci		context.requireDeviceFunctionality("VK_KHR_shader_float16_int8");
464e5c31af7Sopenharmony_ci		context.requireDeviceFunctionality("VK_KHR_8bit_storage");
465e5c31af7Sopenharmony_ci
466e5c31af7Sopenharmony_ci		if (!featuresF16I8.shaderInt8)
467e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "8-bit integers not supported");
468e5c31af7Sopenharmony_ci
469e5c31af7Sopenharmony_ci		if (!featuresStorage8.storageBuffer8BitAccess)
470e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "8-bit storage buffer access not supported");
471e5c31af7Sopenharmony_ci	}
472e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::FLOAT64)
473e5c31af7Sopenharmony_ci	{
474e5c31af7Sopenharmony_ci		if (!features.shaderFloat64)
475e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "64-bit floats not supported");
476e5c31af7Sopenharmony_ci	}
477e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::FLOAT16)
478e5c31af7Sopenharmony_ci	{
479e5c31af7Sopenharmony_ci		context.requireDeviceFunctionality("VK_KHR_shader_float16_int8");
480e5c31af7Sopenharmony_ci		context.requireDeviceFunctionality("VK_KHR_16bit_storage");
481e5c31af7Sopenharmony_ci
482e5c31af7Sopenharmony_ci		if (!featuresF16I8.shaderFloat16)
483e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "16-bit floats not supported");
484e5c31af7Sopenharmony_ci
485e5c31af7Sopenharmony_ci		if (!featuresStorage16.storageBuffer16BitAccess)
486e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "16-bit storage buffer access not supported");
487e5c31af7Sopenharmony_ci	}
488e5c31af7Sopenharmony_ci	else if (samplersNeeded(m_params.dataType))
489e5c31af7Sopenharmony_ci	{
490e5c31af7Sopenharmony_ci		context.requireDeviceFunctionality("VK_EXT_descriptor_indexing");
491e5c31af7Sopenharmony_ci		const auto indexingFeatures = context.getDescriptorIndexingFeatures();
492e5c31af7Sopenharmony_ci		if (!indexingFeatures.shaderSampledImageArrayNonUniformIndexing)
493e5c31af7Sopenharmony_ci			TCU_THROW(NotSupportedError, "No support for non-uniform sampled image arrays");
494e5c31af7Sopenharmony_ci	}
495e5c31af7Sopenharmony_ci}
496e5c31af7Sopenharmony_ci
497e5c31af7Sopenharmony_civoid DataSpillTestCase::initPrograms (vk::SourceCollections& programCollection) const
498e5c31af7Sopenharmony_ci{
499e5c31af7Sopenharmony_ci	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
500e5c31af7Sopenharmony_ci	const vk::SpirVAsmBuildOptions	spvBuildOptions	(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true);
501e5c31af7Sopenharmony_ci
502e5c31af7Sopenharmony_ci	std::ostringstream spvTemplateStream;
503e5c31af7Sopenharmony_ci
504e5c31af7Sopenharmony_ci	// This SPIR-V template will be used to generate shaders for different
505e5c31af7Sopenharmony_ci	// stages (raygen, callable, etc). The basic mechanism uses 3 SSBOs: one
506e5c31af7Sopenharmony_ci	// used strictly as an input, one to write the check result, and one to
507e5c31af7Sopenharmony_ci	// verify the shader call has taken place. The latter two SSBOs contain just
508e5c31af7Sopenharmony_ci	// a single uint, but the input SSBO typically contains other type of data
509e5c31af7Sopenharmony_ci	// that will be filled from the test instance with predetermined values. The
510e5c31af7Sopenharmony_ci	// shader will expect this data to have specific values that can be combined
511e5c31af7Sopenharmony_ci	// some way to give an expected result (e.g. by adding the 4 components if
512e5c31af7Sopenharmony_ci	// it's a vec4). This result will be used in the shader call to make sure
513e5c31af7Sopenharmony_ci	// input values are read *before* the call. After the shader call has taken
514e5c31af7Sopenharmony_ci	// place, the shader will attempt to read the input buffer again and verify
515e5c31af7Sopenharmony_ci	// the value is still correct and matches the previous one. If the result
516e5c31af7Sopenharmony_ci	// matches, it will write a confirmation value in the check buffer. In the
517e5c31af7Sopenharmony_ci	// mean time, the callee will write a confirmation value in the callee
518e5c31af7Sopenharmony_ci	// buffer to verify the shader call took place.
519e5c31af7Sopenharmony_ci	//
520e5c31af7Sopenharmony_ci	// Some test variants use samplers, images or sampled images. These need
521e5c31af7Sopenharmony_ci	// additional bindings of different types and the interesting value is
522e5c31af7Sopenharmony_ci	// typically placed in the image instead of the input buffer, while the
523e5c31af7Sopenharmony_ci	// input buffer is used for sampling coordinates instead.
524e5c31af7Sopenharmony_ci	//
525e5c31af7Sopenharmony_ci	// Some important SPIR-V template variables:
526e5c31af7Sopenharmony_ci	//
527e5c31af7Sopenharmony_ci	// - INPUT_BUFFER_VALUE_TYPE will contain the type of input buffer data.
528e5c31af7Sopenharmony_ci	// - CALC_ZERO_FOR_CALLABLE is expected to contain instructions that will
529e5c31af7Sopenharmony_ci	//   calculate a value of zero to be used in the shader call instruction.
530e5c31af7Sopenharmony_ci	//   This value should be derived from the input data.
531e5c31af7Sopenharmony_ci	// - CALL_STATEMENTS will contain the shader call instructions.
532e5c31af7Sopenharmony_ci	// - CALC_EQUAL_STATEMENT is expected to contain instructions that will
533e5c31af7Sopenharmony_ci	//   set %equal to true as a %bool if the before- and after- data match.
534e5c31af7Sopenharmony_ci	//
535e5c31af7Sopenharmony_ci	// - %input_val_ptr contains the pointer to the input value.
536e5c31af7Sopenharmony_ci	// - %input_val_before contains the value read before the call.
537e5c31af7Sopenharmony_ci	// - %input_val_after contains the value read after the call.
538e5c31af7Sopenharmony_ci
539e5c31af7Sopenharmony_ci	spvTemplateStream
540e5c31af7Sopenharmony_ci		<< "                                  OpCapability RayTracingKHR\n"
541e5c31af7Sopenharmony_ci		<< "${EXTRA_CAPABILITIES}"
542e5c31af7Sopenharmony_ci		<< "                                  OpExtension \"SPV_KHR_ray_tracing\"\n"
543e5c31af7Sopenharmony_ci		<< "${EXTRA_EXTENSIONS}"
544e5c31af7Sopenharmony_ci		<< "                                  OpMemoryModel Logical GLSL450\n"
545e5c31af7Sopenharmony_ci		<< "                                  OpEntryPoint ${ENTRY_POINT} %main \"main\" %topLevelAS %calleeBuffer %outputBuffer %inputBuffer${MAIN_INTERFACE_EXTRAS}\n"
546e5c31af7Sopenharmony_ci		<< "${INTERFACE_DECORATIONS}"
547e5c31af7Sopenharmony_ci		<< "                                  OpMemberDecorate %InputBlock 0 Offset 0\n"
548e5c31af7Sopenharmony_ci		<< "                                  OpDecorate %InputBlock Block\n"
549e5c31af7Sopenharmony_ci		<< "                                  OpDecorate %inputBuffer DescriptorSet 0\n"
550e5c31af7Sopenharmony_ci		<< "                                  OpDecorate %inputBuffer Binding 3\n"
551e5c31af7Sopenharmony_ci		<< "                                  OpMemberDecorate %OutputBlock 0 Offset 0\n"
552e5c31af7Sopenharmony_ci		<< "                                  OpDecorate %OutputBlock Block\n"
553e5c31af7Sopenharmony_ci		<< "                                  OpDecorate %outputBuffer DescriptorSet 0\n"
554e5c31af7Sopenharmony_ci		<< "                                  OpDecorate %outputBuffer Binding 2\n"
555e5c31af7Sopenharmony_ci		<< "                                  OpMemberDecorate %CalleeBlock 0 Offset 0\n"
556e5c31af7Sopenharmony_ci		<< "                                  OpDecorate %CalleeBlock Block\n"
557e5c31af7Sopenharmony_ci		<< "                                  OpDecorate %calleeBuffer DescriptorSet 0\n"
558e5c31af7Sopenharmony_ci		<< "                                  OpDecorate %calleeBuffer Binding 1\n"
559e5c31af7Sopenharmony_ci		<< "                                  OpDecorate %topLevelAS DescriptorSet 0\n"
560e5c31af7Sopenharmony_ci		<< "                                  OpDecorate %topLevelAS Binding 0\n"
561e5c31af7Sopenharmony_ci		<< "${EXTRA_BINDINGS}"
562e5c31af7Sopenharmony_ci		<< "                          %void = OpTypeVoid\n"
563e5c31af7Sopenharmony_ci		<< "                     %void_func = OpTypeFunction %void\n"
564e5c31af7Sopenharmony_ci		<< "                           %int = OpTypeInt 32 1\n"
565e5c31af7Sopenharmony_ci		<< "                          %uint = OpTypeInt 32 0\n"
566e5c31af7Sopenharmony_ci		<< "                         %int_0 = OpConstant %int 0\n"
567e5c31af7Sopenharmony_ci		<< "                        %uint_0 = OpConstant %uint 0\n"
568e5c31af7Sopenharmony_ci		<< "                        %uint_1 = OpConstant %uint 1\n"
569e5c31af7Sopenharmony_ci		<< "                        %uint_2 = OpConstant %uint 2\n"
570e5c31af7Sopenharmony_ci		<< "                        %uint_3 = OpConstant %uint 3\n"
571e5c31af7Sopenharmony_ci		<< "                        %uint_4 = OpConstant %uint 4\n"
572e5c31af7Sopenharmony_ci		<< "                        %uint_5 = OpConstant %uint 5\n"
573e5c31af7Sopenharmony_ci		<< "                      %uint_255 = OpConstant %uint 255\n"
574e5c31af7Sopenharmony_ci		<< "                          %bool = OpTypeBool\n"
575e5c31af7Sopenharmony_ci		<< "                         %float = OpTypeFloat 32\n"
576e5c31af7Sopenharmony_ci		<< "                       %float_0 = OpConstant %float 0\n"
577e5c31af7Sopenharmony_ci		<< "                       %float_1 = OpConstant %float 1\n"
578e5c31af7Sopenharmony_ci		<< "                       %float_9 = OpConstant %float 9\n"
579e5c31af7Sopenharmony_ci		<< "                     %float_0_5 = OpConstant %float 0.5\n"
580e5c31af7Sopenharmony_ci		<< "                      %float_n1 = OpConstant %float -1\n"
581e5c31af7Sopenharmony_ci		<< "                       %v3float = OpTypeVector %float 3\n"
582e5c31af7Sopenharmony_ci		<< "                  %origin_const = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0\n"
583e5c31af7Sopenharmony_ci		<< "               %direction_const = OpConstantComposite %v3float %float_0 %float_0 %float_n1\n"
584e5c31af7Sopenharmony_ci		<< "${EXTRA_TYPES_AND_CONSTANTS}"
585e5c31af7Sopenharmony_ci		<< "                 %data_func_ptr = OpTypePointer Function ${INPUT_BUFFER_VALUE_TYPE}\n"
586e5c31af7Sopenharmony_ci		<< "${INTERFACE_TYPES_AND_VARIABLES}"
587e5c31af7Sopenharmony_ci		<< "                    %InputBlock = OpTypeStruct ${INPUT_BUFFER_VALUE_TYPE}\n"
588e5c31af7Sopenharmony_ci		<< " %_ptr_StorageBuffer_InputBlock = OpTypePointer StorageBuffer %InputBlock\n"
589e5c31af7Sopenharmony_ci		<< "                   %inputBuffer = OpVariable %_ptr_StorageBuffer_InputBlock StorageBuffer\n"
590e5c31af7Sopenharmony_ci		<< "        %data_storagebuffer_ptr = OpTypePointer StorageBuffer ${INPUT_BUFFER_VALUE_TYPE}\n"
591e5c31af7Sopenharmony_ci		<< "                   %OutputBlock = OpTypeStruct %uint\n"
592e5c31af7Sopenharmony_ci		<< "%_ptr_StorageBuffer_OutputBlock = OpTypePointer StorageBuffer %OutputBlock\n"
593e5c31af7Sopenharmony_ci		<< "                  %outputBuffer = OpVariable %_ptr_StorageBuffer_OutputBlock StorageBuffer\n"
594e5c31af7Sopenharmony_ci		<< "       %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n"
595e5c31af7Sopenharmony_ci		<< "                   %CalleeBlock = OpTypeStruct %uint\n"
596e5c31af7Sopenharmony_ci		<< "%_ptr_StorageBuffer_CalleeBlock = OpTypePointer StorageBuffer %CalleeBlock\n"
597e5c31af7Sopenharmony_ci		<< "                  %calleeBuffer = OpVariable %_ptr_StorageBuffer_CalleeBlock StorageBuffer\n"
598e5c31af7Sopenharmony_ci		<< "                       %as_type = OpTypeAccelerationStructureKHR\n"
599e5c31af7Sopenharmony_ci		<< "        %as_uniformconstant_ptr = OpTypePointer UniformConstant %as_type\n"
600e5c31af7Sopenharmony_ci		<< "                    %topLevelAS = OpVariable %as_uniformconstant_ptr UniformConstant\n"
601e5c31af7Sopenharmony_ci		<< "${EXTRA_BINDING_VARIABLES}"
602e5c31af7Sopenharmony_ci		<< "                          %main = OpFunction %void None %void_func\n"
603e5c31af7Sopenharmony_ci		<< "                    %main_label = OpLabel\n"
604e5c31af7Sopenharmony_ci		<< "${EXTRA_FUNCTION_VARIABLES}"
605e5c31af7Sopenharmony_ci		<< "                 %input_val_ptr = OpAccessChain %data_storagebuffer_ptr %inputBuffer %int_0\n"
606e5c31af7Sopenharmony_ci		<< "                %output_val_ptr = OpAccessChain %_ptr_StorageBuffer_uint %outputBuffer %int_0\n"
607e5c31af7Sopenharmony_ci		// Note we use Volatile to load the input buffer value before and after the call statements.
608e5c31af7Sopenharmony_ci		<< "              %input_val_before = OpLoad ${INPUT_BUFFER_VALUE_TYPE} %input_val_ptr Volatile\n"
609e5c31af7Sopenharmony_ci		<< "${CALC_ZERO_FOR_CALLABLE}"
610e5c31af7Sopenharmony_ci		<< "${CALL_STATEMENTS}"
611e5c31af7Sopenharmony_ci		<< "               %input_val_after = OpLoad ${INPUT_BUFFER_VALUE_TYPE} %input_val_ptr Volatile\n"
612e5c31af7Sopenharmony_ci		<< "${CALC_EQUAL_STATEMENT}"
613e5c31af7Sopenharmony_ci		<< "                    %output_val = OpSelect %uint %equal %uint_1 %uint_0\n"
614e5c31af7Sopenharmony_ci		<< "                                  OpStore %output_val_ptr %output_val\n"
615e5c31af7Sopenharmony_ci		<< "                                  OpReturn\n"
616e5c31af7Sopenharmony_ci		<< "                                  OpFunctionEnd\n"
617e5c31af7Sopenharmony_ci		;
618e5c31af7Sopenharmony_ci
619e5c31af7Sopenharmony_ci	const tcu::StringTemplate spvTemplate (spvTemplateStream.str());
620e5c31af7Sopenharmony_ci
621e5c31af7Sopenharmony_ci	std::map<std::string, std::string>	subs;
622e5c31af7Sopenharmony_ci	std::string							componentTypeName;
623e5c31af7Sopenharmony_ci	std::string							opEqual;
624e5c31af7Sopenharmony_ci	const int							numComponents		= static_cast<int>(m_params.vectorType);
625e5c31af7Sopenharmony_ci	const auto							isArray				= (numComponents > static_cast<int>(VectorType::V4));
626e5c31af7Sopenharmony_ci	const auto							numComponentsStr	= de::toString(numComponents);
627e5c31af7Sopenharmony_ci
628e5c31af7Sopenharmony_ci	subs["EXTRA_CAPABILITIES"]			= "";
629e5c31af7Sopenharmony_ci	subs["EXTRA_EXTENSIONS"]			= "";
630e5c31af7Sopenharmony_ci	subs["EXTRA_TYPES_AND_CONSTANTS"]	= "";
631e5c31af7Sopenharmony_ci	subs["EXTRA_FUNCTION_VARIABLES"]	= "";
632e5c31af7Sopenharmony_ci	subs["EXTRA_BINDINGS"]				= "";
633e5c31af7Sopenharmony_ci	subs["EXTRA_BINDING_VARIABLES"]		= "";
634e5c31af7Sopenharmony_ci	subs["EXTRA_FUNCTIONS"]				= "";
635e5c31af7Sopenharmony_ci
636e5c31af7Sopenharmony_ci	// Take into account some of these substitutions will be updated after the if-block.
637e5c31af7Sopenharmony_ci
638e5c31af7Sopenharmony_ci	if (m_params.dataType == DataType::INT32)
639e5c31af7Sopenharmony_ci	{
640e5c31af7Sopenharmony_ci		componentTypeName = "int";
641e5c31af7Sopenharmony_ci
642e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%int";
643e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                        %int_37 = OpConstant %int 37\n";
644e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]		=	"                      %zero_int = OpISub %int %input_val_before %int_37\n"
645e5c31af7Sopenharmony_ci												"             %zero_for_callable = OpBitcast %uint %zero_int\n";
646e5c31af7Sopenharmony_ci	}
647e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::UINT32)
648e5c31af7Sopenharmony_ci	{
649e5c31af7Sopenharmony_ci		componentTypeName = "uint";
650e5c31af7Sopenharmony_ci
651e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%uint";
652e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                       %uint_37 = OpConstant %uint 37\n";
653e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]		=	"             %zero_for_callable = OpISub %uint %input_val_before %uint_37\n";
654e5c31af7Sopenharmony_ci	}
655e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::INT64)
656e5c31af7Sopenharmony_ci	{
657e5c31af7Sopenharmony_ci		componentTypeName = "long";
658e5c31af7Sopenharmony_ci
659e5c31af7Sopenharmony_ci		subs["EXTRA_CAPABILITIES"]			+=	"                                  OpCapability Int64\n";
660e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%long";
661e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                          %long = OpTypeInt 64 1\n"
662e5c31af7Sopenharmony_ci												"                       %long_37 = OpConstant %long 37\n";
663e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]		=	"                     %zero_long = OpISub %long %input_val_before %long_37\n"
664e5c31af7Sopenharmony_ci												"             %zero_for_callable = OpSConvert %uint %zero_long\n";
665e5c31af7Sopenharmony_ci	}
666e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::UINT64)
667e5c31af7Sopenharmony_ci	{
668e5c31af7Sopenharmony_ci		componentTypeName = "ulong";
669e5c31af7Sopenharmony_ci
670e5c31af7Sopenharmony_ci		subs["EXTRA_CAPABILITIES"]			+=	"                                  OpCapability Int64\n";
671e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%ulong";
672e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                         %ulong = OpTypeInt 64 0\n"
673e5c31af7Sopenharmony_ci												"                      %ulong_37 = OpConstant %ulong 37\n";
674e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]		=	"                    %zero_ulong = OpISub %ulong %input_val_before %ulong_37\n"
675e5c31af7Sopenharmony_ci												"             %zero_for_callable = OpUConvert %uint %zero_ulong\n";
676e5c31af7Sopenharmony_ci	}
677e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::INT16)
678e5c31af7Sopenharmony_ci	{
679e5c31af7Sopenharmony_ci		componentTypeName = "short";
680e5c31af7Sopenharmony_ci
681e5c31af7Sopenharmony_ci		subs["EXTRA_CAPABILITIES"]			+=	"                                  OpCapability Int16\n"
682e5c31af7Sopenharmony_ci												"                                  OpCapability StorageBuffer16BitAccess\n";
683e5c31af7Sopenharmony_ci		subs["EXTRA_EXTENSIONS"]			+=	"                                  OpExtension \"SPV_KHR_16bit_storage\"\n";
684e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%short";
685e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                         %short = OpTypeInt 16 1\n"
686e5c31af7Sopenharmony_ci												"                      %short_37 = OpConstant %short 37\n";
687e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]		=	"                    %zero_short = OpISub %short %input_val_before %short_37\n"
688e5c31af7Sopenharmony_ci												"             %zero_for_callable = OpSConvert %uint %zero_short\n";
689e5c31af7Sopenharmony_ci	}
690e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::UINT16)
691e5c31af7Sopenharmony_ci	{
692e5c31af7Sopenharmony_ci		componentTypeName = "ushort";
693e5c31af7Sopenharmony_ci
694e5c31af7Sopenharmony_ci		subs["EXTRA_CAPABILITIES"]			+=	"                                  OpCapability Int16\n"
695e5c31af7Sopenharmony_ci												"                                  OpCapability StorageBuffer16BitAccess\n";
696e5c31af7Sopenharmony_ci		subs["EXTRA_EXTENSIONS"]			+=	"                                  OpExtension \"SPV_KHR_16bit_storage\"\n";
697e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%ushort";
698e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                        %ushort = OpTypeInt 16 0\n"
699e5c31af7Sopenharmony_ci												"                     %ushort_37 = OpConstant %ushort 37\n";
700e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]		=	"                   %zero_ushort = OpISub %ushort %input_val_before %ushort_37\n"
701e5c31af7Sopenharmony_ci												"             %zero_for_callable = OpUConvert %uint %zero_ushort\n";
702e5c31af7Sopenharmony_ci	}
703e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::INT8)
704e5c31af7Sopenharmony_ci	{
705e5c31af7Sopenharmony_ci		componentTypeName = "char";
706e5c31af7Sopenharmony_ci
707e5c31af7Sopenharmony_ci		subs["EXTRA_CAPABILITIES"]			+=	"                                  OpCapability Int8\n"
708e5c31af7Sopenharmony_ci												"                                  OpCapability StorageBuffer8BitAccess\n";
709e5c31af7Sopenharmony_ci		subs["EXTRA_EXTENSIONS"]			+=	"                                  OpExtension \"SPV_KHR_8bit_storage\"\n";
710e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%char";
711e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                          %char = OpTypeInt 8 1\n"
712e5c31af7Sopenharmony_ci												"                       %char_37 = OpConstant %char 37\n";
713e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]		=	"                     %zero_char = OpISub %char %input_val_before %char_37\n"
714e5c31af7Sopenharmony_ci												"             %zero_for_callable = OpSConvert %uint %zero_char\n";
715e5c31af7Sopenharmony_ci	}
716e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::UINT8)
717e5c31af7Sopenharmony_ci	{
718e5c31af7Sopenharmony_ci		componentTypeName = "uchar";
719e5c31af7Sopenharmony_ci
720e5c31af7Sopenharmony_ci		subs["EXTRA_CAPABILITIES"]			+=	"                                  OpCapability Int8\n"
721e5c31af7Sopenharmony_ci												"                                  OpCapability StorageBuffer8BitAccess\n";
722e5c31af7Sopenharmony_ci		subs["EXTRA_EXTENSIONS"]			+=	"                                  OpExtension \"SPV_KHR_8bit_storage\"\n";
723e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%uchar";
724e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                         %uchar = OpTypeInt 8 0\n"
725e5c31af7Sopenharmony_ci												"                      %uchar_37 = OpConstant %uchar 37\n";
726e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]		=	"                    %zero_uchar = OpISub %uchar %input_val_before %uchar_37\n"
727e5c31af7Sopenharmony_ci												"             %zero_for_callable = OpUConvert %uint %zero_uchar\n";
728e5c31af7Sopenharmony_ci	}
729e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::FLOAT32)
730e5c31af7Sopenharmony_ci	{
731e5c31af7Sopenharmony_ci		componentTypeName = "float";
732e5c31af7Sopenharmony_ci
733e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%float";
734e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                      %float_37 = OpConstant %float 37\n";
735e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]		=	"                    %zero_float = OpFSub %float %input_val_before %float_37\n"
736e5c31af7Sopenharmony_ci												"             %zero_for_callable = OpConvertFToU %uint %zero_float\n";
737e5c31af7Sopenharmony_ci	}
738e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::FLOAT64)
739e5c31af7Sopenharmony_ci	{
740e5c31af7Sopenharmony_ci		componentTypeName = "double";
741e5c31af7Sopenharmony_ci
742e5c31af7Sopenharmony_ci		subs["EXTRA_CAPABILITIES"]			+=	"                                  OpCapability Float64\n";
743e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%double";
744e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                        %double = OpTypeFloat 64\n"
745e5c31af7Sopenharmony_ci												"                     %double_37 = OpConstant %double 37\n";
746e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]		=	"                   %zero_double = OpFSub %double %input_val_before %double_37\n"
747e5c31af7Sopenharmony_ci												"             %zero_for_callable = OpConvertFToU %uint %zero_double\n";
748e5c31af7Sopenharmony_ci	}
749e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::FLOAT16)
750e5c31af7Sopenharmony_ci	{
751e5c31af7Sopenharmony_ci		componentTypeName = "half";
752e5c31af7Sopenharmony_ci
753e5c31af7Sopenharmony_ci		subs["EXTRA_CAPABILITIES"]			+=	"                                  OpCapability Float16\n"
754e5c31af7Sopenharmony_ci												"                                  OpCapability StorageBuffer16BitAccess\n";
755e5c31af7Sopenharmony_ci		subs["EXTRA_EXTENSIONS"]			+=	"                                  OpExtension \"SPV_KHR_16bit_storage\"\n";
756e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%half";
757e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                          %half = OpTypeFloat 16\n"
758e5c31af7Sopenharmony_ci												"                       %half_37 = OpConstant %half 37\n";
759e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]		=	"                     %zero_half = OpFSub %half %input_val_before %half_37\n"
760e5c31af7Sopenharmony_ci												"             %zero_for_callable = OpConvertFToU %uint %zero_half\n";
761e5c31af7Sopenharmony_ci	}
762e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::STRUCT)
763e5c31af7Sopenharmony_ci	{
764e5c31af7Sopenharmony_ci		componentTypeName = "InputStruct";
765e5c31af7Sopenharmony_ci
766e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%InputStruct";
767e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                   %InputStruct = OpTypeStruct %uint %float\n"
768e5c31af7Sopenharmony_ci												"                      %float_37 = OpConstant %float 37\n"
769e5c31af7Sopenharmony_ci												"            %uint_part_ptr_type = OpTypePointer StorageBuffer %uint\n"
770e5c31af7Sopenharmony_ci												"           %float_part_ptr_type = OpTypePointer StorageBuffer %float\n"
771e5c31af7Sopenharmony_ci												"       %uint_part_func_ptr_type = OpTypePointer Function %uint\n"
772e5c31af7Sopenharmony_ci												"      %float_part_func_ptr_type = OpTypePointer Function %float\n"
773e5c31af7Sopenharmony_ci												"    %input_struct_func_ptr_type = OpTypePointer Function %InputStruct\n"
774e5c31af7Sopenharmony_ci												;
775e5c31af7Sopenharmony_ci		subs["INTERFACE_DECORATIONS"]		=	"                                  OpMemberDecorate %InputStruct 0 Offset 0\n"
776e5c31af7Sopenharmony_ci												"                                  OpMemberDecorate %InputStruct 1 Offset 4\n";
777e5c31af7Sopenharmony_ci
778e5c31af7Sopenharmony_ci		// Sum struct members, then substract constant and convert to uint.
779e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]		=	"                 %uint_part_ptr = OpAccessChain %uint_part_ptr_type %input_val_ptr %uint_0\n"
780e5c31af7Sopenharmony_ci												"                %float_part_ptr = OpAccessChain %float_part_ptr_type %input_val_ptr %uint_1\n"
781e5c31af7Sopenharmony_ci												"                     %uint_part = OpLoad %uint %uint_part_ptr\n"
782e5c31af7Sopenharmony_ci												"                    %float_part = OpLoad %float %float_part_ptr\n"
783e5c31af7Sopenharmony_ci												"                 %uint_as_float = OpConvertUToF %float %uint_part\n"
784e5c31af7Sopenharmony_ci												"                    %member_sum = OpFAdd %float %float_part %uint_as_float\n"
785e5c31af7Sopenharmony_ci												"                    %zero_float = OpFSub %float %member_sum %float_37\n"
786e5c31af7Sopenharmony_ci												"             %zero_for_callable = OpConvertFToU %uint %zero_float\n"
787e5c31af7Sopenharmony_ci												;
788e5c31af7Sopenharmony_ci	}
789e5c31af7Sopenharmony_ci	else if (samplersNeeded(m_params.dataType))
790e5c31af7Sopenharmony_ci	{
791e5c31af7Sopenharmony_ci		// These tests will use additional bindings as arrays of 2 elements:
792e5c31af7Sopenharmony_ci		// - 1 array of samplers.
793e5c31af7Sopenharmony_ci		// - 1 array of images.
794e5c31af7Sopenharmony_ci		// - 1 array of combined image samplers.
795e5c31af7Sopenharmony_ci		// Input values are typically used as texture coordinates (normally zeros)
796e5c31af7Sopenharmony_ci		// Pixels will contain the expected values instead of them being in the input buffer.
797e5c31af7Sopenharmony_ci
798e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%float";
799e5c31af7Sopenharmony_ci		subs["EXTRA_CAPABILITIES"]			+=	"                                  OpCapability SampledImageArrayNonUniformIndexing\n";
800e5c31af7Sopenharmony_ci		subs["EXTRA_EXTENSIONS"]			+=	"                                  OpExtension \"SPV_EXT_descriptor_indexing\"\n";
801e5c31af7Sopenharmony_ci		subs["MAIN_INTERFACE_EXTRAS"]		+=	" %sampledTexture %textureSampler %combinedImageSampler";
802e5c31af7Sopenharmony_ci		subs["EXTRA_BINDINGS"]				+=	"                                  OpDecorate %sampledTexture DescriptorSet 0\n"
803e5c31af7Sopenharmony_ci												"                                  OpDecorate %sampledTexture Binding 4\n"
804e5c31af7Sopenharmony_ci												"                                  OpDecorate %textureSampler DescriptorSet 0\n"
805e5c31af7Sopenharmony_ci												"                                  OpDecorate %textureSampler Binding 5\n"
806e5c31af7Sopenharmony_ci												"                                  OpDecorate %combinedImageSampler DescriptorSet 0\n"
807e5c31af7Sopenharmony_ci												"                                  OpDecorate %combinedImageSampler Binding 6\n";
808e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                       %uint_37 = OpConstant %uint 37\n"
809e5c31af7Sopenharmony_ci												"                        %v4uint = OpTypeVector %uint 4\n"
810e5c31af7Sopenharmony_ci												"                       %v2float = OpTypeVector %float 2\n"
811e5c31af7Sopenharmony_ci												"                    %image_type = OpTypeImage %uint 2D 0 0 0 1 Unknown\n"
812e5c31af7Sopenharmony_ci												"              %image_array_type = OpTypeArray %image_type %uint_2\n"
813e5c31af7Sopenharmony_ci												"  %image_array_type_uniform_ptr = OpTypePointer UniformConstant %image_array_type\n"
814e5c31af7Sopenharmony_ci												"        %image_type_uniform_ptr = OpTypePointer UniformConstant %image_type\n"
815e5c31af7Sopenharmony_ci												"                  %sampler_type = OpTypeSampler\n"
816e5c31af7Sopenharmony_ci												"            %sampler_array_type = OpTypeArray %sampler_type %uint_2\n"
817e5c31af7Sopenharmony_ci												"%sampler_array_type_uniform_ptr = OpTypePointer UniformConstant %sampler_array_type\n"
818e5c31af7Sopenharmony_ci												"      %sampler_type_uniform_ptr = OpTypePointer UniformConstant %sampler_type\n"
819e5c31af7Sopenharmony_ci												"            %sampled_image_type = OpTypeSampledImage %image_type\n"
820e5c31af7Sopenharmony_ci												"      %sampled_image_array_type = OpTypeArray %sampled_image_type %uint_2\n"
821e5c31af7Sopenharmony_ci												"%sampled_image_array_type_uniform_ptr = OpTypePointer UniformConstant %sampled_image_array_type\n"
822e5c31af7Sopenharmony_ci												"%sampled_image_type_uniform_ptr = OpTypePointer UniformConstant %sampled_image_type\n"
823e5c31af7Sopenharmony_ci												;
824e5c31af7Sopenharmony_ci		subs["EXTRA_BINDING_VARIABLES"]		+=	"                %sampledTexture = OpVariable %image_array_type_uniform_ptr UniformConstant\n"
825e5c31af7Sopenharmony_ci												"                %textureSampler = OpVariable %sampler_array_type_uniform_ptr UniformConstant\n"
826e5c31af7Sopenharmony_ci												"          %combinedImageSampler = OpVariable %sampled_image_array_type_uniform_ptr UniformConstant\n"
827e5c31af7Sopenharmony_ci												;
828e5c31af7Sopenharmony_ci
829e5c31af7Sopenharmony_ci		if (m_params.dataType == DataType::IMAGE || m_params.dataType == DataType::SAMPLER)
830e5c31af7Sopenharmony_ci		{
831e5c31af7Sopenharmony_ci			// Use the first sampler and sample from the first image.
832e5c31af7Sopenharmony_ci			subs["CALC_ZERO_FOR_CALLABLE"]	+=	"%image_0_ptr = OpAccessChain %image_type_uniform_ptr %sampledTexture %uint_0\n"
833e5c31af7Sopenharmony_ci												"%sampler_0_ptr = OpAccessChain %sampler_type_uniform_ptr %textureSampler %uint_0\n"
834e5c31af7Sopenharmony_ci												"%sampler_0 = OpLoad %sampler_type %sampler_0_ptr\n"
835e5c31af7Sopenharmony_ci												"%image_0 = OpLoad %image_type %image_0_ptr\n"
836e5c31af7Sopenharmony_ci												"%sampled_image_0 = OpSampledImage %sampled_image_type %image_0 %sampler_0\n"
837e5c31af7Sopenharmony_ci												"%texture_coords_0 = OpCompositeConstruct %v2float %input_val_before %input_val_before\n"
838e5c31af7Sopenharmony_ci												"%pixel_vec_0 = OpImageSampleExplicitLod %v4uint %sampled_image_0 %texture_coords_0 Lod|ZeroExtend %float_0\n"
839e5c31af7Sopenharmony_ci												"%pixel_0 = OpCompositeExtract %uint %pixel_vec_0 0\n"
840e5c31af7Sopenharmony_ci												"%zero_for_callable = OpISub %uint %pixel_0 %uint_37\n"
841e5c31af7Sopenharmony_ci												;
842e5c31af7Sopenharmony_ci		}
843e5c31af7Sopenharmony_ci		else if (m_params.dataType == DataType::SAMPLED_IMAGE)
844e5c31af7Sopenharmony_ci		{
845e5c31af7Sopenharmony_ci			// Use the first combined image sampler.
846e5c31af7Sopenharmony_ci			subs["CALC_ZERO_FOR_CALLABLE"]	+=	"%sampled_image_0_ptr = OpAccessChain %sampled_image_type_uniform_ptr %combinedImageSampler %uint_0\n"
847e5c31af7Sopenharmony_ci												"%sampled_image_0 = OpLoad %sampled_image_type %sampled_image_0_ptr\n"
848e5c31af7Sopenharmony_ci												"%texture_coords_0 = OpCompositeConstruct %v2float %input_val_before %input_val_before\n"
849e5c31af7Sopenharmony_ci												"%pixel_vec_0 = OpImageSampleExplicitLod %v4uint %sampled_image_0 %texture_coords_0 Lod|ZeroExtend %float_0\n"
850e5c31af7Sopenharmony_ci												"%pixel_0 = OpCompositeExtract %uint %pixel_vec_0 0\n"
851e5c31af7Sopenharmony_ci												"%zero_for_callable = OpISub %uint %pixel_0 %uint_37\n"
852e5c31af7Sopenharmony_ci												;
853e5c31af7Sopenharmony_ci		}
854e5c31af7Sopenharmony_ci		else if (m_params.dataType == DataType::PTR_IMAGE)
855e5c31af7Sopenharmony_ci		{
856e5c31af7Sopenharmony_ci			// We attempt to create the second pointer before the call.
857e5c31af7Sopenharmony_ci			subs["CALC_ZERO_FOR_CALLABLE"]		+=	"%image_0_ptr = OpAccessChain %image_type_uniform_ptr %sampledTexture %uint_0\n"
858e5c31af7Sopenharmony_ci													"%image_1_ptr = OpAccessChain %image_type_uniform_ptr %sampledTexture %uint_1\n"
859e5c31af7Sopenharmony_ci													"%image_0 = OpLoad %image_type %image_0_ptr\n"
860e5c31af7Sopenharmony_ci													"%sampler_0_ptr = OpAccessChain %sampler_type_uniform_ptr %textureSampler %uint_0\n"
861e5c31af7Sopenharmony_ci													"%sampler_0 = OpLoad %sampler_type %sampler_0_ptr\n"
862e5c31af7Sopenharmony_ci													"%sampled_image_0 = OpSampledImage %sampled_image_type %image_0 %sampler_0\n"
863e5c31af7Sopenharmony_ci													"%texture_coords_0 = OpCompositeConstruct %v2float %input_val_before %input_val_before\n"
864e5c31af7Sopenharmony_ci													"%pixel_vec_0 = OpImageSampleExplicitLod %v4uint %sampled_image_0 %texture_coords_0 Lod|ZeroExtend %float_0\n"
865e5c31af7Sopenharmony_ci													"%pixel_0 = OpCompositeExtract %uint %pixel_vec_0 0\n"
866e5c31af7Sopenharmony_ci													"%zero_for_callable = OpISub %uint %pixel_0 %uint_37\n"
867e5c31af7Sopenharmony_ci													;
868e5c31af7Sopenharmony_ci		}
869e5c31af7Sopenharmony_ci		else if (m_params.dataType == DataType::PTR_SAMPLER)
870e5c31af7Sopenharmony_ci		{
871e5c31af7Sopenharmony_ci			// We attempt to create the second pointer before the call.
872e5c31af7Sopenharmony_ci			subs["CALC_ZERO_FOR_CALLABLE"]		+=	"%sampler_0_ptr = OpAccessChain %sampler_type_uniform_ptr %textureSampler %uint_0\n"
873e5c31af7Sopenharmony_ci													"%sampler_1_ptr = OpAccessChain %sampler_type_uniform_ptr %textureSampler %uint_1\n"
874e5c31af7Sopenharmony_ci													"%sampler_0 = OpLoad %sampler_type %sampler_0_ptr\n"
875e5c31af7Sopenharmony_ci													"%image_0_ptr = OpAccessChain %image_type_uniform_ptr %sampledTexture %uint_0\n"
876e5c31af7Sopenharmony_ci													"%image_0 = OpLoad %image_type %image_0_ptr\n"
877e5c31af7Sopenharmony_ci													"%sampled_image_0 = OpSampledImage %sampled_image_type %image_0 %sampler_0\n"
878e5c31af7Sopenharmony_ci													"%texture_coords_0 = OpCompositeConstruct %v2float %input_val_before %input_val_before\n"
879e5c31af7Sopenharmony_ci													"%pixel_vec_0 = OpImageSampleExplicitLod %v4uint %sampled_image_0 %texture_coords_0 Lod|ZeroExtend %float_0\n"
880e5c31af7Sopenharmony_ci													"%pixel_0 = OpCompositeExtract %uint %pixel_vec_0 0\n"
881e5c31af7Sopenharmony_ci													"%zero_for_callable = OpISub %uint %pixel_0 %uint_37\n"
882e5c31af7Sopenharmony_ci													;
883e5c31af7Sopenharmony_ci		}
884e5c31af7Sopenharmony_ci		else if (m_params.dataType == DataType::PTR_SAMPLED_IMAGE)
885e5c31af7Sopenharmony_ci		{
886e5c31af7Sopenharmony_ci			// We attempt to create the second pointer before the call.
887e5c31af7Sopenharmony_ci			subs["CALC_ZERO_FOR_CALLABLE"]		+=	"%sampled_image_0_ptr = OpAccessChain %sampled_image_type_uniform_ptr %combinedImageSampler %uint_0\n"
888e5c31af7Sopenharmony_ci													"%sampled_image_1_ptr = OpAccessChain %sampled_image_type_uniform_ptr %combinedImageSampler %uint_1\n"
889e5c31af7Sopenharmony_ci													"%sampled_image_0 = OpLoad %sampled_image_type %sampled_image_0_ptr\n"
890e5c31af7Sopenharmony_ci													"%texture_coords_0 = OpCompositeConstruct %v2float %input_val_before %input_val_before\n"
891e5c31af7Sopenharmony_ci													"%pixel_vec_0 = OpImageSampleExplicitLod %v4uint %sampled_image_0 %texture_coords_0 Lod|ZeroExtend %float_0\n"
892e5c31af7Sopenharmony_ci													"%pixel_0 = OpCompositeExtract %uint %pixel_vec_0 0\n"
893e5c31af7Sopenharmony_ci													"%zero_for_callable = OpISub %uint %pixel_0 %uint_37\n"
894e5c31af7Sopenharmony_ci													;
895e5c31af7Sopenharmony_ci		}
896e5c31af7Sopenharmony_ci		else
897e5c31af7Sopenharmony_ci		{
898e5c31af7Sopenharmony_ci			DE_ASSERT(false);
899e5c31af7Sopenharmony_ci		}
900e5c31af7Sopenharmony_ci	}
901e5c31af7Sopenharmony_ci	else if (storageImageNeeded(m_params.dataType))
902e5c31af7Sopenharmony_ci	{
903e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%int";
904e5c31af7Sopenharmony_ci		subs["MAIN_INTERFACE_EXTRAS"]		+=	" %storageImage";
905e5c31af7Sopenharmony_ci		subs["EXTRA_BINDINGS"]				+=	"                                  OpDecorate %storageImage DescriptorSet 0\n"
906e5c31af7Sopenharmony_ci												"                                  OpDecorate %storageImage Binding 4\n"
907e5c31af7Sopenharmony_ci												;
908e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                       %uint_37 = OpConstant %uint 37\n"
909e5c31af7Sopenharmony_ci												"                         %v2int = OpTypeVector %int 2\n"
910e5c31af7Sopenharmony_ci												"                    %image_type = OpTypeImage %uint 2D 0 0 0 2 R32ui\n"
911e5c31af7Sopenharmony_ci												"        %image_type_uniform_ptr = OpTypePointer UniformConstant %image_type\n"
912e5c31af7Sopenharmony_ci												"                  %uint_img_ptr = OpTypePointer Image %uint\n"
913e5c31af7Sopenharmony_ci												;
914e5c31af7Sopenharmony_ci		subs["EXTRA_BINDING_VARIABLES"]		+=	"                  %storageImage = OpVariable %image_type_uniform_ptr UniformConstant\n"
915e5c31af7Sopenharmony_ci												;
916e5c31af7Sopenharmony_ci
917e5c31af7Sopenharmony_ci		// Load value from the image, expecting it to be 37 and swapping it with 5.
918e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]	+=	"%coords = OpCompositeConstruct %v2int %input_val_before %input_val_before\n"
919e5c31af7Sopenharmony_ci											"%texel_ptr = OpImageTexelPointer %uint_img_ptr %storageImage %coords %uint_0\n"
920e5c31af7Sopenharmony_ci											"%texel_value = OpAtomicCompareExchange %uint %texel_ptr %uint_1 %uint_0 %uint_0 %uint_5 %uint_37\n"
921e5c31af7Sopenharmony_ci											"%zero_for_callable = OpISub %uint %texel_value %uint_37\n"
922e5c31af7Sopenharmony_ci											;
923e5c31af7Sopenharmony_ci	}
924e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::OP_NULL)
925e5c31af7Sopenharmony_ci	{
926e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%uint";
927e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                       %uint_37 = OpConstant %uint 37\n"
928e5c31af7Sopenharmony_ci												"                 %constant_null = OpConstantNull %uint\n"
929e5c31af7Sopenharmony_ci												;
930e5c31af7Sopenharmony_ci
931e5c31af7Sopenharmony_ci		// Create a local copy of the null constant global object to work with it.
932e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]	+=	"%constant_null_copy = OpCopyObject %uint %constant_null\n"
933e5c31af7Sopenharmony_ci											"%is_37_before = OpIEqual %bool %input_val_before %uint_37\n"
934e5c31af7Sopenharmony_ci											"%zero_for_callable = OpSelect %uint %is_37_before %constant_null_copy %uint_5\n"
935e5c31af7Sopenharmony_ci											;
936e5c31af7Sopenharmony_ci	}
937e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::OP_UNDEF)
938e5c31af7Sopenharmony_ci	{
939e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%uint";
940e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"                       %uint_37 = OpConstant %uint 37\n"
941e5c31af7Sopenharmony_ci												;
942e5c31af7Sopenharmony_ci
943e5c31af7Sopenharmony_ci		// Extract an undef value and write it to the output buffer to make sure it's used before the call. The value will be overwritten later.
944e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"]	+=	"%undef_var = OpUndef %uint\n"
945e5c31af7Sopenharmony_ci											"%undef_val_before = OpCopyObject %uint %undef_var\n"
946e5c31af7Sopenharmony_ci											"OpStore %output_val_ptr %undef_val_before Volatile\n"
947e5c31af7Sopenharmony_ci											"%zero_for_callable = OpISub %uint %uint_37 %input_val_before\n"
948e5c31af7Sopenharmony_ci											;
949e5c31af7Sopenharmony_ci	}
950e5c31af7Sopenharmony_ci	else
951e5c31af7Sopenharmony_ci	{
952e5c31af7Sopenharmony_ci		DE_ASSERT(false);
953e5c31af7Sopenharmony_ci	}
954e5c31af7Sopenharmony_ci
955e5c31af7Sopenharmony_ci	// Comparison statement for data before and after the call.
956e5c31af7Sopenharmony_ci	switch (m_params.dataType)
957e5c31af7Sopenharmony_ci	{
958e5c31af7Sopenharmony_ci	case DataType::INT32:
959e5c31af7Sopenharmony_ci	case DataType::UINT32:
960e5c31af7Sopenharmony_ci	case DataType::INT64:
961e5c31af7Sopenharmony_ci	case DataType::UINT64:
962e5c31af7Sopenharmony_ci	case DataType::INT16:
963e5c31af7Sopenharmony_ci	case DataType::UINT16:
964e5c31af7Sopenharmony_ci	case DataType::INT8:
965e5c31af7Sopenharmony_ci	case DataType::UINT8:
966e5c31af7Sopenharmony_ci		opEqual = "OpIEqual";
967e5c31af7Sopenharmony_ci		break;
968e5c31af7Sopenharmony_ci	case DataType::FLOAT32:
969e5c31af7Sopenharmony_ci	case DataType::FLOAT64:
970e5c31af7Sopenharmony_ci	case DataType::FLOAT16:
971e5c31af7Sopenharmony_ci		opEqual = "OpFOrdEqual";
972e5c31af7Sopenharmony_ci		break;
973e5c31af7Sopenharmony_ci	case DataType::STRUCT:
974e5c31af7Sopenharmony_ci	case DataType::IMAGE:
975e5c31af7Sopenharmony_ci	case DataType::SAMPLER:
976e5c31af7Sopenharmony_ci	case DataType::SAMPLED_IMAGE:
977e5c31af7Sopenharmony_ci	case DataType::PTR_IMAGE:
978e5c31af7Sopenharmony_ci	case DataType::PTR_SAMPLER:
979e5c31af7Sopenharmony_ci	case DataType::PTR_SAMPLED_IMAGE:
980e5c31af7Sopenharmony_ci	case DataType::PTR_TEXEL:
981e5c31af7Sopenharmony_ci	case DataType::OP_NULL:
982e5c31af7Sopenharmony_ci	case DataType::OP_UNDEF:
983e5c31af7Sopenharmony_ci		// These needs special code for the comparison.
984e5c31af7Sopenharmony_ci		opEqual = "INVALID";
985e5c31af7Sopenharmony_ci		break;
986e5c31af7Sopenharmony_ci	default:
987e5c31af7Sopenharmony_ci		DE_ASSERT(false);
988e5c31af7Sopenharmony_ci		break;
989e5c31af7Sopenharmony_ci	}
990e5c31af7Sopenharmony_ci
991e5c31af7Sopenharmony_ci	if (m_params.dataType == DataType::STRUCT)
992e5c31af7Sopenharmony_ci	{
993e5c31af7Sopenharmony_ci		// We need to store the before and after values in a variable in order to be able to access each member individually without accessing the StorageBuffer again.
994e5c31af7Sopenharmony_ci		subs["EXTRA_FUNCTION_VARIABLES"]	=	"         %input_val_func_before = OpVariable %input_struct_func_ptr_type Function\n"
995e5c31af7Sopenharmony_ci												"          %input_val_func_after = OpVariable %input_struct_func_ptr_type Function\n"
996e5c31af7Sopenharmony_ci												;
997e5c31af7Sopenharmony_ci		subs["CALC_EQUAL_STATEMENT"]		=	"                                  OpStore %input_val_func_before %input_val_before\n"
998e5c31af7Sopenharmony_ci												"                                  OpStore %input_val_func_after %input_val_after\n"
999e5c31af7Sopenharmony_ci												"     %uint_part_func_before_ptr = OpAccessChain %uint_part_func_ptr_type %input_val_func_before %uint_0\n"
1000e5c31af7Sopenharmony_ci												"    %float_part_func_before_ptr = OpAccessChain %float_part_func_ptr_type %input_val_func_before %uint_1\n"
1001e5c31af7Sopenharmony_ci												"      %uint_part_func_after_ptr = OpAccessChain %uint_part_func_ptr_type %input_val_func_after %uint_0\n"
1002e5c31af7Sopenharmony_ci												"     %float_part_func_after_ptr = OpAccessChain %float_part_func_ptr_type %input_val_func_after %uint_1\n"
1003e5c31af7Sopenharmony_ci												"              %uint_part_before = OpLoad %uint %uint_part_func_before_ptr\n"
1004e5c31af7Sopenharmony_ci												"             %float_part_before = OpLoad %float %float_part_func_before_ptr\n"
1005e5c31af7Sopenharmony_ci												"               %uint_part_after = OpLoad %uint %uint_part_func_after_ptr\n"
1006e5c31af7Sopenharmony_ci												"              %float_part_after = OpLoad %float %float_part_func_after_ptr\n"
1007e5c31af7Sopenharmony_ci												"                    %uint_equal = OpIEqual %bool %uint_part_before %uint_part_after\n"
1008e5c31af7Sopenharmony_ci												"                   %float_equal = OpFOrdEqual %bool %float_part_before %float_part_after\n"
1009e5c31af7Sopenharmony_ci												"                         %equal = OpLogicalAnd %bool %uint_equal %float_equal\n"
1010e5c31af7Sopenharmony_ci												;
1011e5c31af7Sopenharmony_ci	}
1012e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::IMAGE)
1013e5c31af7Sopenharmony_ci	{
1014e5c31af7Sopenharmony_ci		// Use the same image and the second sampler with different coordinates (actually the same).
1015e5c31af7Sopenharmony_ci		subs["CALC_EQUAL_STATEMENT"]	+=	"%sampler_1_ptr = OpAccessChain %sampler_type_uniform_ptr %textureSampler %uint_1\n"
1016e5c31af7Sopenharmony_ci											"%sampler_1 = OpLoad %sampler_type %sampler_1_ptr\n"
1017e5c31af7Sopenharmony_ci											"%sampled_image_1 = OpSampledImage %sampled_image_type %image_0 %sampler_1\n"
1018e5c31af7Sopenharmony_ci											"%texture_coords_1 = OpCompositeConstruct %v2float %input_val_after %input_val_after\n"
1019e5c31af7Sopenharmony_ci											"%pixel_vec_1 = OpImageSampleExplicitLod %v4uint %sampled_image_1 %texture_coords_1 Lod|ZeroExtend %float_0\n"
1020e5c31af7Sopenharmony_ci											"%pixel_1 = OpCompositeExtract %uint %pixel_vec_1 0\n"
1021e5c31af7Sopenharmony_ci											"%equal = OpIEqual %bool %pixel_0 %pixel_1\n"
1022e5c31af7Sopenharmony_ci											;
1023e5c31af7Sopenharmony_ci	}
1024e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::SAMPLER)
1025e5c31af7Sopenharmony_ci	{
1026e5c31af7Sopenharmony_ci		// Use the same sampler and sample from the second image with different coordinates (but actually the same).
1027e5c31af7Sopenharmony_ci		subs["CALC_EQUAL_STATEMENT"]	+=	"%image_1_ptr = OpAccessChain %image_type_uniform_ptr %sampledTexture %uint_1\n"
1028e5c31af7Sopenharmony_ci											"%image_1 = OpLoad %image_type %image_1_ptr\n"
1029e5c31af7Sopenharmony_ci											"%sampled_image_1 = OpSampledImage %sampled_image_type %image_1 %sampler_0\n"
1030e5c31af7Sopenharmony_ci											"%texture_coords_1 = OpCompositeConstruct %v2float %input_val_after %input_val_after\n"
1031e5c31af7Sopenharmony_ci											"%pixel_vec_1 = OpImageSampleExplicitLod %v4uint %sampled_image_1 %texture_coords_1 Lod|ZeroExtend %float_0\n"
1032e5c31af7Sopenharmony_ci											"%pixel_1 = OpCompositeExtract %uint %pixel_vec_1 0\n"
1033e5c31af7Sopenharmony_ci											"%equal = OpIEqual %bool %pixel_0 %pixel_1\n"
1034e5c31af7Sopenharmony_ci											;
1035e5c31af7Sopenharmony_ci	}
1036e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::SAMPLED_IMAGE)
1037e5c31af7Sopenharmony_ci	{
1038e5c31af7Sopenharmony_ci		// Reuse the same combined image sampler with different coordinates (actually the same).
1039e5c31af7Sopenharmony_ci		subs["CALC_EQUAL_STATEMENT"]	+=	"%texture_coords_1 = OpCompositeConstruct %v2float %input_val_after %input_val_after\n"
1040e5c31af7Sopenharmony_ci											"%pixel_vec_1 = OpImageSampleExplicitLod %v4uint %sampled_image_0 %texture_coords_1 Lod|ZeroExtend %float_0\n"
1041e5c31af7Sopenharmony_ci											"%pixel_1 = OpCompositeExtract %uint %pixel_vec_1 0\n"
1042e5c31af7Sopenharmony_ci											"%equal = OpIEqual %bool %pixel_0 %pixel_1\n"
1043e5c31af7Sopenharmony_ci											;
1044e5c31af7Sopenharmony_ci	}
1045e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::PTR_IMAGE)
1046e5c31af7Sopenharmony_ci	{
1047e5c31af7Sopenharmony_ci		// We attempt to use the second pointer only after the call.
1048e5c31af7Sopenharmony_ci		subs["CALC_EQUAL_STATEMENT"]	+=	"%image_1 = OpLoad %image_type %image_1_ptr\n"
1049e5c31af7Sopenharmony_ci											"%sampled_image_1 = OpSampledImage %sampled_image_type %image_1 %sampler_0\n"
1050e5c31af7Sopenharmony_ci											"%texture_coords_1 = OpCompositeConstruct %v2float %input_val_after %input_val_after\n"
1051e5c31af7Sopenharmony_ci											"%pixel_vec_1 = OpImageSampleExplicitLod %v4uint %sampled_image_1 %texture_coords_1 Lod|ZeroExtend %float_0\n"
1052e5c31af7Sopenharmony_ci											"%pixel_1 = OpCompositeExtract %uint %pixel_vec_1 0\n"
1053e5c31af7Sopenharmony_ci											"%equal = OpIEqual %bool %pixel_0 %pixel_1\n"
1054e5c31af7Sopenharmony_ci											;
1055e5c31af7Sopenharmony_ci
1056e5c31af7Sopenharmony_ci	}
1057e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::PTR_SAMPLER)
1058e5c31af7Sopenharmony_ci	{
1059e5c31af7Sopenharmony_ci		// We attempt to use the second pointer only after the call.
1060e5c31af7Sopenharmony_ci		subs["CALC_EQUAL_STATEMENT"]	+=	"%sampler_1 = OpLoad %sampler_type %sampler_1_ptr\n"
1061e5c31af7Sopenharmony_ci											"%sampled_image_1 = OpSampledImage %sampled_image_type %image_0 %sampler_1\n"
1062e5c31af7Sopenharmony_ci											"%texture_coords_1 = OpCompositeConstruct %v2float %input_val_after %input_val_after\n"
1063e5c31af7Sopenharmony_ci											"%pixel_vec_1 = OpImageSampleExplicitLod %v4uint %sampled_image_1 %texture_coords_1 Lod|ZeroExtend %float_0\n"
1064e5c31af7Sopenharmony_ci											"%pixel_1 = OpCompositeExtract %uint %pixel_vec_1 0\n"
1065e5c31af7Sopenharmony_ci											"%equal = OpIEqual %bool %pixel_0 %pixel_1\n"
1066e5c31af7Sopenharmony_ci											;
1067e5c31af7Sopenharmony_ci	}
1068e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::PTR_SAMPLED_IMAGE)
1069e5c31af7Sopenharmony_ci	{
1070e5c31af7Sopenharmony_ci		// We attempt to use the second pointer only after the call.
1071e5c31af7Sopenharmony_ci		subs["CALC_EQUAL_STATEMENT"]	+=	"%sampled_image_1 = OpLoad %sampled_image_type %sampled_image_1_ptr\n"
1072e5c31af7Sopenharmony_ci											"%texture_coords_1 = OpCompositeConstruct %v2float %input_val_after %input_val_after\n"
1073e5c31af7Sopenharmony_ci											"%pixel_vec_1 = OpImageSampleExplicitLod %v4uint %sampled_image_1 %texture_coords_1 Lod|ZeroExtend %float_0\n"
1074e5c31af7Sopenharmony_ci											"%pixel_1 = OpCompositeExtract %uint %pixel_vec_1 0\n"
1075e5c31af7Sopenharmony_ci											"%equal = OpIEqual %bool %pixel_0 %pixel_1\n"
1076e5c31af7Sopenharmony_ci											;
1077e5c31af7Sopenharmony_ci	}
1078e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::PTR_TEXEL)
1079e5c31af7Sopenharmony_ci	{
1080e5c31af7Sopenharmony_ci		// Check value 5 was stored properly.
1081e5c31af7Sopenharmony_ci		subs["CALC_EQUAL_STATEMENT"]	+=	"%stored_val = OpAtomicLoad %uint %texel_ptr %uint_1 %uint_0\n"
1082e5c31af7Sopenharmony_ci											"%equal = OpIEqual %bool %stored_val %uint_5\n"
1083e5c31af7Sopenharmony_ci											;
1084e5c31af7Sopenharmony_ci	}
1085e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::OP_NULL)
1086e5c31af7Sopenharmony_ci	{
1087e5c31af7Sopenharmony_ci		// Reuse the null constant after the call.
1088e5c31af7Sopenharmony_ci		subs["CALC_EQUAL_STATEMENT"]	+=	"%is_37_after = OpIEqual %bool %input_val_after %uint_37\n"
1089e5c31af7Sopenharmony_ci											"%writeback_val = OpSelect %uint %is_37_after %constant_null_copy %uint_5\n"
1090e5c31af7Sopenharmony_ci											"OpStore %input_val_ptr %writeback_val Volatile\n"
1091e5c31af7Sopenharmony_ci											"%readback_val = OpLoad %uint %input_val_ptr Volatile\n"
1092e5c31af7Sopenharmony_ci											"%equal = OpIEqual %bool %readback_val %uint_0\n"
1093e5c31af7Sopenharmony_ci											;
1094e5c31af7Sopenharmony_ci	}
1095e5c31af7Sopenharmony_ci	else if (m_params.dataType == DataType::OP_UNDEF)
1096e5c31af7Sopenharmony_ci	{
1097e5c31af7Sopenharmony_ci		// Extract another undef value and write it to the input buffer. It will not be checked later.
1098e5c31af7Sopenharmony_ci		subs["CALC_EQUAL_STATEMENT"]	+=	"%undef_val_after = OpCopyObject %uint %undef_var\n"
1099e5c31af7Sopenharmony_ci											"OpStore %input_val_ptr %undef_val_after Volatile\n"
1100e5c31af7Sopenharmony_ci											"%equal = OpIEqual %bool %input_val_after %input_val_before\n"
1101e5c31af7Sopenharmony_ci											;
1102e5c31af7Sopenharmony_ci	}
1103e5c31af7Sopenharmony_ci	else
1104e5c31af7Sopenharmony_ci	{
1105e5c31af7Sopenharmony_ci		subs["CALC_EQUAL_STATEMENT"]	+=	"                         %equal = " + opEqual + " %bool %input_val_before %input_val_after\n";
1106e5c31af7Sopenharmony_ci	}
1107e5c31af7Sopenharmony_ci
1108e5c31af7Sopenharmony_ci	// Modifications for vectors and arrays.
1109e5c31af7Sopenharmony_ci	if (numComponents > 1)
1110e5c31af7Sopenharmony_ci	{
1111e5c31af7Sopenharmony_ci		const std::string	vectorTypeName		= "v" + numComponentsStr + componentTypeName;
1112e5c31af7Sopenharmony_ci		const std::string	opType				= (isArray ? "OpTypeArray" : "OpTypeVector");
1113e5c31af7Sopenharmony_ci		const std::string	componentCountStr	= (isArray ? ("%uint_" + numComponentsStr) : numComponentsStr);
1114e5c31af7Sopenharmony_ci
1115e5c31af7Sopenharmony_ci		// Some extra types are needed.
1116e5c31af7Sopenharmony_ci		if (!(m_params.dataType == DataType::FLOAT32 && m_params.vectorType == VectorType::V3))
1117e5c31af7Sopenharmony_ci		{
1118e5c31af7Sopenharmony_ci			// Note: v3float is already defined in the shader by default.
1119e5c31af7Sopenharmony_ci			subs["EXTRA_TYPES_AND_CONSTANTS"] += "%" + vectorTypeName + " = " + opType + " %" + componentTypeName + " " + componentCountStr + "\n";
1120e5c31af7Sopenharmony_ci		}
1121e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"%v" + numComponentsStr + "bool = " + opType + " %bool " + componentCountStr + "\n";
1122e5c31af7Sopenharmony_ci		subs["EXTRA_TYPES_AND_CONSTANTS"]	+=	"%comp_ptr = OpTypePointer StorageBuffer %" + componentTypeName + "\n";
1123e5c31af7Sopenharmony_ci
1124e5c31af7Sopenharmony_ci		// The input value in the buffer has a different type.
1125e5c31af7Sopenharmony_ci		subs["INPUT_BUFFER_VALUE_TYPE"]		=	"%" + vectorTypeName;
1126e5c31af7Sopenharmony_ci
1127e5c31af7Sopenharmony_ci		// Overwrite the way we calculate the zero used in the call.
1128e5c31af7Sopenharmony_ci
1129e5c31af7Sopenharmony_ci		// Proper operations for adding, substracting and converting components.
1130e5c31af7Sopenharmony_ci		std::string opAdd;
1131e5c31af7Sopenharmony_ci		std::string opSub;
1132e5c31af7Sopenharmony_ci		std::string opConvert;
1133e5c31af7Sopenharmony_ci
1134e5c31af7Sopenharmony_ci		switch (m_params.dataType)
1135e5c31af7Sopenharmony_ci		{
1136e5c31af7Sopenharmony_ci		case DataType::INT32:
1137e5c31af7Sopenharmony_ci		case DataType::UINT32:
1138e5c31af7Sopenharmony_ci		case DataType::INT64:
1139e5c31af7Sopenharmony_ci		case DataType::UINT64:
1140e5c31af7Sopenharmony_ci		case DataType::INT16:
1141e5c31af7Sopenharmony_ci		case DataType::UINT16:
1142e5c31af7Sopenharmony_ci		case DataType::INT8:
1143e5c31af7Sopenharmony_ci		case DataType::UINT8:
1144e5c31af7Sopenharmony_ci			opAdd = "OpIAdd";
1145e5c31af7Sopenharmony_ci			opSub = "OpISub";
1146e5c31af7Sopenharmony_ci			break;
1147e5c31af7Sopenharmony_ci		case DataType::FLOAT32:
1148e5c31af7Sopenharmony_ci		case DataType::FLOAT64:
1149e5c31af7Sopenharmony_ci		case DataType::FLOAT16:
1150e5c31af7Sopenharmony_ci			opAdd = "OpFAdd";
1151e5c31af7Sopenharmony_ci			opSub = "OpFSub";
1152e5c31af7Sopenharmony_ci			break;
1153e5c31af7Sopenharmony_ci		default:
1154e5c31af7Sopenharmony_ci			DE_ASSERT(false);
1155e5c31af7Sopenharmony_ci			break;
1156e5c31af7Sopenharmony_ci		}
1157e5c31af7Sopenharmony_ci
1158e5c31af7Sopenharmony_ci		switch (m_params.dataType)
1159e5c31af7Sopenharmony_ci		{
1160e5c31af7Sopenharmony_ci		case DataType::UINT32:
1161e5c31af7Sopenharmony_ci			opConvert = "OpCopyObject";
1162e5c31af7Sopenharmony_ci			break;
1163e5c31af7Sopenharmony_ci		case DataType::INT32:
1164e5c31af7Sopenharmony_ci			opConvert = "OpBitcast";
1165e5c31af7Sopenharmony_ci			break;
1166e5c31af7Sopenharmony_ci		case DataType::INT64:
1167e5c31af7Sopenharmony_ci		case DataType::INT16:
1168e5c31af7Sopenharmony_ci		case DataType::INT8:
1169e5c31af7Sopenharmony_ci			opConvert = "OpSConvert";
1170e5c31af7Sopenharmony_ci			break;
1171e5c31af7Sopenharmony_ci		case DataType::UINT64:
1172e5c31af7Sopenharmony_ci		case DataType::UINT16:
1173e5c31af7Sopenharmony_ci		case DataType::UINT8:
1174e5c31af7Sopenharmony_ci			opConvert = "OpUConvert";
1175e5c31af7Sopenharmony_ci			break;
1176e5c31af7Sopenharmony_ci		case DataType::FLOAT32:
1177e5c31af7Sopenharmony_ci		case DataType::FLOAT64:
1178e5c31af7Sopenharmony_ci		case DataType::FLOAT16:
1179e5c31af7Sopenharmony_ci			opConvert = "OpConvertFToU";
1180e5c31af7Sopenharmony_ci			break;
1181e5c31af7Sopenharmony_ci		default:
1182e5c31af7Sopenharmony_ci			DE_ASSERT(false);
1183e5c31af7Sopenharmony_ci			break;
1184e5c31af7Sopenharmony_ci		}
1185e5c31af7Sopenharmony_ci
1186e5c31af7Sopenharmony_ci		std::ostringstream zeroForCallable;
1187e5c31af7Sopenharmony_ci
1188e5c31af7Sopenharmony_ci		// Create pointers to components and load components.
1189e5c31af7Sopenharmony_ci		for (int i = 0; i < numComponents; ++i)
1190e5c31af7Sopenharmony_ci		{
1191e5c31af7Sopenharmony_ci			zeroForCallable
1192e5c31af7Sopenharmony_ci				<< "%component_ptr_" << i << " = OpAccessChain %comp_ptr %input_val_ptr %uint_" << i << "\n"
1193e5c31af7Sopenharmony_ci				<< "%component_" << i << " = OpLoad %" << componentTypeName << " %component_ptr_" << i << "\n"
1194e5c31af7Sopenharmony_ci				;
1195e5c31af7Sopenharmony_ci		}
1196e5c31af7Sopenharmony_ci
1197e5c31af7Sopenharmony_ci		// Sum components together in %total_sum.
1198e5c31af7Sopenharmony_ci		for (int i = 1; i < numComponents; ++i)
1199e5c31af7Sopenharmony_ci		{
1200e5c31af7Sopenharmony_ci			const std::string previous		= ((i == 1) ? "%component_0" : ("%partial_" + de::toString(i-1)));
1201e5c31af7Sopenharmony_ci			const std::string resultName	= ((i == (numComponents - 1)) ? "%total_sum" : ("%partial_" + de::toString(i)));
1202e5c31af7Sopenharmony_ci			zeroForCallable << resultName << " = " << opAdd << " %" << componentTypeName << " %component_" << i << " " << previous << "\n";
1203e5c31af7Sopenharmony_ci		}
1204e5c31af7Sopenharmony_ci
1205e5c31af7Sopenharmony_ci		// Recalculate the zero.
1206e5c31af7Sopenharmony_ci		zeroForCallable
1207e5c31af7Sopenharmony_ci			<< "%zero_" << componentTypeName << " = " << opSub << " %" << componentTypeName << " %total_sum %" << componentTypeName << "_37\n"
1208e5c31af7Sopenharmony_ci			<< "%zero_for_callable = " << opConvert << " %uint %zero_" << componentTypeName << "\n"
1209e5c31af7Sopenharmony_ci			;
1210e5c31af7Sopenharmony_ci
1211e5c31af7Sopenharmony_ci		// Finally replace the zero_for_callable statements with the special version for vectors.
1212e5c31af7Sopenharmony_ci		subs["CALC_ZERO_FOR_CALLABLE"] = zeroForCallable.str();
1213e5c31af7Sopenharmony_ci
1214e5c31af7Sopenharmony_ci		// Rework comparison statements.
1215e5c31af7Sopenharmony_ci		if (isArray)
1216e5c31af7Sopenharmony_ci		{
1217e5c31af7Sopenharmony_ci			// Arrays need to be compared per-component.
1218e5c31af7Sopenharmony_ci			std::ostringstream calcEqual;
1219e5c31af7Sopenharmony_ci
1220e5c31af7Sopenharmony_ci			for (int i = 0; i < numComponents; ++i)
1221e5c31af7Sopenharmony_ci			{
1222e5c31af7Sopenharmony_ci				calcEqual
1223e5c31af7Sopenharmony_ci					<< "%component_after_" << i << " = OpLoad %" << componentTypeName << " %component_ptr_" << i << "\n"
1224e5c31af7Sopenharmony_ci					<< "%equal_" << i << " = " << opEqual << " %bool %component_" << i << " %component_after_" << i << "\n";
1225e5c31af7Sopenharmony_ci				if (i > 0)
1226e5c31af7Sopenharmony_ci					calcEqual << "%and_" << i << " = OpLogicalAnd %bool %equal_" << (i - 1) << " %equal_" << i << "\n";
1227e5c31af7Sopenharmony_ci				if (i == numComponents - 1)
1228e5c31af7Sopenharmony_ci					calcEqual << "%equal = OpCopyObject %bool %and_" << i << "\n";
1229e5c31af7Sopenharmony_ci			}
1230e5c31af7Sopenharmony_ci
1231e5c31af7Sopenharmony_ci			subs["CALC_EQUAL_STATEMENT"] = calcEqual.str();
1232e5c31af7Sopenharmony_ci		}
1233e5c31af7Sopenharmony_ci		else
1234e5c31af7Sopenharmony_ci		{
1235e5c31af7Sopenharmony_ci			// Vectors can be compared using a bool vector and OpAll.
1236e5c31af7Sopenharmony_ci			subs["CALC_EQUAL_STATEMENT"] =	"                  %equal_vector = " + opEqual + " %v" + numComponentsStr + "bool %input_val_before %input_val_after\n";
1237e5c31af7Sopenharmony_ci			subs["CALC_EQUAL_STATEMENT"] +=	"                         %equal = OpAll %bool %equal_vector\n";
1238e5c31af7Sopenharmony_ci		}
1239e5c31af7Sopenharmony_ci	}
1240e5c31af7Sopenharmony_ci
1241e5c31af7Sopenharmony_ci	if (isArray)
1242e5c31af7Sopenharmony_ci	{
1243e5c31af7Sopenharmony_ci		// Arrays need an ArrayStride decoration.
1244e5c31af7Sopenharmony_ci		std::ostringstream interfaceDecorations;
1245e5c31af7Sopenharmony_ci		interfaceDecorations << "OpDecorate %v" << numComponentsStr << componentTypeName << " ArrayStride " << getElementSize(m_params.dataType, VectorType::SCALAR) << "\n";
1246e5c31af7Sopenharmony_ci		subs["INTERFACE_DECORATIONS"] = interfaceDecorations.str();
1247e5c31af7Sopenharmony_ci	}
1248e5c31af7Sopenharmony_ci
1249e5c31af7Sopenharmony_ci	const auto inputBlockDecls = getGLSLInputValDecl(m_params.dataType, m_params.vectorType);
1250e5c31af7Sopenharmony_ci
1251e5c31af7Sopenharmony_ci	std::ostringstream glslBindings;
1252e5c31af7Sopenharmony_ci	glslBindings
1253e5c31af7Sopenharmony_ci		<< inputBlockDecls.first // Additional data types needed.
1254e5c31af7Sopenharmony_ci		<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
1255e5c31af7Sopenharmony_ci		<< "layout(set = 0, binding = 1) buffer CalleeBlock { uint val; } calleeBuffer;\n"
1256e5c31af7Sopenharmony_ci		<< "layout(set = 0, binding = 2) buffer OutputBlock { uint val; } outputBuffer;\n"
1257e5c31af7Sopenharmony_ci		<< "layout(set = 0, binding = 3) buffer InputBlock { " << inputBlockDecls.second << " } inputBuffer;\n"
1258e5c31af7Sopenharmony_ci		;
1259e5c31af7Sopenharmony_ci
1260e5c31af7Sopenharmony_ci	if (samplersNeeded(m_params.dataType))
1261e5c31af7Sopenharmony_ci	{
1262e5c31af7Sopenharmony_ci		glslBindings
1263e5c31af7Sopenharmony_ci			<< "layout(set = 0, binding = 4) uniform utexture2D sampledTexture[2];\n"
1264e5c31af7Sopenharmony_ci			<< "layout(set = 0, binding = 5) uniform sampler textureSampler[2];\n"
1265e5c31af7Sopenharmony_ci			<< "layout(set = 0, binding = 6) uniform usampler2D combinedImageSampler[2];\n"
1266e5c31af7Sopenharmony_ci			;
1267e5c31af7Sopenharmony_ci	}
1268e5c31af7Sopenharmony_ci	else if (storageImageNeeded(m_params.dataType))
1269e5c31af7Sopenharmony_ci	{
1270e5c31af7Sopenharmony_ci		glslBindings
1271e5c31af7Sopenharmony_ci			<< "layout(set = 0, binding = 4, r32ui) uniform uimage2D storageImage;\n"
1272e5c31af7Sopenharmony_ci			;
1273e5c31af7Sopenharmony_ci	}
1274e5c31af7Sopenharmony_ci
1275e5c31af7Sopenharmony_ci	const auto glslBindingsStr	=	glslBindings.str();
1276e5c31af7Sopenharmony_ci	const auto glslHeaderStr	=	"#version 460 core\n"
1277e5c31af7Sopenharmony_ci									"#extension GL_EXT_ray_tracing : require\n"
1278e5c31af7Sopenharmony_ci									"#extension GL_EXT_shader_explicit_arithmetic_types : require\n";
1279e5c31af7Sopenharmony_ci
1280e5c31af7Sopenharmony_ci
1281e5c31af7Sopenharmony_ci	if (m_params.callType == CallType::TRACE_RAY)
1282e5c31af7Sopenharmony_ci	{
1283e5c31af7Sopenharmony_ci		subs["ENTRY_POINT"]						=	"RayGenerationKHR";
1284e5c31af7Sopenharmony_ci		subs["MAIN_INTERFACE_EXTRAS"]			+=	" %hitValue";
1285e5c31af7Sopenharmony_ci		subs["INTERFACE_DECORATIONS"]			+=	"                                  OpDecorate %hitValue Location 0\n";
1286e5c31af7Sopenharmony_ci		subs["INTERFACE_TYPES_AND_VARIABLES"]	=	"                   %payload_ptr = OpTypePointer RayPayloadKHR %v3float\n"
1287e5c31af7Sopenharmony_ci													"                      %hitValue = OpVariable %payload_ptr RayPayloadKHR\n";
1288e5c31af7Sopenharmony_ci		subs["CALL_STATEMENTS"]					=	"                      %as_value = OpLoad %as_type %topLevelAS\n"
1289e5c31af7Sopenharmony_ci													"                                  OpTraceRayKHR %as_value %uint_0 %uint_255 %zero_for_callable %zero_for_callable %zero_for_callable %origin_const %float_0 %direction_const %float_9 %hitValue\n";
1290e5c31af7Sopenharmony_ci
1291e5c31af7Sopenharmony_ci		const auto rgen = spvTemplate.specialize(subs);
1292e5c31af7Sopenharmony_ci		programCollection.spirvAsmSources.add("rgen") << rgen << spvBuildOptions;
1293e5c31af7Sopenharmony_ci
1294e5c31af7Sopenharmony_ci		std::stringstream chit;
1295e5c31af7Sopenharmony_ci		chit
1296e5c31af7Sopenharmony_ci			<< glslHeaderStr
1297e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1298e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec3 attribs;\n"
1299e5c31af7Sopenharmony_ci			<< glslBindingsStr
1300e5c31af7Sopenharmony_ci			<< "void main()\n"
1301e5c31af7Sopenharmony_ci			<< "{\n"
1302e5c31af7Sopenharmony_ci			<< "    calleeBuffer.val = 1u;\n"
1303e5c31af7Sopenharmony_ci			<< "}\n"
1304e5c31af7Sopenharmony_ci			;
1305e5c31af7Sopenharmony_ci		programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(chit.str())) << buildOptions;
1306e5c31af7Sopenharmony_ci	}
1307e5c31af7Sopenharmony_ci	else if (m_params.callType == CallType::EXECUTE_CALLABLE)
1308e5c31af7Sopenharmony_ci	{
1309e5c31af7Sopenharmony_ci		subs["ENTRY_POINT"]						=	"RayGenerationKHR";
1310e5c31af7Sopenharmony_ci		subs["MAIN_INTERFACE_EXTRAS"]			+=	" %callableData";
1311e5c31af7Sopenharmony_ci		subs["INTERFACE_DECORATIONS"]			+=	"                                  OpDecorate %callableData Location 0\n";
1312e5c31af7Sopenharmony_ci		subs["INTERFACE_TYPES_AND_VARIABLES"]	=	"             %callable_data_ptr = OpTypePointer CallableDataKHR %float\n"
1313e5c31af7Sopenharmony_ci													"                  %callableData = OpVariable %callable_data_ptr CallableDataKHR\n";
1314e5c31af7Sopenharmony_ci		subs["CALL_STATEMENTS"]					=	"                                  OpExecuteCallableKHR %zero_for_callable %callableData\n";
1315e5c31af7Sopenharmony_ci
1316e5c31af7Sopenharmony_ci		const auto rgen = spvTemplate.specialize(subs);
1317e5c31af7Sopenharmony_ci		programCollection.spirvAsmSources.add("rgen") << rgen << spvBuildOptions;
1318e5c31af7Sopenharmony_ci
1319e5c31af7Sopenharmony_ci		std::ostringstream call;
1320e5c31af7Sopenharmony_ci		call
1321e5c31af7Sopenharmony_ci			<< glslHeaderStr
1322e5c31af7Sopenharmony_ci			<< "layout(location = 0) callableDataInEXT float callableData;\n"
1323e5c31af7Sopenharmony_ci			<< glslBindingsStr
1324e5c31af7Sopenharmony_ci			<< "void main()\n"
1325e5c31af7Sopenharmony_ci			<< "{\n"
1326e5c31af7Sopenharmony_ci			<< "    calleeBuffer.val = 1u;\n"
1327e5c31af7Sopenharmony_ci			<< "}\n"
1328e5c31af7Sopenharmony_ci			;
1329e5c31af7Sopenharmony_ci
1330e5c31af7Sopenharmony_ci		programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(call.str())) << buildOptions;
1331e5c31af7Sopenharmony_ci	}
1332e5c31af7Sopenharmony_ci	else if (m_params.callType == CallType::REPORT_INTERSECTION)
1333e5c31af7Sopenharmony_ci	{
1334e5c31af7Sopenharmony_ci		subs["ENTRY_POINT"]						=	"IntersectionKHR";
1335e5c31af7Sopenharmony_ci		subs["MAIN_INTERFACE_EXTRAS"]			+=	" %attribs";
1336e5c31af7Sopenharmony_ci		subs["INTERFACE_DECORATIONS"]			+=	"";
1337e5c31af7Sopenharmony_ci		subs["INTERFACE_TYPES_AND_VARIABLES"]	=	"             %hit_attribute_ptr = OpTypePointer HitAttributeKHR %v3float\n"
1338e5c31af7Sopenharmony_ci													"                       %attribs = OpVariable %hit_attribute_ptr HitAttributeKHR\n";
1339e5c31af7Sopenharmony_ci		subs["CALL_STATEMENTS"]					=	"              %intersection_ret = OpReportIntersectionKHR %bool %float_1 %zero_for_callable\n";
1340e5c31af7Sopenharmony_ci
1341e5c31af7Sopenharmony_ci		const auto rint = spvTemplate.specialize(subs);
1342e5c31af7Sopenharmony_ci		programCollection.spirvAsmSources.add("rint") << rint << spvBuildOptions;
1343e5c31af7Sopenharmony_ci
1344e5c31af7Sopenharmony_ci		std::ostringstream rgen;
1345e5c31af7Sopenharmony_ci		rgen
1346e5c31af7Sopenharmony_ci			<< glslHeaderStr
1347e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
1348e5c31af7Sopenharmony_ci			<< glslBindingsStr
1349e5c31af7Sopenharmony_ci			<< "void main()\n"
1350e5c31af7Sopenharmony_ci			<< "{\n"
1351e5c31af7Sopenharmony_ci			<< "  traceRayEXT(topLevelAS, 0u, 0xFFu, 0, 0, 0, vec3(0.5, 0.5, 0.0), 0.0, vec3(0.0, 0.0, -1.0), 9.0, 0);\n"
1352e5c31af7Sopenharmony_ci			<< "}\n"
1353e5c31af7Sopenharmony_ci			;
1354e5c31af7Sopenharmony_ci		programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions;
1355e5c31af7Sopenharmony_ci
1356e5c31af7Sopenharmony_ci		std::stringstream ahit;
1357e5c31af7Sopenharmony_ci		ahit
1358e5c31af7Sopenharmony_ci			<< glslHeaderStr
1359e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1360e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec3 attribs;\n"
1361e5c31af7Sopenharmony_ci			<< glslBindingsStr
1362e5c31af7Sopenharmony_ci			<< "void main()\n"
1363e5c31af7Sopenharmony_ci			<< "{\n"
1364e5c31af7Sopenharmony_ci			<< "    calleeBuffer.val = 1u;\n"
1365e5c31af7Sopenharmony_ci			<< "}\n"
1366e5c31af7Sopenharmony_ci			;
1367e5c31af7Sopenharmony_ci		programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(ahit.str())) << buildOptions;
1368e5c31af7Sopenharmony_ci	}
1369e5c31af7Sopenharmony_ci	else
1370e5c31af7Sopenharmony_ci	{
1371e5c31af7Sopenharmony_ci		DE_ASSERT(false);
1372e5c31af7Sopenharmony_ci	}
1373e5c31af7Sopenharmony_ci}
1374e5c31af7Sopenharmony_ci
1375e5c31af7Sopenharmony_ciusing v2i32 = tcu::Vector<deInt32, 2>;
1376e5c31af7Sopenharmony_ciusing v3i32 = tcu::Vector<deInt32, 3>;
1377e5c31af7Sopenharmony_ciusing v4i32 = tcu::Vector<deInt32, 4>;
1378e5c31af7Sopenharmony_ciusing a5i32 = std::array<deInt32, 5>;
1379e5c31af7Sopenharmony_ci
1380e5c31af7Sopenharmony_ciusing v2u32 = tcu::Vector<deUint32, 2>;
1381e5c31af7Sopenharmony_ciusing v3u32 = tcu::Vector<deUint32, 3>;
1382e5c31af7Sopenharmony_ciusing v4u32 = tcu::Vector<deUint32, 4>;
1383e5c31af7Sopenharmony_ciusing a5u32 = std::array<deUint32, 5>;
1384e5c31af7Sopenharmony_ci
1385e5c31af7Sopenharmony_ciusing v2i64 = tcu::Vector<deInt64, 2>;
1386e5c31af7Sopenharmony_ciusing v3i64 = tcu::Vector<deInt64, 3>;
1387e5c31af7Sopenharmony_ciusing v4i64 = tcu::Vector<deInt64, 4>;
1388e5c31af7Sopenharmony_ciusing a5i64 = std::array<deInt64, 5>;
1389e5c31af7Sopenharmony_ci
1390e5c31af7Sopenharmony_ciusing v2u64 = tcu::Vector<deUint64, 2>;
1391e5c31af7Sopenharmony_ciusing v3u64 = tcu::Vector<deUint64, 3>;
1392e5c31af7Sopenharmony_ciusing v4u64 = tcu::Vector<deUint64, 4>;
1393e5c31af7Sopenharmony_ciusing a5u64 = std::array<deUint64, 5>;
1394e5c31af7Sopenharmony_ci
1395e5c31af7Sopenharmony_ciusing v2i16 = tcu::Vector<deInt16, 2>;
1396e5c31af7Sopenharmony_ciusing v3i16 = tcu::Vector<deInt16, 3>;
1397e5c31af7Sopenharmony_ciusing v4i16 = tcu::Vector<deInt16, 4>;
1398e5c31af7Sopenharmony_ciusing a5i16 = std::array<deInt16, 5>;
1399e5c31af7Sopenharmony_ci
1400e5c31af7Sopenharmony_ciusing v2u16 = tcu::Vector<deUint16, 2>;
1401e5c31af7Sopenharmony_ciusing v3u16 = tcu::Vector<deUint16, 3>;
1402e5c31af7Sopenharmony_ciusing v4u16 = tcu::Vector<deUint16, 4>;
1403e5c31af7Sopenharmony_ciusing a5u16 = std::array<deUint16, 5>;
1404e5c31af7Sopenharmony_ci
1405e5c31af7Sopenharmony_ciusing v2i8 = tcu::Vector<deInt8, 2>;
1406e5c31af7Sopenharmony_ciusing v3i8 = tcu::Vector<deInt8, 3>;
1407e5c31af7Sopenharmony_ciusing v4i8 = tcu::Vector<deInt8, 4>;
1408e5c31af7Sopenharmony_ciusing a5i8 = std::array<deInt8, 5>;
1409e5c31af7Sopenharmony_ci
1410e5c31af7Sopenharmony_ciusing v2u8 = tcu::Vector<deUint8, 2>;
1411e5c31af7Sopenharmony_ciusing v3u8 = tcu::Vector<deUint8, 3>;
1412e5c31af7Sopenharmony_ciusing v4u8 = tcu::Vector<deUint8, 4>;
1413e5c31af7Sopenharmony_ciusing a5u8 = std::array<deUint8, 5>;
1414e5c31af7Sopenharmony_ci
1415e5c31af7Sopenharmony_ciusing v2f32 = tcu::Vector<tcu::Float32, 2>;
1416e5c31af7Sopenharmony_ciusing v3f32 = tcu::Vector<tcu::Float32, 3>;
1417e5c31af7Sopenharmony_ciusing v4f32 = tcu::Vector<tcu::Float32, 4>;
1418e5c31af7Sopenharmony_ciusing a5f32 = std::array<tcu::Float32, 5>;
1419e5c31af7Sopenharmony_ci
1420e5c31af7Sopenharmony_ciusing v2f64 = tcu::Vector<tcu::Float64, 2>;
1421e5c31af7Sopenharmony_ciusing v3f64 = tcu::Vector<tcu::Float64, 3>;
1422e5c31af7Sopenharmony_ciusing v4f64 = tcu::Vector<tcu::Float64, 4>;
1423e5c31af7Sopenharmony_ciusing a5f64 = std::array<tcu::Float64, 5>;
1424e5c31af7Sopenharmony_ci
1425e5c31af7Sopenharmony_ciusing v2f16 = tcu::Vector<tcu::Float16, 2>;
1426e5c31af7Sopenharmony_ciusing v3f16 = tcu::Vector<tcu::Float16, 3>;
1427e5c31af7Sopenharmony_ciusing v4f16 = tcu::Vector<tcu::Float16, 4>;
1428e5c31af7Sopenharmony_ciusing a5f16 = std::array<tcu::Float16, 5>;
1429e5c31af7Sopenharmony_ci
1430e5c31af7Sopenharmony_ci// Scalar types get filled with value 37, matching the value that will be substracted in the shader.
1431e5c31af7Sopenharmony_ci#define GEN_SCALAR_FILL(DATA_TYPE)											\
1432e5c31af7Sopenharmony_ci	do {																	\
1433e5c31af7Sopenharmony_ci		const auto inputBufferValue = static_cast<DATA_TYPE>(37.0);			\
1434e5c31af7Sopenharmony_ci		deMemcpy(bufferPtr, &inputBufferValue, sizeof(inputBufferValue));	\
1435e5c31af7Sopenharmony_ci	} while (0)
1436e5c31af7Sopenharmony_ci
1437e5c31af7Sopenharmony_ci// Vector types get filled with values that add up to 37, matching the value that will be substracted in the shader.
1438e5c31af7Sopenharmony_ci#define GEN_V2_FILL(DATA_TYPE)												\
1439e5c31af7Sopenharmony_ci	do {																	\
1440e5c31af7Sopenharmony_ci		DATA_TYPE inputBufferValue;											\
1441e5c31af7Sopenharmony_ci		inputBufferValue.x() = static_cast<DATA_TYPE::Element>(21.0);		\
1442e5c31af7Sopenharmony_ci		inputBufferValue.y() = static_cast<DATA_TYPE::Element>(16.0);		\
1443e5c31af7Sopenharmony_ci		deMemcpy(bufferPtr, &inputBufferValue, sizeof(inputBufferValue));	\
1444e5c31af7Sopenharmony_ci	} while (0)
1445e5c31af7Sopenharmony_ci
1446e5c31af7Sopenharmony_ci#define GEN_V3_FILL(DATA_TYPE)												\
1447e5c31af7Sopenharmony_ci	do {																	\
1448e5c31af7Sopenharmony_ci		DATA_TYPE inputBufferValue;											\
1449e5c31af7Sopenharmony_ci		inputBufferValue.x() = static_cast<DATA_TYPE::Element>(11.0);		\
1450e5c31af7Sopenharmony_ci		inputBufferValue.y() = static_cast<DATA_TYPE::Element>(19.0);		\
1451e5c31af7Sopenharmony_ci		inputBufferValue.z() = static_cast<DATA_TYPE::Element>(7.0);		\
1452e5c31af7Sopenharmony_ci		deMemcpy(bufferPtr, &inputBufferValue, sizeof(inputBufferValue));	\
1453e5c31af7Sopenharmony_ci	} while (0)
1454e5c31af7Sopenharmony_ci
1455e5c31af7Sopenharmony_ci#define GEN_V4_FILL(DATA_TYPE)												\
1456e5c31af7Sopenharmony_ci	do {																	\
1457e5c31af7Sopenharmony_ci		DATA_TYPE inputBufferValue;											\
1458e5c31af7Sopenharmony_ci		inputBufferValue.x() = static_cast<DATA_TYPE::Element>(9.0);		\
1459e5c31af7Sopenharmony_ci		inputBufferValue.y() = static_cast<DATA_TYPE::Element>(11.0);		\
1460e5c31af7Sopenharmony_ci		inputBufferValue.z() = static_cast<DATA_TYPE::Element>(3.0);		\
1461e5c31af7Sopenharmony_ci		inputBufferValue.w() = static_cast<DATA_TYPE::Element>(14.0);		\
1462e5c31af7Sopenharmony_ci		deMemcpy(bufferPtr, &inputBufferValue, sizeof(inputBufferValue));	\
1463e5c31af7Sopenharmony_ci	} while (0)
1464e5c31af7Sopenharmony_ci
1465e5c31af7Sopenharmony_ci#define GEN_A5_FILL(DATA_TYPE)															\
1466e5c31af7Sopenharmony_ci	do {																				\
1467e5c31af7Sopenharmony_ci		DATA_TYPE inputBufferValue;														\
1468e5c31af7Sopenharmony_ci		inputBufferValue[0] = static_cast<DATA_TYPE::value_type>(13.0);					\
1469e5c31af7Sopenharmony_ci		inputBufferValue[1] = static_cast<DATA_TYPE::value_type>(6.0);					\
1470e5c31af7Sopenharmony_ci		inputBufferValue[2] = static_cast<DATA_TYPE::value_type>(2.0);					\
1471e5c31af7Sopenharmony_ci		inputBufferValue[3] = static_cast<DATA_TYPE::value_type>(5.0);					\
1472e5c31af7Sopenharmony_ci		inputBufferValue[4] = static_cast<DATA_TYPE::value_type>(11.0);					\
1473e5c31af7Sopenharmony_ci		deMemcpy(bufferPtr, inputBufferValue.data(), de::dataSize(inputBufferValue));	\
1474e5c31af7Sopenharmony_ci	} while (0)
1475e5c31af7Sopenharmony_ci
1476e5c31af7Sopenharmony_civoid fillInputBuffer (DataType dataType, VectorType vectorType, void* bufferPtr)
1477e5c31af7Sopenharmony_ci{
1478e5c31af7Sopenharmony_ci	if (vectorType == VectorType::SCALAR)
1479e5c31af7Sopenharmony_ci	{
1480e5c31af7Sopenharmony_ci		if		(dataType == DataType::INT32)	GEN_SCALAR_FILL(deInt32);
1481e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT32)	GEN_SCALAR_FILL(deUint32);
1482e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT64)	GEN_SCALAR_FILL(deInt64);
1483e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT64)	GEN_SCALAR_FILL(deUint64);
1484e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT16)	GEN_SCALAR_FILL(deInt16);
1485e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT16)	GEN_SCALAR_FILL(deUint16);
1486e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT8)	GEN_SCALAR_FILL(deInt8);
1487e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT8)	GEN_SCALAR_FILL(deUint8);
1488e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT32)	GEN_SCALAR_FILL(tcu::Float32);
1489e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT64)	GEN_SCALAR_FILL(tcu::Float64);
1490e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT16)	GEN_SCALAR_FILL(tcu::Float16);
1491e5c31af7Sopenharmony_ci		else if (dataType == DataType::STRUCT)
1492e5c31af7Sopenharmony_ci		{
1493e5c31af7Sopenharmony_ci			InputStruct data = { 12u, 25.0f };
1494e5c31af7Sopenharmony_ci			deMemcpy(bufferPtr, &data, sizeof(data));
1495e5c31af7Sopenharmony_ci		}
1496e5c31af7Sopenharmony_ci		else if (dataType == DataType::OP_NULL)		GEN_SCALAR_FILL(deUint32);
1497e5c31af7Sopenharmony_ci		else if (dataType == DataType::OP_UNDEF)	GEN_SCALAR_FILL(deUint32);
1498e5c31af7Sopenharmony_ci		else
1499e5c31af7Sopenharmony_ci		{
1500e5c31af7Sopenharmony_ci			DE_ASSERT(false);
1501e5c31af7Sopenharmony_ci		}
1502e5c31af7Sopenharmony_ci	}
1503e5c31af7Sopenharmony_ci	else if (vectorType == VectorType::V2)
1504e5c31af7Sopenharmony_ci	{
1505e5c31af7Sopenharmony_ci		if		(dataType == DataType::INT32)	GEN_V2_FILL(v2i32);
1506e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT32)	GEN_V2_FILL(v2u32);
1507e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT64)	GEN_V2_FILL(v2i64);
1508e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT64)	GEN_V2_FILL(v2u64);
1509e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT16)	GEN_V2_FILL(v2i16);
1510e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT16)	GEN_V2_FILL(v2u16);
1511e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT8)	GEN_V2_FILL(v2i8);
1512e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT8)	GEN_V2_FILL(v2u8);
1513e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT32)	GEN_V2_FILL(v2f32);
1514e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT64)	GEN_V2_FILL(v2f64);
1515e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT16)	GEN_V2_FILL(v2f16);
1516e5c31af7Sopenharmony_ci		else
1517e5c31af7Sopenharmony_ci		{
1518e5c31af7Sopenharmony_ci			DE_ASSERT(false);
1519e5c31af7Sopenharmony_ci		}
1520e5c31af7Sopenharmony_ci	}
1521e5c31af7Sopenharmony_ci	else if (vectorType == VectorType::V3)
1522e5c31af7Sopenharmony_ci	{
1523e5c31af7Sopenharmony_ci		if		(dataType == DataType::INT32)	GEN_V3_FILL(v3i32);
1524e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT32)	GEN_V3_FILL(v3u32);
1525e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT64)	GEN_V3_FILL(v3i64);
1526e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT64)	GEN_V3_FILL(v3u64);
1527e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT16)	GEN_V3_FILL(v3i16);
1528e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT16)	GEN_V3_FILL(v3u16);
1529e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT8)	GEN_V3_FILL(v3i8);
1530e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT8)	GEN_V3_FILL(v3u8);
1531e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT32)	GEN_V3_FILL(v3f32);
1532e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT64)	GEN_V3_FILL(v3f64);
1533e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT16)	GEN_V3_FILL(v3f16);
1534e5c31af7Sopenharmony_ci		else
1535e5c31af7Sopenharmony_ci		{
1536e5c31af7Sopenharmony_ci			DE_ASSERT(false);
1537e5c31af7Sopenharmony_ci		}
1538e5c31af7Sopenharmony_ci	}
1539e5c31af7Sopenharmony_ci	else if (vectorType == VectorType::V4)
1540e5c31af7Sopenharmony_ci	{
1541e5c31af7Sopenharmony_ci		if		(dataType == DataType::INT32)	GEN_V4_FILL(v4i32);
1542e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT32)	GEN_V4_FILL(v4u32);
1543e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT64)	GEN_V4_FILL(v4i64);
1544e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT64)	GEN_V4_FILL(v4u64);
1545e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT16)	GEN_V4_FILL(v4i16);
1546e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT16)	GEN_V4_FILL(v4u16);
1547e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT8)	GEN_V4_FILL(v4i8);
1548e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT8)	GEN_V4_FILL(v4u8);
1549e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT32)	GEN_V4_FILL(v4f32);
1550e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT64)	GEN_V4_FILL(v4f64);
1551e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT16)	GEN_V4_FILL(v4f16);
1552e5c31af7Sopenharmony_ci		else
1553e5c31af7Sopenharmony_ci		{
1554e5c31af7Sopenharmony_ci			DE_ASSERT(false);
1555e5c31af7Sopenharmony_ci		}
1556e5c31af7Sopenharmony_ci	}
1557e5c31af7Sopenharmony_ci	else if (vectorType == VectorType::A5)
1558e5c31af7Sopenharmony_ci	{
1559e5c31af7Sopenharmony_ci		if		(dataType == DataType::INT32)	GEN_A5_FILL(a5i32);
1560e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT32)	GEN_A5_FILL(a5u32);
1561e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT64)	GEN_A5_FILL(a5i64);
1562e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT64)	GEN_A5_FILL(a5u64);
1563e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT16)	GEN_A5_FILL(a5i16);
1564e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT16)	GEN_A5_FILL(a5u16);
1565e5c31af7Sopenharmony_ci		else if	(dataType == DataType::INT8)	GEN_A5_FILL(a5i8);
1566e5c31af7Sopenharmony_ci		else if	(dataType == DataType::UINT8)	GEN_A5_FILL(a5u8);
1567e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT32)	GEN_A5_FILL(a5f32);
1568e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT64)	GEN_A5_FILL(a5f64);
1569e5c31af7Sopenharmony_ci		else if	(dataType == DataType::FLOAT16)	GEN_A5_FILL(a5f16);
1570e5c31af7Sopenharmony_ci		else
1571e5c31af7Sopenharmony_ci		{
1572e5c31af7Sopenharmony_ci			DE_ASSERT(false);
1573e5c31af7Sopenharmony_ci		}
1574e5c31af7Sopenharmony_ci	}
1575e5c31af7Sopenharmony_ci	else
1576e5c31af7Sopenharmony_ci	{
1577e5c31af7Sopenharmony_ci		DE_ASSERT(false);
1578e5c31af7Sopenharmony_ci	}
1579e5c31af7Sopenharmony_ci}
1580e5c31af7Sopenharmony_ci
1581e5c31af7Sopenharmony_citcu::TestStatus DataSpillTestInstance::iterate (void)
1582e5c31af7Sopenharmony_ci{
1583e5c31af7Sopenharmony_ci	const auto& vki						= m_context.getInstanceInterface();
1584e5c31af7Sopenharmony_ci	const auto	physicalDevice			= m_context.getPhysicalDevice();
1585e5c31af7Sopenharmony_ci	const auto&	vkd						= m_context.getDeviceInterface();
1586e5c31af7Sopenharmony_ci	const auto	device					= m_context.getDevice();
1587e5c31af7Sopenharmony_ci	const auto	queue					= m_context.getUniversalQueue();
1588e5c31af7Sopenharmony_ci	const auto	familyIndex				= m_context.getUniversalQueueFamilyIndex();
1589e5c31af7Sopenharmony_ci	auto&		alloc					= m_context.getDefaultAllocator();
1590e5c31af7Sopenharmony_ci	const auto	shaderStages			= getShaderStages(m_params.callType);
1591e5c31af7Sopenharmony_ci
1592e5c31af7Sopenharmony_ci	// Command buffer.
1593e5c31af7Sopenharmony_ci	const auto cmdPool		= makeCommandPool(vkd, device, familyIndex);
1594e5c31af7Sopenharmony_ci	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1595e5c31af7Sopenharmony_ci	const auto cmdBuffer	= cmdBufferPtr.get();
1596e5c31af7Sopenharmony_ci
1597e5c31af7Sopenharmony_ci	beginCommandBuffer(vkd, cmdBuffer);
1598e5c31af7Sopenharmony_ci
1599e5c31af7Sopenharmony_ci	// Callee, input and output buffers.
1600e5c31af7Sopenharmony_ci	const auto calleeBufferSize	= getElementSize(DataType::UINT32, VectorType::SCALAR);
1601e5c31af7Sopenharmony_ci	const auto outputBufferSize	= getElementSize(DataType::UINT32, VectorType::SCALAR);
1602e5c31af7Sopenharmony_ci	const auto inputBufferSize	= getElementSize(m_params.dataType, m_params.vectorType);
1603e5c31af7Sopenharmony_ci
1604e5c31af7Sopenharmony_ci	const auto calleeBufferInfo	= makeBufferCreateInfo(calleeBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1605e5c31af7Sopenharmony_ci	const auto outputBufferInfo	= makeBufferCreateInfo(outputBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1606e5c31af7Sopenharmony_ci	const auto inputBufferInfo	= makeBufferCreateInfo(inputBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1607e5c31af7Sopenharmony_ci
1608e5c31af7Sopenharmony_ci	BufferWithMemory calleeBuffer	(vkd, device, alloc, calleeBufferInfo, MemoryRequirement::HostVisible);
1609e5c31af7Sopenharmony_ci	BufferWithMemory outputBuffer	(vkd, device, alloc, outputBufferInfo, MemoryRequirement::HostVisible);
1610e5c31af7Sopenharmony_ci	BufferWithMemory inputBuffer	(vkd, device, alloc, inputBufferInfo, MemoryRequirement::HostVisible);
1611e5c31af7Sopenharmony_ci
1612e5c31af7Sopenharmony_ci	// Fill buffers with values.
1613e5c31af7Sopenharmony_ci	auto& calleeBufferAlloc	= calleeBuffer.getAllocation();
1614e5c31af7Sopenharmony_ci	auto* calleeBufferPtr	= calleeBufferAlloc.getHostPtr();
1615e5c31af7Sopenharmony_ci	auto& outputBufferAlloc	= outputBuffer.getAllocation();
1616e5c31af7Sopenharmony_ci	auto* outputBufferPtr	= outputBufferAlloc.getHostPtr();
1617e5c31af7Sopenharmony_ci	auto& inputBufferAlloc	= inputBuffer.getAllocation();
1618e5c31af7Sopenharmony_ci	auto* inputBufferPtr	= inputBufferAlloc.getHostPtr();
1619e5c31af7Sopenharmony_ci
1620e5c31af7Sopenharmony_ci	deMemset(calleeBufferPtr, 0, static_cast<size_t>(calleeBufferSize));
1621e5c31af7Sopenharmony_ci	deMemset(outputBufferPtr, 0, static_cast<size_t>(outputBufferSize));
1622e5c31af7Sopenharmony_ci
1623e5c31af7Sopenharmony_ci	if (samplersNeeded(m_params.dataType) || storageImageNeeded(m_params.dataType))
1624e5c31af7Sopenharmony_ci	{
1625e5c31af7Sopenharmony_ci		// The input buffer for these cases will be filled with zeros (sampling coordinates), and the input textures will contain the interesting input value.
1626e5c31af7Sopenharmony_ci		deMemset(inputBufferPtr, 0, static_cast<size_t>(inputBufferSize));
1627e5c31af7Sopenharmony_ci	}
1628e5c31af7Sopenharmony_ci	else
1629e5c31af7Sopenharmony_ci	{
1630e5c31af7Sopenharmony_ci		// We want to fill the input buffer with values that will be consistently used in the shader to obtain a result of zero.
1631e5c31af7Sopenharmony_ci		fillInputBuffer(m_params.dataType, m_params.vectorType, inputBufferPtr);
1632e5c31af7Sopenharmony_ci	}
1633e5c31af7Sopenharmony_ci
1634e5c31af7Sopenharmony_ci	flushAlloc(vkd, device, calleeBufferAlloc);
1635e5c31af7Sopenharmony_ci	flushAlloc(vkd, device, outputBufferAlloc);
1636e5c31af7Sopenharmony_ci	flushAlloc(vkd, device, inputBufferAlloc);
1637e5c31af7Sopenharmony_ci
1638e5c31af7Sopenharmony_ci	// Acceleration structures.
1639e5c31af7Sopenharmony_ci	de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure;
1640e5c31af7Sopenharmony_ci	de::MovePtr<TopLevelAccelerationStructure>		topLevelAccelerationStructure;
1641e5c31af7Sopenharmony_ci
1642e5c31af7Sopenharmony_ci	bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
1643e5c31af7Sopenharmony_ci	bottomLevelAccelerationStructure->setDefaultGeometryData(getShaderStageForGeometry(m_params.callType), VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR);
1644e5c31af7Sopenharmony_ci	bottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, alloc);
1645e5c31af7Sopenharmony_ci
1646e5c31af7Sopenharmony_ci	topLevelAccelerationStructure = makeTopLevelAccelerationStructure();
1647e5c31af7Sopenharmony_ci	topLevelAccelerationStructure->setInstanceCount(1);
1648e5c31af7Sopenharmony_ci	topLevelAccelerationStructure->addInstance(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1649e5c31af7Sopenharmony_ci	topLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, alloc);
1650e5c31af7Sopenharmony_ci
1651e5c31af7Sopenharmony_ci	// Get some ray tracing properties.
1652e5c31af7Sopenharmony_ci	deUint32 shaderGroupHandleSize		= 0u;
1653e5c31af7Sopenharmony_ci	deUint32 shaderGroupBaseAlignment	= 1u;
1654e5c31af7Sopenharmony_ci	{
1655e5c31af7Sopenharmony_ci		const auto rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physicalDevice);
1656e5c31af7Sopenharmony_ci		shaderGroupHandleSize				= rayTracingPropertiesKHR->getShaderGroupHandleSize();
1657e5c31af7Sopenharmony_ci		shaderGroupBaseAlignment			= rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
1658e5c31af7Sopenharmony_ci	}
1659e5c31af7Sopenharmony_ci
1660e5c31af7Sopenharmony_ci	// Textures and samplers if needed.
1661e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>				textureData;
1662e5c31af7Sopenharmony_ci	std::vector<de::MovePtr<ImageWithMemory>>	textures;
1663e5c31af7Sopenharmony_ci	std::vector<Move<VkImageView>>				textureViews;
1664e5c31af7Sopenharmony_ci	std::vector<Move<VkSampler>>				samplers;
1665e5c31af7Sopenharmony_ci
1666e5c31af7Sopenharmony_ci	if (samplersNeeded(m_params.dataType) || storageImageNeeded(m_params.dataType))
1667e5c31af7Sopenharmony_ci	{
1668e5c31af7Sopenharmony_ci		// Create texture data with the expected contents.
1669e5c31af7Sopenharmony_ci		{
1670e5c31af7Sopenharmony_ci			const auto textureDataSize			= static_cast<VkDeviceSize>(sizeof(deUint32));
1671e5c31af7Sopenharmony_ci			const auto textureDataCreateInfo	= makeBufferCreateInfo(textureDataSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
1672e5c31af7Sopenharmony_ci
1673e5c31af7Sopenharmony_ci			textureData = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, alloc, textureDataCreateInfo, MemoryRequirement::HostVisible));
1674e5c31af7Sopenharmony_ci			auto& textureDataAlloc = textureData->getAllocation();
1675e5c31af7Sopenharmony_ci			auto* textureDataPtr = textureDataAlloc.getHostPtr();
1676e5c31af7Sopenharmony_ci
1677e5c31af7Sopenharmony_ci			fillInputBuffer(DataType::UINT32, VectorType::SCALAR, textureDataPtr);
1678e5c31af7Sopenharmony_ci			flushAlloc(vkd, device, textureDataAlloc);
1679e5c31af7Sopenharmony_ci		}
1680e5c31af7Sopenharmony_ci
1681e5c31af7Sopenharmony_ci		// Images will be created like this with different usages.
1682e5c31af7Sopenharmony_ci		VkImageCreateInfo imageCreateInfo =
1683e5c31af7Sopenharmony_ci		{
1684e5c31af7Sopenharmony_ci			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
1685e5c31af7Sopenharmony_ci			nullptr,								//	const void*				pNext;
1686e5c31af7Sopenharmony_ci			0u,										//	VkImageCreateFlags		flags;
1687e5c31af7Sopenharmony_ci			VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
1688e5c31af7Sopenharmony_ci			kImageFormat,							//	VkFormat				format;
1689e5c31af7Sopenharmony_ci			kImageExtent,							//	VkExtent3D				extent;
1690e5c31af7Sopenharmony_ci			1u,										//	deUint32				mipLevels;
1691e5c31af7Sopenharmony_ci			1u,										//	deUint32				arrayLayers;
1692e5c31af7Sopenharmony_ci			VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
1693e5c31af7Sopenharmony_ci			VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
1694e5c31af7Sopenharmony_ci			kSampledImageUsage,						//	VkImageUsageFlags		usage;
1695e5c31af7Sopenharmony_ci			VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
1696e5c31af7Sopenharmony_ci			0u,										//	deUint32				queueFamilyIndexCount;
1697e5c31af7Sopenharmony_ci			nullptr,								//	const deUint32*			pQueueFamilyIndices;
1698e5c31af7Sopenharmony_ci			VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
1699e5c31af7Sopenharmony_ci		};
1700e5c31af7Sopenharmony_ci
1701e5c31af7Sopenharmony_ci		const auto imageSubresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1702e5c31af7Sopenharmony_ci		const auto imageSubresourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1703e5c31af7Sopenharmony_ci
1704e5c31af7Sopenharmony_ci		if (samplersNeeded(m_params.dataType))
1705e5c31af7Sopenharmony_ci		{
1706e5c31af7Sopenharmony_ci			// All samplers will be created like this.
1707e5c31af7Sopenharmony_ci			const VkSamplerCreateInfo samplerCreateInfo =
1708e5c31af7Sopenharmony_ci			{
1709e5c31af7Sopenharmony_ci				VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,	//	VkStructureType			sType;
1710e5c31af7Sopenharmony_ci				nullptr,								//	const void*				pNext;
1711e5c31af7Sopenharmony_ci				0u,										//	VkSamplerCreateFlags	flags;
1712e5c31af7Sopenharmony_ci				VK_FILTER_NEAREST,						//	VkFilter				magFilter;
1713e5c31af7Sopenharmony_ci				VK_FILTER_NEAREST,						//	VkFilter				minFilter;
1714e5c31af7Sopenharmony_ci				VK_SAMPLER_MIPMAP_MODE_NEAREST,			//	VkSamplerMipmapMode		mipmapMode;
1715e5c31af7Sopenharmony_ci				VK_SAMPLER_ADDRESS_MODE_REPEAT,			//	VkSamplerAddressMode	addressModeU;
1716e5c31af7Sopenharmony_ci				VK_SAMPLER_ADDRESS_MODE_REPEAT,			//	VkSamplerAddressMode	addressModeV;
1717e5c31af7Sopenharmony_ci				VK_SAMPLER_ADDRESS_MODE_REPEAT,			//	VkSamplerAddressMode	addressModeW;
1718e5c31af7Sopenharmony_ci				0.0,									//	float					mipLodBias;
1719e5c31af7Sopenharmony_ci				VK_FALSE,								//	VkBool32				anisotropyEnable;
1720e5c31af7Sopenharmony_ci				1.0f,									//	float					maxAnisotropy;
1721e5c31af7Sopenharmony_ci				VK_FALSE,								//	VkBool32				compareEnable;
1722e5c31af7Sopenharmony_ci				VK_COMPARE_OP_ALWAYS,					//	VkCompareOp				compareOp;
1723e5c31af7Sopenharmony_ci				0.0f,									//	float					minLod;
1724e5c31af7Sopenharmony_ci				1.0f,									//	float					maxLod;
1725e5c31af7Sopenharmony_ci				VK_BORDER_COLOR_INT_OPAQUE_BLACK,		//	VkBorderColor			borderColor;
1726e5c31af7Sopenharmony_ci				VK_FALSE,								//	VkBool32				unnormalizedCoordinates;
1727e5c31af7Sopenharmony_ci			};
1728e5c31af7Sopenharmony_ci
1729e5c31af7Sopenharmony_ci			// Create textures and samplers.
1730e5c31af7Sopenharmony_ci			for (size_t i = 0; i < kNumImages; ++i)
1731e5c31af7Sopenharmony_ci			{
1732e5c31af7Sopenharmony_ci				textures.emplace_back(new ImageWithMemory(vkd, device, alloc, imageCreateInfo, MemoryRequirement::Any));
1733e5c31af7Sopenharmony_ci				textureViews.emplace_back(makeImageView(vkd, device, textures.back()->get(), VK_IMAGE_VIEW_TYPE_2D, kImageFormat, imageSubresourceRange));
1734e5c31af7Sopenharmony_ci			}
1735e5c31af7Sopenharmony_ci
1736e5c31af7Sopenharmony_ci			for (size_t i = 0; i < kNumSamplers; ++i)
1737e5c31af7Sopenharmony_ci				samplers.emplace_back(createSampler(vkd, device, &samplerCreateInfo));
1738e5c31af7Sopenharmony_ci
1739e5c31af7Sopenharmony_ci			// Make sure texture data is available in the transfer stage.
1740e5c31af7Sopenharmony_ci			const auto textureDataBarrier = makeMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
1741e5c31af7Sopenharmony_ci			vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1u, &textureDataBarrier, 0u, nullptr, 0u, nullptr);
1742e5c31af7Sopenharmony_ci
1743e5c31af7Sopenharmony_ci			const auto bufferImageCopy = makeBufferImageCopy(kImageExtent, imageSubresourceLayers);
1744e5c31af7Sopenharmony_ci
1745e5c31af7Sopenharmony_ci			// Fill textures with data and prepare them for the ray tracing pipeline stages.
1746e5c31af7Sopenharmony_ci			for (size_t i = 0; i < kNumImages; ++i)
1747e5c31af7Sopenharmony_ci			{
1748e5c31af7Sopenharmony_ci				const auto texturePreCopyBarrier	= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, textures[i]->get(), imageSubresourceRange);
1749e5c31af7Sopenharmony_ci				const auto texturePostCopyBarrier	= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, textures[i]->get(), imageSubresourceRange);
1750e5c31af7Sopenharmony_ci
1751e5c31af7Sopenharmony_ci				vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &texturePreCopyBarrier);
1752e5c31af7Sopenharmony_ci				vkd.cmdCopyBufferToImage(cmdBuffer, textureData->get(), textures[i]->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopy);
1753e5c31af7Sopenharmony_ci				vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, 0u, 0u, nullptr, 0u, nullptr, 1u, &texturePostCopyBarrier);
1754e5c31af7Sopenharmony_ci			}
1755e5c31af7Sopenharmony_ci		}
1756e5c31af7Sopenharmony_ci		else if (storageImageNeeded(m_params.dataType))
1757e5c31af7Sopenharmony_ci		{
1758e5c31af7Sopenharmony_ci			// Image will be used for storage.
1759e5c31af7Sopenharmony_ci			imageCreateInfo.usage = kStorageImageUsage;
1760e5c31af7Sopenharmony_ci
1761e5c31af7Sopenharmony_ci			textures.emplace_back(new ImageWithMemory(vkd, device, alloc, imageCreateInfo, MemoryRequirement::Any));
1762e5c31af7Sopenharmony_ci			textureViews.emplace_back(makeImageView(vkd, device, textures.back()->get(), VK_IMAGE_VIEW_TYPE_2D, kImageFormat, imageSubresourceRange));
1763e5c31af7Sopenharmony_ci
1764e5c31af7Sopenharmony_ci			// Make sure texture data is available in the transfer stage.
1765e5c31af7Sopenharmony_ci			const auto textureDataBarrier = makeMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
1766e5c31af7Sopenharmony_ci			vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1u, &textureDataBarrier, 0u, nullptr, 0u, nullptr);
1767e5c31af7Sopenharmony_ci
1768e5c31af7Sopenharmony_ci			const auto bufferImageCopy			= makeBufferImageCopy(kImageExtent, imageSubresourceLayers);
1769e5c31af7Sopenharmony_ci			const auto texturePreCopyBarrier	= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, textures.back()->get(), imageSubresourceRange);
1770e5c31af7Sopenharmony_ci			const auto texturePostCopyBarrier	= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, (VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, textures.back()->get(), imageSubresourceRange);
1771e5c31af7Sopenharmony_ci
1772e5c31af7Sopenharmony_ci			// Fill texture with data and prepare them for the ray tracing pipeline stages.
1773e5c31af7Sopenharmony_ci			vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &texturePreCopyBarrier);
1774e5c31af7Sopenharmony_ci			vkd.cmdCopyBufferToImage(cmdBuffer, textureData->get(), textures.back()->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopy);
1775e5c31af7Sopenharmony_ci			vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, 0u, 0u, nullptr, 0u, nullptr, 1u, &texturePostCopyBarrier);
1776e5c31af7Sopenharmony_ci		}
1777e5c31af7Sopenharmony_ci		else
1778e5c31af7Sopenharmony_ci		{
1779e5c31af7Sopenharmony_ci			DE_ASSERT(false);
1780e5c31af7Sopenharmony_ci		}
1781e5c31af7Sopenharmony_ci	}
1782e5c31af7Sopenharmony_ci
1783e5c31af7Sopenharmony_ci	// Descriptor set layout.
1784e5c31af7Sopenharmony_ci	DescriptorSetLayoutBuilder dslBuilder;
1785e5c31af7Sopenharmony_ci	dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1u, shaderStages, nullptr);
1786e5c31af7Sopenharmony_ci	dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, shaderStages, nullptr);	// Callee buffer.
1787e5c31af7Sopenharmony_ci	dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, shaderStages, nullptr);	// Output buffer.
1788e5c31af7Sopenharmony_ci	dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, shaderStages, nullptr);	// Input buffer.
1789e5c31af7Sopenharmony_ci	if (samplersNeeded(m_params.dataType))
1790e5c31af7Sopenharmony_ci	{
1791e5c31af7Sopenharmony_ci		dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2u, shaderStages, nullptr);
1792e5c31af7Sopenharmony_ci		dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_SAMPLER, 2u, shaderStages, nullptr);
1793e5c31af7Sopenharmony_ci		dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, shaderStages, nullptr);
1794e5c31af7Sopenharmony_ci	}
1795e5c31af7Sopenharmony_ci	else if (storageImageNeeded(m_params.dataType))
1796e5c31af7Sopenharmony_ci	{
1797e5c31af7Sopenharmony_ci		dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1u, shaderStages, nullptr);
1798e5c31af7Sopenharmony_ci	}
1799e5c31af7Sopenharmony_ci	const auto descriptorSetLayout = dslBuilder.build(vkd, device);
1800e5c31af7Sopenharmony_ci
1801e5c31af7Sopenharmony_ci	// Pipeline layout.
1802e5c31af7Sopenharmony_ci	const auto pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
1803e5c31af7Sopenharmony_ci
1804e5c31af7Sopenharmony_ci	// Descriptor pool and set.
1805e5c31af7Sopenharmony_ci	DescriptorPoolBuilder poolBuilder;
1806e5c31af7Sopenharmony_ci	poolBuilder.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR);
1807e5c31af7Sopenharmony_ci	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3u);
1808e5c31af7Sopenharmony_ci	if (samplersNeeded(m_params.dataType))
1809e5c31af7Sopenharmony_ci	{
1810e5c31af7Sopenharmony_ci		poolBuilder.addType(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2u);
1811e5c31af7Sopenharmony_ci		poolBuilder.addType(VK_DESCRIPTOR_TYPE_SAMPLER, 2u);
1812e5c31af7Sopenharmony_ci		poolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u);
1813e5c31af7Sopenharmony_ci	}
1814e5c31af7Sopenharmony_ci	else if (storageImageNeeded(m_params.dataType))
1815e5c31af7Sopenharmony_ci	{
1816e5c31af7Sopenharmony_ci		poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1u);
1817e5c31af7Sopenharmony_ci	}
1818e5c31af7Sopenharmony_ci	const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1819e5c31af7Sopenharmony_ci	const auto descriptorSet = makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
1820e5c31af7Sopenharmony_ci
1821e5c31af7Sopenharmony_ci	// Update descriptor set.
1822e5c31af7Sopenharmony_ci	{
1823e5c31af7Sopenharmony_ci		const VkWriteDescriptorSetAccelerationStructureKHR writeASInfo =
1824e5c31af7Sopenharmony_ci		{
1825e5c31af7Sopenharmony_ci			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,
1826e5c31af7Sopenharmony_ci			nullptr,
1827e5c31af7Sopenharmony_ci			1u,
1828e5c31af7Sopenharmony_ci			topLevelAccelerationStructure.get()->getPtr(),
1829e5c31af7Sopenharmony_ci		};
1830e5c31af7Sopenharmony_ci
1831e5c31af7Sopenharmony_ci		DescriptorSetUpdateBuilder updateBuilder;
1832e5c31af7Sopenharmony_ci
1833e5c31af7Sopenharmony_ci		const auto ds = descriptorSet.get();
1834e5c31af7Sopenharmony_ci
1835e5c31af7Sopenharmony_ci		const auto calleeBufferDescriptorInfo	= makeDescriptorBufferInfo(calleeBuffer.get(), 0ull, VK_WHOLE_SIZE);
1836e5c31af7Sopenharmony_ci		const auto outputBufferDescriptorInfo	= makeDescriptorBufferInfo(outputBuffer.get(), 0ull, VK_WHOLE_SIZE);
1837e5c31af7Sopenharmony_ci		const auto inputBufferDescriptorInfo	= makeDescriptorBufferInfo(inputBuffer.get(), 0ull, VK_WHOLE_SIZE);
1838e5c31af7Sopenharmony_ci
1839e5c31af7Sopenharmony_ci		updateBuilder.writeSingle(ds, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &writeASInfo);
1840e5c31af7Sopenharmony_ci		updateBuilder.writeSingle(ds, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &calleeBufferDescriptorInfo);
1841e5c31af7Sopenharmony_ci		updateBuilder.writeSingle(ds, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputBufferDescriptorInfo);
1842e5c31af7Sopenharmony_ci		updateBuilder.writeSingle(ds, DescriptorSetUpdateBuilder::Location::binding(3u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputBufferDescriptorInfo);
1843e5c31af7Sopenharmony_ci
1844e5c31af7Sopenharmony_ci		if (samplersNeeded(m_params.dataType))
1845e5c31af7Sopenharmony_ci		{
1846e5c31af7Sopenharmony_ci			// Update textures, samplers and combined image samplers.
1847e5c31af7Sopenharmony_ci			std::vector<VkDescriptorImageInfo> textureDescInfos;
1848e5c31af7Sopenharmony_ci			std::vector<VkDescriptorImageInfo> textureSamplerInfos;
1849e5c31af7Sopenharmony_ci			std::vector<VkDescriptorImageInfo> combinedSamplerInfos;
1850e5c31af7Sopenharmony_ci
1851e5c31af7Sopenharmony_ci			for (size_t i = 0; i < kNumAloneImages; ++i)
1852e5c31af7Sopenharmony_ci				textureDescInfos.push_back(makeDescriptorImageInfo(DE_NULL, textureViews[i].get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
1853e5c31af7Sopenharmony_ci			for (size_t i = 0; i < kNumAloneSamplers; ++i)
1854e5c31af7Sopenharmony_ci				textureSamplerInfos.push_back(makeDescriptorImageInfo(samplers[i].get(), DE_NULL, VK_IMAGE_LAYOUT_UNDEFINED));
1855e5c31af7Sopenharmony_ci
1856e5c31af7Sopenharmony_ci			for (size_t i = 0; i < kNumCombined; ++i)
1857e5c31af7Sopenharmony_ci				combinedSamplerInfos.push_back(makeDescriptorImageInfo(samplers[i + kNumAloneSamplers].get(), textureViews[i + kNumAloneImages].get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
1858e5c31af7Sopenharmony_ci
1859e5c31af7Sopenharmony_ci			updateBuilder.writeArray(ds, DescriptorSetUpdateBuilder::Location::binding(4u), VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, kNumAloneImages, textureDescInfos.data());
1860e5c31af7Sopenharmony_ci			updateBuilder.writeArray(ds, DescriptorSetUpdateBuilder::Location::binding(5u), VK_DESCRIPTOR_TYPE_SAMPLER, kNumAloneSamplers, textureSamplerInfos.data());
1861e5c31af7Sopenharmony_ci			updateBuilder.writeArray(ds, DescriptorSetUpdateBuilder::Location::binding(6u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, kNumCombined, combinedSamplerInfos.data());
1862e5c31af7Sopenharmony_ci		}
1863e5c31af7Sopenharmony_ci		else if (storageImageNeeded(m_params.dataType))
1864e5c31af7Sopenharmony_ci		{
1865e5c31af7Sopenharmony_ci			const auto storageImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, textureViews.back().get(), VK_IMAGE_LAYOUT_GENERAL);
1866e5c31af7Sopenharmony_ci			updateBuilder.writeSingle(ds, DescriptorSetUpdateBuilder::Location::binding(4u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &storageImageDescriptorInfo);
1867e5c31af7Sopenharmony_ci		}
1868e5c31af7Sopenharmony_ci
1869e5c31af7Sopenharmony_ci		updateBuilder.update(vkd, device);
1870e5c31af7Sopenharmony_ci	}
1871e5c31af7Sopenharmony_ci
1872e5c31af7Sopenharmony_ci	// Create raytracing pipeline and shader binding tables.
1873e5c31af7Sopenharmony_ci	Move<VkPipeline>				pipeline;
1874e5c31af7Sopenharmony_ci
1875e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	raygenShaderBindingTable;
1876e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	missShaderBindingTable;
1877e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	hitShaderBindingTable;
1878e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	callableShaderBindingTable;
1879e5c31af7Sopenharmony_ci
1880e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR	raygenShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1881e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR	missShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1882e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR	hitShaderBindingTableRegion			= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1883e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR	callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1884e5c31af7Sopenharmony_ci
1885e5c31af7Sopenharmony_ci	{
1886e5c31af7Sopenharmony_ci		const auto rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
1887e5c31af7Sopenharmony_ci		const auto callType = m_params.callType;
1888e5c31af7Sopenharmony_ci
1889e5c31af7Sopenharmony_ci		// Every case uses a ray generation shader.
1890e5c31af7Sopenharmony_ci		rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("rgen"), 0), 0);
1891e5c31af7Sopenharmony_ci
1892e5c31af7Sopenharmony_ci		if (callType == CallType::TRACE_RAY)
1893e5c31af7Sopenharmony_ci		{
1894e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("chit"), 0), 1);
1895e5c31af7Sopenharmony_ci		}
1896e5c31af7Sopenharmony_ci		else if (callType == CallType::EXECUTE_CALLABLE)
1897e5c31af7Sopenharmony_ci		{
1898e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("call"), 0), 1);
1899e5c31af7Sopenharmony_ci		}
1900e5c31af7Sopenharmony_ci		else if (callType == CallType::REPORT_INTERSECTION)
1901e5c31af7Sopenharmony_ci		{
1902e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("rint"), 0), 1);
1903e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("ahit"), 0), 1);
1904e5c31af7Sopenharmony_ci		}
1905e5c31af7Sopenharmony_ci		else
1906e5c31af7Sopenharmony_ci		{
1907e5c31af7Sopenharmony_ci			DE_ASSERT(false);
1908e5c31af7Sopenharmony_ci		}
1909e5c31af7Sopenharmony_ci
1910e5c31af7Sopenharmony_ci		pipeline = rayTracingPipeline->createPipeline(vkd, device, pipelineLayout.get());
1911e5c31af7Sopenharmony_ci
1912e5c31af7Sopenharmony_ci		raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
1913e5c31af7Sopenharmony_ci		raygenShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
1914e5c31af7Sopenharmony_ci
1915e5c31af7Sopenharmony_ci		if (callType == CallType::EXECUTE_CALLABLE)
1916e5c31af7Sopenharmony_ci		{
1917e5c31af7Sopenharmony_ci			callableShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
1918e5c31af7Sopenharmony_ci			callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
1919e5c31af7Sopenharmony_ci		}
1920e5c31af7Sopenharmony_ci		else if (callType == CallType::TRACE_RAY || callType == CallType::REPORT_INTERSECTION)
1921e5c31af7Sopenharmony_ci		{
1922e5c31af7Sopenharmony_ci			hitShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
1923e5c31af7Sopenharmony_ci			hitShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
1924e5c31af7Sopenharmony_ci		}
1925e5c31af7Sopenharmony_ci		else
1926e5c31af7Sopenharmony_ci		{
1927e5c31af7Sopenharmony_ci			DE_ASSERT(false);
1928e5c31af7Sopenharmony_ci		}
1929e5c31af7Sopenharmony_ci	}
1930e5c31af7Sopenharmony_ci
1931e5c31af7Sopenharmony_ci	// Use ray tracing pipeline.
1932e5c31af7Sopenharmony_ci	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline.get());
1933e5c31af7Sopenharmony_ci	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr);
1934e5c31af7Sopenharmony_ci	vkd.cmdTraceRaysKHR(cmdBuffer, &raygenShaderBindingTableRegion, &missShaderBindingTableRegion, &hitShaderBindingTableRegion, &callableShaderBindingTableRegion, 1u, 1u, 1u);
1935e5c31af7Sopenharmony_ci
1936e5c31af7Sopenharmony_ci	// Synchronize output and callee buffers.
1937e5c31af7Sopenharmony_ci	const auto memBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
1938e5c31af7Sopenharmony_ci	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &memBarrier, 0u, nullptr, 0u, nullptr);
1939e5c31af7Sopenharmony_ci
1940e5c31af7Sopenharmony_ci	endCommandBuffer(vkd, cmdBuffer);
1941e5c31af7Sopenharmony_ci	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
1942e5c31af7Sopenharmony_ci
1943e5c31af7Sopenharmony_ci	// Verify output and callee buffers.
1944e5c31af7Sopenharmony_ci	invalidateAlloc(vkd, device, outputBufferAlloc);
1945e5c31af7Sopenharmony_ci	invalidateAlloc(vkd, device, calleeBufferAlloc);
1946e5c31af7Sopenharmony_ci
1947e5c31af7Sopenharmony_ci	std::map<std::string, void*> bufferPtrs;
1948e5c31af7Sopenharmony_ci	bufferPtrs["output"] = outputBufferPtr;
1949e5c31af7Sopenharmony_ci	bufferPtrs["callee"] = calleeBufferPtr;
1950e5c31af7Sopenharmony_ci
1951e5c31af7Sopenharmony_ci	for (const auto& ptr : bufferPtrs)
1952e5c31af7Sopenharmony_ci	{
1953e5c31af7Sopenharmony_ci		const auto& bufferName	= ptr.first;
1954e5c31af7Sopenharmony_ci		const auto& bufferPtr	= ptr.second;
1955e5c31af7Sopenharmony_ci
1956e5c31af7Sopenharmony_ci		deUint32 outputVal;
1957e5c31af7Sopenharmony_ci		deMemcpy(&outputVal, bufferPtr, sizeof(outputVal));
1958e5c31af7Sopenharmony_ci
1959e5c31af7Sopenharmony_ci		if (outputVal != 1u)
1960e5c31af7Sopenharmony_ci			return tcu::TestStatus::fail("Unexpected value found in " + bufferName + " buffer: " + de::toString(outputVal));
1961e5c31af7Sopenharmony_ci	}
1962e5c31af7Sopenharmony_ci
1963e5c31af7Sopenharmony_ci	return tcu::TestStatus::pass("Pass");
1964e5c31af7Sopenharmony_ci}
1965e5c31af7Sopenharmony_ci
1966e5c31af7Sopenharmony_cienum class InterfaceType
1967e5c31af7Sopenharmony_ci{
1968e5c31af7Sopenharmony_ci	RAY_PAYLOAD = 0,
1969e5c31af7Sopenharmony_ci	CALLABLE_DATA,
1970e5c31af7Sopenharmony_ci	HIT_ATTRIBUTES,
1971e5c31af7Sopenharmony_ci	SHADER_RECORD_BUFFER_RGEN,
1972e5c31af7Sopenharmony_ci	SHADER_RECORD_BUFFER_CALL,
1973e5c31af7Sopenharmony_ci	SHADER_RECORD_BUFFER_MISS,
1974e5c31af7Sopenharmony_ci	SHADER_RECORD_BUFFER_HIT,
1975e5c31af7Sopenharmony_ci};
1976e5c31af7Sopenharmony_ci
1977e5c31af7Sopenharmony_ci// Separate class to ease testing pipeline interface variables.
1978e5c31af7Sopenharmony_ciclass DataSpillPipelineInterfaceTestCase : public vkt::TestCase
1979e5c31af7Sopenharmony_ci{
1980e5c31af7Sopenharmony_cipublic:
1981e5c31af7Sopenharmony_ci	struct TestParams
1982e5c31af7Sopenharmony_ci	{
1983e5c31af7Sopenharmony_ci		InterfaceType	interfaceType;
1984e5c31af7Sopenharmony_ci	};
1985e5c31af7Sopenharmony_ci
1986e5c31af7Sopenharmony_ci							DataSpillPipelineInterfaceTestCase		(tcu::TestContext& testCtx, const std::string& name, const TestParams& testParams);
1987e5c31af7Sopenharmony_ci	virtual					~DataSpillPipelineInterfaceTestCase		(void) {}
1988e5c31af7Sopenharmony_ci
1989e5c31af7Sopenharmony_ci	virtual void			initPrograms							(vk::SourceCollections& programCollection) const;
1990e5c31af7Sopenharmony_ci	virtual TestInstance*	createInstance							(Context& context) const;
1991e5c31af7Sopenharmony_ci	virtual void			checkSupport							(Context& context) const;
1992e5c31af7Sopenharmony_ci
1993e5c31af7Sopenharmony_ciprivate:
1994e5c31af7Sopenharmony_ci	TestParams				m_params;
1995e5c31af7Sopenharmony_ci};
1996e5c31af7Sopenharmony_ci
1997e5c31af7Sopenharmony_ciclass DataSpillPipelineInterfaceTestInstance : public vkt::TestInstance
1998e5c31af7Sopenharmony_ci{
1999e5c31af7Sopenharmony_cipublic:
2000e5c31af7Sopenharmony_ci	using TestParams = DataSpillPipelineInterfaceTestCase::TestParams;
2001e5c31af7Sopenharmony_ci
2002e5c31af7Sopenharmony_ci						DataSpillPipelineInterfaceTestInstance	(Context& context, const TestParams& testParams);
2003e5c31af7Sopenharmony_ci						~DataSpillPipelineInterfaceTestInstance	(void) {}
2004e5c31af7Sopenharmony_ci
2005e5c31af7Sopenharmony_ci	tcu::TestStatus		iterate									(void);
2006e5c31af7Sopenharmony_ci
2007e5c31af7Sopenharmony_ciprivate:
2008e5c31af7Sopenharmony_ci	TestParams			m_params;
2009e5c31af7Sopenharmony_ci};
2010e5c31af7Sopenharmony_ci
2011e5c31af7Sopenharmony_ciDataSpillPipelineInterfaceTestCase::DataSpillPipelineInterfaceTestCase (tcu::TestContext& testCtx, const std::string& name, const TestParams& testParams)
2012e5c31af7Sopenharmony_ci	: vkt::TestCase	(testCtx, name)
2013e5c31af7Sopenharmony_ci	, m_params		(testParams)
2014e5c31af7Sopenharmony_ci{
2015e5c31af7Sopenharmony_ci}
2016e5c31af7Sopenharmony_ci
2017e5c31af7Sopenharmony_ciTestInstance* DataSpillPipelineInterfaceTestCase::createInstance (Context& context) const
2018e5c31af7Sopenharmony_ci{
2019e5c31af7Sopenharmony_ci	return new DataSpillPipelineInterfaceTestInstance (context, m_params);
2020e5c31af7Sopenharmony_ci}
2021e5c31af7Sopenharmony_ci
2022e5c31af7Sopenharmony_ciDataSpillPipelineInterfaceTestInstance::DataSpillPipelineInterfaceTestInstance (Context& context, const TestParams& testParams)
2023e5c31af7Sopenharmony_ci	: vkt::TestInstance	(context)
2024e5c31af7Sopenharmony_ci	, m_params			(testParams)
2025e5c31af7Sopenharmony_ci{
2026e5c31af7Sopenharmony_ci}
2027e5c31af7Sopenharmony_ci
2028e5c31af7Sopenharmony_civoid DataSpillPipelineInterfaceTestCase::checkSupport (Context& context) const
2029e5c31af7Sopenharmony_ci{
2030e5c31af7Sopenharmony_ci	commonCheckSupport(context);
2031e5c31af7Sopenharmony_ci}
2032e5c31af7Sopenharmony_ci
2033e5c31af7Sopenharmony_civoid DataSpillPipelineInterfaceTestCase::initPrograms (vk::SourceCollections& programCollection) const
2034e5c31af7Sopenharmony_ci{
2035e5c31af7Sopenharmony_ci	const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
2036e5c31af7Sopenharmony_ci
2037e5c31af7Sopenharmony_ci	const std::string glslHeader =
2038e5c31af7Sopenharmony_ci		"#version 460 core\n"
2039e5c31af7Sopenharmony_ci		"#extension GL_EXT_ray_tracing : require\n"
2040e5c31af7Sopenharmony_ci		;
2041e5c31af7Sopenharmony_ci
2042e5c31af7Sopenharmony_ci	const std::string glslBindings =
2043e5c31af7Sopenharmony_ci		"layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
2044e5c31af7Sopenharmony_ci		"layout(set = 0, binding = 1) buffer StorageBlock { uint val[" + std::to_string(kNumStorageValues) + "]; } storageBuffer;\n"
2045e5c31af7Sopenharmony_ci		;
2046e5c31af7Sopenharmony_ci
2047e5c31af7Sopenharmony_ci	if (m_params.interfaceType == InterfaceType::RAY_PAYLOAD)
2048e5c31af7Sopenharmony_ci	{
2049e5c31af7Sopenharmony_ci		// The closest hit shader will store 100 in the second array position.
2050e5c31af7Sopenharmony_ci		// The ray gen shader will store 103 in the first array position using the hitValue after the traceRayExt() call.
2051e5c31af7Sopenharmony_ci
2052e5c31af7Sopenharmony_ci		std::ostringstream rgen;
2053e5c31af7Sopenharmony_ci		rgen
2054e5c31af7Sopenharmony_ci			<< glslHeader
2055e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
2056e5c31af7Sopenharmony_ci			<< glslBindings
2057e5c31af7Sopenharmony_ci			<< "void main()\n"
2058e5c31af7Sopenharmony_ci			<< "{\n"
2059e5c31af7Sopenharmony_ci			<< "  hitValue = vec3(10.0, 30.0, 60.0);\n"
2060e5c31af7Sopenharmony_ci			<< "  traceRayEXT(topLevelAS, 0u, 0xFFu, 0, 0, 0, vec3(0.5, 0.5, 0.0), 0.0, vec3(0.0, 0.0, -1.0), 9.0, 0);\n"
2061e5c31af7Sopenharmony_ci			<< "  storageBuffer.val[0] = uint(hitValue.x + hitValue.y + hitValue.z);\n"
2062e5c31af7Sopenharmony_ci			<< "}\n"
2063e5c31af7Sopenharmony_ci			;
2064e5c31af7Sopenharmony_ci		programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions;
2065e5c31af7Sopenharmony_ci
2066e5c31af7Sopenharmony_ci		std::stringstream chit;
2067e5c31af7Sopenharmony_ci		chit
2068e5c31af7Sopenharmony_ci			<< glslHeader
2069e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
2070e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec3 attribs;\n"
2071e5c31af7Sopenharmony_ci			<< glslBindings
2072e5c31af7Sopenharmony_ci			<< "void main()\n"
2073e5c31af7Sopenharmony_ci			<< "{\n"
2074e5c31af7Sopenharmony_ci			<< "  storageBuffer.val[1] = uint(hitValue.x + hitValue.y + hitValue.z);\n"
2075e5c31af7Sopenharmony_ci			<< "  hitValue = vec3(hitValue.x + 1.0, hitValue.y + 1.0, hitValue.z + 1.0);\n"
2076e5c31af7Sopenharmony_ci			<< "}\n"
2077e5c31af7Sopenharmony_ci			;
2078e5c31af7Sopenharmony_ci		programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(chit.str())) << buildOptions;
2079e5c31af7Sopenharmony_ci	}
2080e5c31af7Sopenharmony_ci	else if (m_params.interfaceType == InterfaceType::CALLABLE_DATA)
2081e5c31af7Sopenharmony_ci	{
2082e5c31af7Sopenharmony_ci		// The callable shader shader will store 100 in the second array position.
2083e5c31af7Sopenharmony_ci		// The ray gen shader will store 200 in the first array position using the callable data after the executeCallableEXT() call.
2084e5c31af7Sopenharmony_ci
2085e5c31af7Sopenharmony_ci		std::ostringstream rgen;
2086e5c31af7Sopenharmony_ci		rgen
2087e5c31af7Sopenharmony_ci			<< glslHeader
2088e5c31af7Sopenharmony_ci			<< "layout(location = 0) callableDataEXT float callableData;\n"
2089e5c31af7Sopenharmony_ci			<< glslBindings
2090e5c31af7Sopenharmony_ci			<< "void main()\n"
2091e5c31af7Sopenharmony_ci			<< "{\n"
2092e5c31af7Sopenharmony_ci			<< "  callableData = 100.0;\n"
2093e5c31af7Sopenharmony_ci			<< "  executeCallableEXT(0, 0);\n"
2094e5c31af7Sopenharmony_ci			<< "  storageBuffer.val[0] = uint(callableData);\n"
2095e5c31af7Sopenharmony_ci			<< "}\n"
2096e5c31af7Sopenharmony_ci			;
2097e5c31af7Sopenharmony_ci		programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions;
2098e5c31af7Sopenharmony_ci
2099e5c31af7Sopenharmony_ci		std::ostringstream call;
2100e5c31af7Sopenharmony_ci		call
2101e5c31af7Sopenharmony_ci			<< glslHeader
2102e5c31af7Sopenharmony_ci			<< "layout(location = 0) callableDataInEXT float callableData;\n"
2103e5c31af7Sopenharmony_ci			<< glslBindings
2104e5c31af7Sopenharmony_ci			<< "void main()\n"
2105e5c31af7Sopenharmony_ci			<< "{\n"
2106e5c31af7Sopenharmony_ci			<< "    storageBuffer.val[1] = uint(callableData);\n"
2107e5c31af7Sopenharmony_ci			<< "    callableData = callableData * 2.0;\n"
2108e5c31af7Sopenharmony_ci			<< "}\n"
2109e5c31af7Sopenharmony_ci			;
2110e5c31af7Sopenharmony_ci
2111e5c31af7Sopenharmony_ci		programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(call.str())) << buildOptions;
2112e5c31af7Sopenharmony_ci	}
2113e5c31af7Sopenharmony_ci	else if (m_params.interfaceType == InterfaceType::HIT_ATTRIBUTES)
2114e5c31af7Sopenharmony_ci	{
2115e5c31af7Sopenharmony_ci		// The ray gen shader will store value 300 in the first storage buffer position.
2116e5c31af7Sopenharmony_ci		// The intersection shader will store value 315 in the second storage buffer position.
2117e5c31af7Sopenharmony_ci		// The closes hit shader will store value 330 in the third storage buffer position using the hit attributes.
2118e5c31af7Sopenharmony_ci
2119e5c31af7Sopenharmony_ci		std::ostringstream rgen;
2120e5c31af7Sopenharmony_ci		rgen
2121e5c31af7Sopenharmony_ci			<< glslHeader
2122e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
2123e5c31af7Sopenharmony_ci			<< glslBindings
2124e5c31af7Sopenharmony_ci			<< "void main()\n"
2125e5c31af7Sopenharmony_ci			<< "{\n"
2126e5c31af7Sopenharmony_ci			<< "  traceRayEXT(topLevelAS, 0u, 0xFFu, 0, 0, 0, vec3(0.5, 0.5, 0.0), 0.0, vec3(0.0, 0.0, -1.0), 9.0, 0);\n"
2127e5c31af7Sopenharmony_ci			<< "  storageBuffer.val[0] = 300u;\n"
2128e5c31af7Sopenharmony_ci			<< "}\n"
2129e5c31af7Sopenharmony_ci			;
2130e5c31af7Sopenharmony_ci		programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions;
2131e5c31af7Sopenharmony_ci
2132e5c31af7Sopenharmony_ci		std::stringstream rint;
2133e5c31af7Sopenharmony_ci		rint
2134e5c31af7Sopenharmony_ci			<< glslHeader
2135e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec3 attribs;\n"
2136e5c31af7Sopenharmony_ci			<< glslBindings
2137e5c31af7Sopenharmony_ci			<< "void main()\n"
2138e5c31af7Sopenharmony_ci			<< "{\n"
2139e5c31af7Sopenharmony_ci			<< "  attribs = vec3(140.0, 160.0, 30.0);\n"
2140e5c31af7Sopenharmony_ci			<< "  storageBuffer.val[1] = 315u;\n"
2141e5c31af7Sopenharmony_ci			<< "  reportIntersectionEXT(1.0f, 0);\n"
2142e5c31af7Sopenharmony_ci			<< "}\n"
2143e5c31af7Sopenharmony_ci			;
2144e5c31af7Sopenharmony_ci
2145e5c31af7Sopenharmony_ci		programCollection.glslSources.add("rint") << glu::IntersectionSource(updateRayTracingGLSL(rint.str())) << buildOptions;
2146e5c31af7Sopenharmony_ci
2147e5c31af7Sopenharmony_ci		std::stringstream chit;
2148e5c31af7Sopenharmony_ci		chit
2149e5c31af7Sopenharmony_ci			<< glslHeader
2150e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
2151e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec3 attribs;\n"
2152e5c31af7Sopenharmony_ci			<< glslBindings
2153e5c31af7Sopenharmony_ci			<< "void main()\n"
2154e5c31af7Sopenharmony_ci			<< "{\n"
2155e5c31af7Sopenharmony_ci			<< "  storageBuffer.val[2] = uint(attribs.x + attribs.y + attribs.z);\n"
2156e5c31af7Sopenharmony_ci			<< "}\n"
2157e5c31af7Sopenharmony_ci			;
2158e5c31af7Sopenharmony_ci		programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(chit.str())) << buildOptions;
2159e5c31af7Sopenharmony_ci
2160e5c31af7Sopenharmony_ci	}
2161e5c31af7Sopenharmony_ci	else if (m_params.interfaceType == InterfaceType::SHADER_RECORD_BUFFER_RGEN)
2162e5c31af7Sopenharmony_ci	{
2163e5c31af7Sopenharmony_ci		// The ray gen shader will have a uvec4 in the shader record buffer with contents 400, 401, 402, 403.
2164e5c31af7Sopenharmony_ci		// The shader will call a callable shader indicating a position in that vec4 (0, 1, 2, 3). For example, let's use position 1.
2165e5c31af7Sopenharmony_ci		// The callable shader will return the indicated position+1 modulo 4, so it will return 2 in our case.
2166e5c31af7Sopenharmony_ci		// *After* returning from the callable shader, the raygen shader will use that reply to access position 2 and write a 402 in the first output buffer position.
2167e5c31af7Sopenharmony_ci		// The callable shader will store 450 in the second output buffer position.
2168e5c31af7Sopenharmony_ci
2169e5c31af7Sopenharmony_ci		std::ostringstream rgen;
2170e5c31af7Sopenharmony_ci		rgen
2171e5c31af7Sopenharmony_ci			<< glslHeader
2172e5c31af7Sopenharmony_ci			<< "layout(shaderRecordEXT) buffer ShaderRecordStruct {\n"
2173e5c31af7Sopenharmony_ci			<< "  uvec4 info;\n"
2174e5c31af7Sopenharmony_ci			<< "};\n"
2175e5c31af7Sopenharmony_ci			<< "layout(location = 0) callableDataEXT uint callableData;\n"
2176e5c31af7Sopenharmony_ci			<< glslBindings
2177e5c31af7Sopenharmony_ci			<< "void main()\n"
2178e5c31af7Sopenharmony_ci			<< "{\n"
2179e5c31af7Sopenharmony_ci			<< "  callableData = 1u;"
2180e5c31af7Sopenharmony_ci			<< "  executeCallableEXT(0, 0);\n"
2181e5c31af7Sopenharmony_ci			<< "  if      (callableData == 0u) storageBuffer.val[0] = info.x;\n"
2182e5c31af7Sopenharmony_ci			<< "  else if (callableData == 1u) storageBuffer.val[0] = info.y;\n"
2183e5c31af7Sopenharmony_ci			<< "  else if (callableData == 2u) storageBuffer.val[0] = info.z;\n"
2184e5c31af7Sopenharmony_ci			<< "  else if (callableData == 3u) storageBuffer.val[0] = info.w;\n"
2185e5c31af7Sopenharmony_ci			<< "}\n"
2186e5c31af7Sopenharmony_ci			;
2187e5c31af7Sopenharmony_ci		programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions;
2188e5c31af7Sopenharmony_ci
2189e5c31af7Sopenharmony_ci		std::ostringstream call;
2190e5c31af7Sopenharmony_ci		call
2191e5c31af7Sopenharmony_ci			<< glslHeader
2192e5c31af7Sopenharmony_ci			<< "layout(location = 0) callableDataInEXT uint callableData;\n"
2193e5c31af7Sopenharmony_ci			<< glslBindings
2194e5c31af7Sopenharmony_ci			<< "void main()\n"
2195e5c31af7Sopenharmony_ci			<< "{\n"
2196e5c31af7Sopenharmony_ci			<< "    storageBuffer.val[1] = 450u;\n"
2197e5c31af7Sopenharmony_ci			<< "    callableData = (callableData + 1u) % 4u;\n"
2198e5c31af7Sopenharmony_ci			<< "}\n"
2199e5c31af7Sopenharmony_ci			;
2200e5c31af7Sopenharmony_ci
2201e5c31af7Sopenharmony_ci		programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(call.str())) << buildOptions;
2202e5c31af7Sopenharmony_ci	}
2203e5c31af7Sopenharmony_ci	else if (m_params.interfaceType == InterfaceType::SHADER_RECORD_BUFFER_CALL)
2204e5c31af7Sopenharmony_ci	{
2205e5c31af7Sopenharmony_ci		// Similar to the previous case, with a twist:
2206e5c31af7Sopenharmony_ci		//   * rgen passes the vector position.
2207e5c31af7Sopenharmony_ci		//   * call increases that by one.
2208e5c31af7Sopenharmony_ci		//   * subcall increases again and does the modulo operation, also writing 450 in the third output buffer value.
2209e5c31af7Sopenharmony_ci		//   * call is the one accessing the vector at the returned position, writing 403 in this case to the second output buffer value.
2210e5c31af7Sopenharmony_ci		//   * call passes this value back doubled to rgen, which writes it to the first output buffer value (806).
2211e5c31af7Sopenharmony_ci
2212e5c31af7Sopenharmony_ci		std::ostringstream rgen;
2213e5c31af7Sopenharmony_ci		rgen
2214e5c31af7Sopenharmony_ci			<< glslHeader
2215e5c31af7Sopenharmony_ci			<< "layout(location = 0) callableDataEXT uint callableData;\n"
2216e5c31af7Sopenharmony_ci			<< glslBindings
2217e5c31af7Sopenharmony_ci			<< "void main()\n"
2218e5c31af7Sopenharmony_ci			<< "{\n"
2219e5c31af7Sopenharmony_ci			<< "  callableData = 1u;\n"
2220e5c31af7Sopenharmony_ci			<< "  executeCallableEXT(0, 0);\n"
2221e5c31af7Sopenharmony_ci			<< "  storageBuffer.val[0] = callableData;\n"
2222e5c31af7Sopenharmony_ci			<< "}\n"
2223e5c31af7Sopenharmony_ci			;
2224e5c31af7Sopenharmony_ci		programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions;
2225e5c31af7Sopenharmony_ci
2226e5c31af7Sopenharmony_ci		std::ostringstream call;
2227e5c31af7Sopenharmony_ci		call
2228e5c31af7Sopenharmony_ci			<< glslHeader
2229e5c31af7Sopenharmony_ci			<< "layout(shaderRecordEXT) buffer ShaderRecordStruct {\n"
2230e5c31af7Sopenharmony_ci			<< "  uvec4 info;\n"
2231e5c31af7Sopenharmony_ci			<< "};\n"
2232e5c31af7Sopenharmony_ci			<< "layout(location = 0) callableDataInEXT uint callableDataIn;\n"
2233e5c31af7Sopenharmony_ci			<< "layout(location = 1) callableDataEXT uint callableDataOut;\n"
2234e5c31af7Sopenharmony_ci			<< glslBindings
2235e5c31af7Sopenharmony_ci			<< "void main()\n"
2236e5c31af7Sopenharmony_ci			<< "{\n"
2237e5c31af7Sopenharmony_ci			<< "  callableDataOut = callableDataIn + 1u;\n"
2238e5c31af7Sopenharmony_ci			<< "  executeCallableEXT(1, 1);\n"
2239e5c31af7Sopenharmony_ci			<< "  uint outputBufferValue = 777u;\n"
2240e5c31af7Sopenharmony_ci			<< "  if      (callableDataOut == 0u) outputBufferValue = info.x;\n"
2241e5c31af7Sopenharmony_ci			<< "  else if (callableDataOut == 1u) outputBufferValue = info.y;\n"
2242e5c31af7Sopenharmony_ci			<< "  else if (callableDataOut == 2u) outputBufferValue = info.z;\n"
2243e5c31af7Sopenharmony_ci			<< "  else if (callableDataOut == 3u) outputBufferValue = info.w;\n"
2244e5c31af7Sopenharmony_ci			<< "  storageBuffer.val[1] = outputBufferValue;\n"
2245e5c31af7Sopenharmony_ci			<< "  callableDataIn = outputBufferValue * 2u;\n"
2246e5c31af7Sopenharmony_ci			<< "}\n"
2247e5c31af7Sopenharmony_ci			;
2248e5c31af7Sopenharmony_ci
2249e5c31af7Sopenharmony_ci		programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(call.str())) << buildOptions;
2250e5c31af7Sopenharmony_ci
2251e5c31af7Sopenharmony_ci		std::ostringstream subcall;
2252e5c31af7Sopenharmony_ci		subcall
2253e5c31af7Sopenharmony_ci			<< glslHeader
2254e5c31af7Sopenharmony_ci			<< "layout(location = 1) callableDataInEXT uint callableData;\n"
2255e5c31af7Sopenharmony_ci			<< glslBindings
2256e5c31af7Sopenharmony_ci			<< "void main()\n"
2257e5c31af7Sopenharmony_ci			<< "{\n"
2258e5c31af7Sopenharmony_ci			<< "  callableData = (callableData + 1u) % 4u;\n"
2259e5c31af7Sopenharmony_ci			<< "  storageBuffer.val[2] = 450u;\n"
2260e5c31af7Sopenharmony_ci			<< "}\n"
2261e5c31af7Sopenharmony_ci			;
2262e5c31af7Sopenharmony_ci
2263e5c31af7Sopenharmony_ci		programCollection.glslSources.add("subcall") << glu::CallableSource(updateRayTracingGLSL(subcall.str())) << buildOptions;
2264e5c31af7Sopenharmony_ci	}
2265e5c31af7Sopenharmony_ci	else if (m_params.interfaceType == InterfaceType::SHADER_RECORD_BUFFER_MISS || m_params.interfaceType == InterfaceType::SHADER_RECORD_BUFFER_HIT)
2266e5c31af7Sopenharmony_ci	{
2267e5c31af7Sopenharmony_ci		// Similar to the previous one, but the intermediate call shader has been replaced with a miss or closest hit shader.
2268e5c31af7Sopenharmony_ci		// The rgen shader will communicate with the miss/chit shader using the ray payload instead of the callable data.
2269e5c31af7Sopenharmony_ci		// Also, the initial position will be 2, so it will wrap around in this case. The numbers will also change.
2270e5c31af7Sopenharmony_ci
2271e5c31af7Sopenharmony_ci		std::ostringstream rgen;
2272e5c31af7Sopenharmony_ci		rgen
2273e5c31af7Sopenharmony_ci			<< glslHeader
2274e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadEXT uint rayPayload;\n"
2275e5c31af7Sopenharmony_ci			<< glslBindings
2276e5c31af7Sopenharmony_ci			<< "void main()\n"
2277e5c31af7Sopenharmony_ci			<< "{\n"
2278e5c31af7Sopenharmony_ci			<< "  rayPayload = 2u;\n"
2279e5c31af7Sopenharmony_ci			<< "  traceRayEXT(topLevelAS, 0u, 0xFFu, 0, 0, 0, vec3(0.5, 0.5, 0.0), 0.0, vec3(0.0, 0.0, -1.0), 9.0, 0);\n"
2280e5c31af7Sopenharmony_ci			<< "  storageBuffer.val[0] = rayPayload;\n"
2281e5c31af7Sopenharmony_ci			<< "}\n"
2282e5c31af7Sopenharmony_ci			;
2283e5c31af7Sopenharmony_ci		programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions;
2284e5c31af7Sopenharmony_ci
2285e5c31af7Sopenharmony_ci		std::ostringstream chitOrMiss;
2286e5c31af7Sopenharmony_ci		chitOrMiss
2287e5c31af7Sopenharmony_ci			<< glslHeader
2288e5c31af7Sopenharmony_ci			<< "layout(shaderRecordEXT) buffer ShaderRecordStruct {\n"
2289e5c31af7Sopenharmony_ci			<< "  uvec4 info;\n"
2290e5c31af7Sopenharmony_ci			<< "};\n"
2291e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT uint rayPayload;\n"
2292e5c31af7Sopenharmony_ci			<< "layout(location = 0) callableDataEXT uint callableData;\n"
2293e5c31af7Sopenharmony_ci			<< glslBindings
2294e5c31af7Sopenharmony_ci			<< "void main()\n"
2295e5c31af7Sopenharmony_ci			<< "{\n"
2296e5c31af7Sopenharmony_ci			<< "  callableData = rayPayload + 1u;\n"
2297e5c31af7Sopenharmony_ci			<< "  executeCallableEXT(0, 0);\n"
2298e5c31af7Sopenharmony_ci			<< "  uint outputBufferValue = 777u;\n"
2299e5c31af7Sopenharmony_ci			<< "  if      (callableData == 0u) outputBufferValue = info.x;\n"
2300e5c31af7Sopenharmony_ci			<< "  else if (callableData == 1u) outputBufferValue = info.y;\n"
2301e5c31af7Sopenharmony_ci			<< "  else if (callableData == 2u) outputBufferValue = info.z;\n"
2302e5c31af7Sopenharmony_ci			<< "  else if (callableData == 3u) outputBufferValue = info.w;\n"
2303e5c31af7Sopenharmony_ci			<< "  storageBuffer.val[1] = outputBufferValue;\n"
2304e5c31af7Sopenharmony_ci			<< "  rayPayload = outputBufferValue * 3u;\n"
2305e5c31af7Sopenharmony_ci			<< "}\n"
2306e5c31af7Sopenharmony_ci			;
2307e5c31af7Sopenharmony_ci
2308e5c31af7Sopenharmony_ci		if (m_params.interfaceType == InterfaceType::SHADER_RECORD_BUFFER_MISS)
2309e5c31af7Sopenharmony_ci			programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(chitOrMiss.str())) << buildOptions;
2310e5c31af7Sopenharmony_ci		else if (m_params.interfaceType == InterfaceType::SHADER_RECORD_BUFFER_HIT)
2311e5c31af7Sopenharmony_ci			programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(chitOrMiss.str())) << buildOptions;
2312e5c31af7Sopenharmony_ci		else
2313e5c31af7Sopenharmony_ci			DE_ASSERT(false);
2314e5c31af7Sopenharmony_ci
2315e5c31af7Sopenharmony_ci		std::ostringstream call;
2316e5c31af7Sopenharmony_ci		call
2317e5c31af7Sopenharmony_ci			<< glslHeader
2318e5c31af7Sopenharmony_ci			<< "layout(location = 0) callableDataInEXT uint callableData;\n"
2319e5c31af7Sopenharmony_ci			<< glslBindings
2320e5c31af7Sopenharmony_ci			<< "void main()\n"
2321e5c31af7Sopenharmony_ci			<< "{\n"
2322e5c31af7Sopenharmony_ci			<< "    storageBuffer.val[2] = 490u;\n"
2323e5c31af7Sopenharmony_ci			<< "    callableData = (callableData + 1u) % 4u;\n"
2324e5c31af7Sopenharmony_ci			<< "}\n"
2325e5c31af7Sopenharmony_ci			;
2326e5c31af7Sopenharmony_ci
2327e5c31af7Sopenharmony_ci		programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(call.str())) << buildOptions;
2328e5c31af7Sopenharmony_ci	}
2329e5c31af7Sopenharmony_ci	else
2330e5c31af7Sopenharmony_ci	{
2331e5c31af7Sopenharmony_ci		DE_ASSERT(false);
2332e5c31af7Sopenharmony_ci	}
2333e5c31af7Sopenharmony_ci}
2334e5c31af7Sopenharmony_ci
2335e5c31af7Sopenharmony_ciVkShaderStageFlags getShaderStages (InterfaceType type_)
2336e5c31af7Sopenharmony_ci{
2337e5c31af7Sopenharmony_ci	VkShaderStageFlags flags = VK_SHADER_STAGE_RAYGEN_BIT_KHR;
2338e5c31af7Sopenharmony_ci
2339e5c31af7Sopenharmony_ci	switch (type_)
2340e5c31af7Sopenharmony_ci	{
2341e5c31af7Sopenharmony_ci	case InterfaceType::HIT_ATTRIBUTES:
2342e5c31af7Sopenharmony_ci		flags |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
2343e5c31af7Sopenharmony_ci		// fallthrough.
2344e5c31af7Sopenharmony_ci	case InterfaceType::RAY_PAYLOAD:
2345e5c31af7Sopenharmony_ci		flags |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
2346e5c31af7Sopenharmony_ci		break;
2347e5c31af7Sopenharmony_ci	case InterfaceType::CALLABLE_DATA:
2348e5c31af7Sopenharmony_ci	case InterfaceType::SHADER_RECORD_BUFFER_RGEN:
2349e5c31af7Sopenharmony_ci	case InterfaceType::SHADER_RECORD_BUFFER_CALL:
2350e5c31af7Sopenharmony_ci		flags |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
2351e5c31af7Sopenharmony_ci		break;
2352e5c31af7Sopenharmony_ci	case InterfaceType::SHADER_RECORD_BUFFER_MISS:
2353e5c31af7Sopenharmony_ci		flags |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
2354e5c31af7Sopenharmony_ci		flags |= VK_SHADER_STAGE_MISS_BIT_KHR;
2355e5c31af7Sopenharmony_ci		break;
2356e5c31af7Sopenharmony_ci	case InterfaceType::SHADER_RECORD_BUFFER_HIT:
2357e5c31af7Sopenharmony_ci		flags |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
2358e5c31af7Sopenharmony_ci		flags |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
2359e5c31af7Sopenharmony_ci		break;
2360e5c31af7Sopenharmony_ci	default:
2361e5c31af7Sopenharmony_ci		DE_ASSERT(false);
2362e5c31af7Sopenharmony_ci		break;
2363e5c31af7Sopenharmony_ci	}
2364e5c31af7Sopenharmony_ci
2365e5c31af7Sopenharmony_ci	return flags;
2366e5c31af7Sopenharmony_ci}
2367e5c31af7Sopenharmony_ci
2368e5c31af7Sopenharmony_ci// Proper stage for generating default geometry.
2369e5c31af7Sopenharmony_ciVkShaderStageFlagBits getShaderStageForGeometry (InterfaceType type_)
2370e5c31af7Sopenharmony_ci{
2371e5c31af7Sopenharmony_ci	VkShaderStageFlagBits bits = VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM;
2372e5c31af7Sopenharmony_ci
2373e5c31af7Sopenharmony_ci	switch (type_)
2374e5c31af7Sopenharmony_ci	{
2375e5c31af7Sopenharmony_ci	case InterfaceType::HIT_ATTRIBUTES:				bits = VK_SHADER_STAGE_INTERSECTION_BIT_KHR;	break;
2376e5c31af7Sopenharmony_ci	case InterfaceType::RAY_PAYLOAD:				bits = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;		break;
2377e5c31af7Sopenharmony_ci	case InterfaceType::CALLABLE_DATA:				bits = VK_SHADER_STAGE_CALLABLE_BIT_KHR;		break;
2378e5c31af7Sopenharmony_ci	case InterfaceType::SHADER_RECORD_BUFFER_RGEN:	bits = VK_SHADER_STAGE_CALLABLE_BIT_KHR;		break;
2379e5c31af7Sopenharmony_ci	case InterfaceType::SHADER_RECORD_BUFFER_CALL:	bits = VK_SHADER_STAGE_CALLABLE_BIT_KHR;		break;
2380e5c31af7Sopenharmony_ci	case InterfaceType::SHADER_RECORD_BUFFER_MISS:	bits = VK_SHADER_STAGE_MISS_BIT_KHR;			break;
2381e5c31af7Sopenharmony_ci	case InterfaceType::SHADER_RECORD_BUFFER_HIT:	bits = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;		break;
2382e5c31af7Sopenharmony_ci	default: DE_ASSERT(false); break;
2383e5c31af7Sopenharmony_ci	}
2384e5c31af7Sopenharmony_ci
2385e5c31af7Sopenharmony_ci	DE_ASSERT(bits != VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM);
2386e5c31af7Sopenharmony_ci	return bits;
2387e5c31af7Sopenharmony_ci}
2388e5c31af7Sopenharmony_ci
2389e5c31af7Sopenharmony_civoid createSBTWithShaderRecord (const DeviceInterface& vkd, VkDevice device, vk::Allocator &alloc,
2390e5c31af7Sopenharmony_ci								VkPipeline pipeline, RayTracingPipeline* rayTracingPipeline,
2391e5c31af7Sopenharmony_ci								deUint32 shaderGroupHandleSize, deUint32 shaderGroupBaseAlignment,
2392e5c31af7Sopenharmony_ci								deUint32 firstGroup, deUint32 groupCount,
2393e5c31af7Sopenharmony_ci								de::MovePtr<BufferWithMemory>& shaderBindingTable,
2394e5c31af7Sopenharmony_ci								VkStridedDeviceAddressRegionKHR& shaderBindingTableRegion)
2395e5c31af7Sopenharmony_ci{
2396e5c31af7Sopenharmony_ci	const auto alignedSize		= de::roundUp(shaderGroupHandleSize + kShaderRecordSize, shaderGroupHandleSize);
2397e5c31af7Sopenharmony_ci	shaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, firstGroup, groupCount, 0u, 0u, MemoryRequirement::Any, 0u, 0u, kShaderRecordSize);
2398e5c31af7Sopenharmony_ci	shaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, shaderBindingTable->get(), 0), alignedSize, groupCount * alignedSize);
2399e5c31af7Sopenharmony_ci
2400e5c31af7Sopenharmony_ci	// Fill shader record buffer data.
2401e5c31af7Sopenharmony_ci	// Note we will only fill the first shader record after the handle.
2402e5c31af7Sopenharmony_ci	const tcu::UVec4	shaderRecordData	(400u, 401u, 402u, 403u);
2403e5c31af7Sopenharmony_ci	auto&				sbtAlloc			= shaderBindingTable->getAllocation();
2404e5c31af7Sopenharmony_ci	auto*				dataPtr				= reinterpret_cast<deUint8*>(sbtAlloc.getHostPtr()) + shaderGroupHandleSize;
2405e5c31af7Sopenharmony_ci
2406e5c31af7Sopenharmony_ci	DE_STATIC_ASSERT(sizeof(shaderRecordData) == static_cast<size_t>(kShaderRecordSize));
2407e5c31af7Sopenharmony_ci	deMemcpy(dataPtr, &shaderRecordData, sizeof(shaderRecordData));
2408e5c31af7Sopenharmony_ci}
2409e5c31af7Sopenharmony_ci
2410e5c31af7Sopenharmony_citcu::TestStatus DataSpillPipelineInterfaceTestInstance::iterate (void)
2411e5c31af7Sopenharmony_ci{
2412e5c31af7Sopenharmony_ci	const auto& vki						= m_context.getInstanceInterface();
2413e5c31af7Sopenharmony_ci	const auto	physicalDevice			= m_context.getPhysicalDevice();
2414e5c31af7Sopenharmony_ci	const auto&	vkd						= m_context.getDeviceInterface();
2415e5c31af7Sopenharmony_ci	const auto	device					= m_context.getDevice();
2416e5c31af7Sopenharmony_ci	const auto	queue					= m_context.getUniversalQueue();
2417e5c31af7Sopenharmony_ci	const auto	familyIndex				= m_context.getUniversalQueueFamilyIndex();
2418e5c31af7Sopenharmony_ci	auto&		alloc					= m_context.getDefaultAllocator();
2419e5c31af7Sopenharmony_ci	const auto	shaderStages			= getShaderStages(m_params.interfaceType);
2420e5c31af7Sopenharmony_ci
2421e5c31af7Sopenharmony_ci	// Command buffer.
2422e5c31af7Sopenharmony_ci	const auto cmdPool		= makeCommandPool(vkd, device, familyIndex);
2423e5c31af7Sopenharmony_ci	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
2424e5c31af7Sopenharmony_ci	const auto cmdBuffer	= cmdBufferPtr.get();
2425e5c31af7Sopenharmony_ci
2426e5c31af7Sopenharmony_ci	beginCommandBuffer(vkd, cmdBuffer);
2427e5c31af7Sopenharmony_ci
2428e5c31af7Sopenharmony_ci	// Storage buffer.
2429e5c31af7Sopenharmony_ci	std::array<deUint32, kNumStorageValues>	storageBufferData;
2430e5c31af7Sopenharmony_ci	const auto								storageBufferSize	= de::dataSize(storageBufferData);
2431e5c31af7Sopenharmony_ci	const auto								storagebufferInfo	= makeBufferCreateInfo(storageBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2432e5c31af7Sopenharmony_ci	BufferWithMemory						storageBuffer		(vkd, device, alloc, storagebufferInfo, MemoryRequirement::HostVisible);
2433e5c31af7Sopenharmony_ci
2434e5c31af7Sopenharmony_ci	// Zero-out buffer.
2435e5c31af7Sopenharmony_ci	auto& storageBufferAlloc	= storageBuffer.getAllocation();
2436e5c31af7Sopenharmony_ci	auto* storageBufferPtr		= storageBufferAlloc.getHostPtr();
2437e5c31af7Sopenharmony_ci	deMemset(storageBufferPtr, 0, storageBufferSize);
2438e5c31af7Sopenharmony_ci	flushAlloc(vkd, device, storageBufferAlloc);
2439e5c31af7Sopenharmony_ci
2440e5c31af7Sopenharmony_ci	// Acceleration structures.
2441e5c31af7Sopenharmony_ci	de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure;
2442e5c31af7Sopenharmony_ci	de::MovePtr<TopLevelAccelerationStructure>		topLevelAccelerationStructure;
2443e5c31af7Sopenharmony_ci
2444e5c31af7Sopenharmony_ci	bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
2445e5c31af7Sopenharmony_ci	bottomLevelAccelerationStructure->setDefaultGeometryData(getShaderStageForGeometry(m_params.interfaceType), VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR);
2446e5c31af7Sopenharmony_ci	bottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, alloc);
2447e5c31af7Sopenharmony_ci
2448e5c31af7Sopenharmony_ci	topLevelAccelerationStructure = makeTopLevelAccelerationStructure();
2449e5c31af7Sopenharmony_ci	topLevelAccelerationStructure->setInstanceCount(1);
2450e5c31af7Sopenharmony_ci	topLevelAccelerationStructure->addInstance(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
2451e5c31af7Sopenharmony_ci	topLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, alloc);
2452e5c31af7Sopenharmony_ci
2453e5c31af7Sopenharmony_ci	// Get some ray tracing properties.
2454e5c31af7Sopenharmony_ci	deUint32 shaderGroupHandleSize		= 0u;
2455e5c31af7Sopenharmony_ci	deUint32 shaderGroupBaseAlignment	= 1u;
2456e5c31af7Sopenharmony_ci	{
2457e5c31af7Sopenharmony_ci		const auto rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physicalDevice);
2458e5c31af7Sopenharmony_ci		shaderGroupHandleSize				= rayTracingPropertiesKHR->getShaderGroupHandleSize();
2459e5c31af7Sopenharmony_ci		shaderGroupBaseAlignment			= rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
2460e5c31af7Sopenharmony_ci	}
2461e5c31af7Sopenharmony_ci
2462e5c31af7Sopenharmony_ci	// Descriptor set layout.
2463e5c31af7Sopenharmony_ci	DescriptorSetLayoutBuilder dslBuilder;
2464e5c31af7Sopenharmony_ci	dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1u, shaderStages, nullptr);
2465e5c31af7Sopenharmony_ci	dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, shaderStages, nullptr);	// Callee buffer.
2466e5c31af7Sopenharmony_ci	const auto descriptorSetLayout = dslBuilder.build(vkd, device);
2467e5c31af7Sopenharmony_ci
2468e5c31af7Sopenharmony_ci	// Pipeline layout.
2469e5c31af7Sopenharmony_ci	const auto pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get());
2470e5c31af7Sopenharmony_ci
2471e5c31af7Sopenharmony_ci	// Descriptor pool and set.
2472e5c31af7Sopenharmony_ci	DescriptorPoolBuilder poolBuilder;
2473e5c31af7Sopenharmony_ci	poolBuilder.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR);
2474e5c31af7Sopenharmony_ci	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
2475e5c31af7Sopenharmony_ci	const auto descriptorPool	= poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2476e5c31af7Sopenharmony_ci	const auto descriptorSet	= makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
2477e5c31af7Sopenharmony_ci
2478e5c31af7Sopenharmony_ci	// Update descriptor set.
2479e5c31af7Sopenharmony_ci	{
2480e5c31af7Sopenharmony_ci		const VkWriteDescriptorSetAccelerationStructureKHR writeASInfo =
2481e5c31af7Sopenharmony_ci		{
2482e5c31af7Sopenharmony_ci			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,
2483e5c31af7Sopenharmony_ci			nullptr,
2484e5c31af7Sopenharmony_ci			1u,
2485e5c31af7Sopenharmony_ci			topLevelAccelerationStructure.get()->getPtr(),
2486e5c31af7Sopenharmony_ci		};
2487e5c31af7Sopenharmony_ci
2488e5c31af7Sopenharmony_ci		const auto	ds							= descriptorSet.get();
2489e5c31af7Sopenharmony_ci		const auto	storageBufferDescriptorInfo	= makeDescriptorBufferInfo(storageBuffer.get(), 0ull, VK_WHOLE_SIZE);
2490e5c31af7Sopenharmony_ci
2491e5c31af7Sopenharmony_ci		DescriptorSetUpdateBuilder updateBuilder;
2492e5c31af7Sopenharmony_ci		updateBuilder.writeSingle(ds, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &writeASInfo);
2493e5c31af7Sopenharmony_ci		updateBuilder.writeSingle(ds, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &storageBufferDescriptorInfo);
2494e5c31af7Sopenharmony_ci		updateBuilder.update(vkd, device);
2495e5c31af7Sopenharmony_ci	}
2496e5c31af7Sopenharmony_ci
2497e5c31af7Sopenharmony_ci	// Create raytracing pipeline and shader binding tables.
2498e5c31af7Sopenharmony_ci	const auto						interfaceType	= m_params.interfaceType;
2499e5c31af7Sopenharmony_ci	Move<VkPipeline>				pipeline;
2500e5c31af7Sopenharmony_ci
2501e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	raygenShaderBindingTable;
2502e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	missShaderBindingTable;
2503e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	hitShaderBindingTable;
2504e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	callableShaderBindingTable;
2505e5c31af7Sopenharmony_ci
2506e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR	raygenShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
2507e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR	missShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
2508e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR	hitShaderBindingTableRegion			= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
2509e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR	callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
2510e5c31af7Sopenharmony_ci
2511e5c31af7Sopenharmony_ci	{
2512e5c31af7Sopenharmony_ci		const auto rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
2513e5c31af7Sopenharmony_ci
2514e5c31af7Sopenharmony_ci		// Every case uses a ray generation shader.
2515e5c31af7Sopenharmony_ci		rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("rgen"), 0), 0);
2516e5c31af7Sopenharmony_ci
2517e5c31af7Sopenharmony_ci		if (interfaceType == InterfaceType::RAY_PAYLOAD)
2518e5c31af7Sopenharmony_ci		{
2519e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("chit"), 0), 1);
2520e5c31af7Sopenharmony_ci		}
2521e5c31af7Sopenharmony_ci		else if (interfaceType == InterfaceType::CALLABLE_DATA || interfaceType == InterfaceType::SHADER_RECORD_BUFFER_RGEN)
2522e5c31af7Sopenharmony_ci		{
2523e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("call"), 0), 1);
2524e5c31af7Sopenharmony_ci		}
2525e5c31af7Sopenharmony_ci		else if (interfaceType == InterfaceType::HIT_ATTRIBUTES)
2526e5c31af7Sopenharmony_ci		{
2527e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("rint"), 0), 1);
2528e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("chit"), 0), 1);
2529e5c31af7Sopenharmony_ci		}
2530e5c31af7Sopenharmony_ci		else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_CALL)
2531e5c31af7Sopenharmony_ci		{
2532e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("call"), 0), 1);
2533e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("subcall"), 0), 2);
2534e5c31af7Sopenharmony_ci		}
2535e5c31af7Sopenharmony_ci		else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_MISS)
2536e5c31af7Sopenharmony_ci		{
2537e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("miss"), 0), 1);
2538e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("call"), 0), 2);
2539e5c31af7Sopenharmony_ci		}
2540e5c31af7Sopenharmony_ci		else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_HIT)
2541e5c31af7Sopenharmony_ci		{
2542e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("chit"), 0), 1);
2543e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("call"), 0), 2);
2544e5c31af7Sopenharmony_ci		}
2545e5c31af7Sopenharmony_ci		else
2546e5c31af7Sopenharmony_ci		{
2547e5c31af7Sopenharmony_ci			DE_ASSERT(false);
2548e5c31af7Sopenharmony_ci		}
2549e5c31af7Sopenharmony_ci
2550e5c31af7Sopenharmony_ci		pipeline = rayTracingPipeline->createPipeline(vkd, device, pipelineLayout.get());
2551e5c31af7Sopenharmony_ci
2552e5c31af7Sopenharmony_ci		if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_RGEN)
2553e5c31af7Sopenharmony_ci		{
2554e5c31af7Sopenharmony_ci			createSBTWithShaderRecord (vkd, device, alloc, pipeline.get(), rayTracingPipeline.get(), shaderGroupHandleSize, shaderGroupBaseAlignment,
2555e5c31af7Sopenharmony_ci									   0u, 1u, raygenShaderBindingTable, raygenShaderBindingTableRegion);
2556e5c31af7Sopenharmony_ci		}
2557e5c31af7Sopenharmony_ci		else
2558e5c31af7Sopenharmony_ci		{
2559e5c31af7Sopenharmony_ci			raygenShaderBindingTable		= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
2560e5c31af7Sopenharmony_ci			raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2561e5c31af7Sopenharmony_ci		}
2562e5c31af7Sopenharmony_ci
2563e5c31af7Sopenharmony_ci
2564e5c31af7Sopenharmony_ci		if (interfaceType == InterfaceType::CALLABLE_DATA || interfaceType == InterfaceType::SHADER_RECORD_BUFFER_RGEN)
2565e5c31af7Sopenharmony_ci		{
2566e5c31af7Sopenharmony_ci			callableShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
2567e5c31af7Sopenharmony_ci			callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2568e5c31af7Sopenharmony_ci		}
2569e5c31af7Sopenharmony_ci		else if (interfaceType == InterfaceType::RAY_PAYLOAD || interfaceType == InterfaceType::HIT_ATTRIBUTES)
2570e5c31af7Sopenharmony_ci		{
2571e5c31af7Sopenharmony_ci			hitShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
2572e5c31af7Sopenharmony_ci			hitShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2573e5c31af7Sopenharmony_ci		}
2574e5c31af7Sopenharmony_ci		else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_CALL)
2575e5c31af7Sopenharmony_ci		{
2576e5c31af7Sopenharmony_ci			createSBTWithShaderRecord (vkd, device, alloc, pipeline.get(), rayTracingPipeline.get(), shaderGroupHandleSize, shaderGroupBaseAlignment,
2577e5c31af7Sopenharmony_ci									   1u, 2u, callableShaderBindingTable, callableShaderBindingTableRegion);
2578e5c31af7Sopenharmony_ci		}
2579e5c31af7Sopenharmony_ci		else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_MISS)
2580e5c31af7Sopenharmony_ci		{
2581e5c31af7Sopenharmony_ci			createSBTWithShaderRecord (vkd, device, alloc, pipeline.get(), rayTracingPipeline.get(), shaderGroupHandleSize, shaderGroupBaseAlignment,
2582e5c31af7Sopenharmony_ci									   1u, 1u, missShaderBindingTable, missShaderBindingTableRegion);
2583e5c31af7Sopenharmony_ci
2584e5c31af7Sopenharmony_ci			// Callable shader table.
2585e5c31af7Sopenharmony_ci			callableShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1);
2586e5c31af7Sopenharmony_ci			callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2587e5c31af7Sopenharmony_ci		}
2588e5c31af7Sopenharmony_ci		else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_HIT)
2589e5c31af7Sopenharmony_ci		{
2590e5c31af7Sopenharmony_ci			createSBTWithShaderRecord (vkd, device, alloc, pipeline.get(), rayTracingPipeline.get(), shaderGroupHandleSize, shaderGroupBaseAlignment,
2591e5c31af7Sopenharmony_ci									   1u, 1u, hitShaderBindingTable, hitShaderBindingTableRegion);
2592e5c31af7Sopenharmony_ci
2593e5c31af7Sopenharmony_ci			// Callable shader table.
2594e5c31af7Sopenharmony_ci			callableShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1);
2595e5c31af7Sopenharmony_ci			callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
2596e5c31af7Sopenharmony_ci		}
2597e5c31af7Sopenharmony_ci		else
2598e5c31af7Sopenharmony_ci		{
2599e5c31af7Sopenharmony_ci			DE_ASSERT(false);
2600e5c31af7Sopenharmony_ci		}
2601e5c31af7Sopenharmony_ci	}
2602e5c31af7Sopenharmony_ci
2603e5c31af7Sopenharmony_ci	// Use ray tracing pipeline.
2604e5c31af7Sopenharmony_ci	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline.get());
2605e5c31af7Sopenharmony_ci	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr);
2606e5c31af7Sopenharmony_ci	vkd.cmdTraceRaysKHR(cmdBuffer, &raygenShaderBindingTableRegion, &missShaderBindingTableRegion, &hitShaderBindingTableRegion, &callableShaderBindingTableRegion, 1u, 1u, 1u);
2607e5c31af7Sopenharmony_ci
2608e5c31af7Sopenharmony_ci	// Synchronize output and callee buffers.
2609e5c31af7Sopenharmony_ci	const auto memBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
2610e5c31af7Sopenharmony_ci	vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &memBarrier, 0u, nullptr, 0u, nullptr);
2611e5c31af7Sopenharmony_ci
2612e5c31af7Sopenharmony_ci	endCommandBuffer(vkd, cmdBuffer);
2613e5c31af7Sopenharmony_ci	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
2614e5c31af7Sopenharmony_ci
2615e5c31af7Sopenharmony_ci	// Verify storage buffer.
2616e5c31af7Sopenharmony_ci	invalidateAlloc(vkd, device, storageBufferAlloc);
2617e5c31af7Sopenharmony_ci	deMemcpy(storageBufferData.data(), storageBufferPtr, storageBufferSize);
2618e5c31af7Sopenharmony_ci
2619e5c31af7Sopenharmony_ci	// These values must match what the shaders store.
2620e5c31af7Sopenharmony_ci	std::vector<deUint32> expectedData;
2621e5c31af7Sopenharmony_ci	if (interfaceType == InterfaceType::RAY_PAYLOAD)
2622e5c31af7Sopenharmony_ci	{
2623e5c31af7Sopenharmony_ci		expectedData.push_back(103u);
2624e5c31af7Sopenharmony_ci		expectedData.push_back(100u);
2625e5c31af7Sopenharmony_ci	}
2626e5c31af7Sopenharmony_ci	else if (interfaceType == InterfaceType::CALLABLE_DATA)
2627e5c31af7Sopenharmony_ci	{
2628e5c31af7Sopenharmony_ci		expectedData.push_back(200u);
2629e5c31af7Sopenharmony_ci		expectedData.push_back(100u);
2630e5c31af7Sopenharmony_ci	}
2631e5c31af7Sopenharmony_ci	else if (interfaceType == InterfaceType::HIT_ATTRIBUTES)
2632e5c31af7Sopenharmony_ci	{
2633e5c31af7Sopenharmony_ci		expectedData.push_back(300u);
2634e5c31af7Sopenharmony_ci		expectedData.push_back(315u);
2635e5c31af7Sopenharmony_ci		expectedData.push_back(330u);
2636e5c31af7Sopenharmony_ci	}
2637e5c31af7Sopenharmony_ci	else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_RGEN)
2638e5c31af7Sopenharmony_ci	{
2639e5c31af7Sopenharmony_ci		expectedData.push_back(402u);
2640e5c31af7Sopenharmony_ci		expectedData.push_back(450u);
2641e5c31af7Sopenharmony_ci	}
2642e5c31af7Sopenharmony_ci	else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_CALL)
2643e5c31af7Sopenharmony_ci	{
2644e5c31af7Sopenharmony_ci		expectedData.push_back(806u);
2645e5c31af7Sopenharmony_ci		expectedData.push_back(403u);
2646e5c31af7Sopenharmony_ci		expectedData.push_back(450u);
2647e5c31af7Sopenharmony_ci	}
2648e5c31af7Sopenharmony_ci	else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_MISS || interfaceType == InterfaceType::SHADER_RECORD_BUFFER_HIT)
2649e5c31af7Sopenharmony_ci	{
2650e5c31af7Sopenharmony_ci		expectedData.push_back(1200u);
2651e5c31af7Sopenharmony_ci		expectedData.push_back( 400u);
2652e5c31af7Sopenharmony_ci		expectedData.push_back( 490u);
2653e5c31af7Sopenharmony_ci	}
2654e5c31af7Sopenharmony_ci	else
2655e5c31af7Sopenharmony_ci	{
2656e5c31af7Sopenharmony_ci		DE_ASSERT(false);
2657e5c31af7Sopenharmony_ci	}
2658e5c31af7Sopenharmony_ci
2659e5c31af7Sopenharmony_ci	size_t pos;
2660e5c31af7Sopenharmony_ci	for (pos = 0u; pos < expectedData.size(); ++pos)
2661e5c31af7Sopenharmony_ci	{
2662e5c31af7Sopenharmony_ci		const auto& stored		= storageBufferData.at(pos);
2663e5c31af7Sopenharmony_ci		const auto& expected	= expectedData.at(pos);
2664e5c31af7Sopenharmony_ci		if (stored != expected)
2665e5c31af7Sopenharmony_ci		{
2666e5c31af7Sopenharmony_ci			std::ostringstream msg;
2667e5c31af7Sopenharmony_ci			msg << "Unexpected output value found at position " << pos << " (expected " << expected << " but got " << stored << ")";
2668e5c31af7Sopenharmony_ci			return tcu::TestStatus::fail(msg.str());
2669e5c31af7Sopenharmony_ci		}
2670e5c31af7Sopenharmony_ci	}
2671e5c31af7Sopenharmony_ci
2672e5c31af7Sopenharmony_ci	// Expect zeros in unused positions, as filled on the host.
2673e5c31af7Sopenharmony_ci	for (; pos < storageBufferData.size(); ++pos)
2674e5c31af7Sopenharmony_ci	{
2675e5c31af7Sopenharmony_ci		const auto& stored = storageBufferData.at(pos);
2676e5c31af7Sopenharmony_ci		if (stored != 0u)
2677e5c31af7Sopenharmony_ci		{
2678e5c31af7Sopenharmony_ci			std::ostringstream msg;
2679e5c31af7Sopenharmony_ci			msg << "Unexpected output value found at position " << pos << " (expected 0 but got " << stored << ")";
2680e5c31af7Sopenharmony_ci			return tcu::TestStatus::fail(msg.str());
2681e5c31af7Sopenharmony_ci		}
2682e5c31af7Sopenharmony_ci	}
2683e5c31af7Sopenharmony_ci
2684e5c31af7Sopenharmony_ci	return tcu::TestStatus::pass("Pass");
2685e5c31af7Sopenharmony_ci}
2686e5c31af7Sopenharmony_ci
2687e5c31af7Sopenharmony_ci} // anonymous namespace
2688e5c31af7Sopenharmony_ci
2689e5c31af7Sopenharmony_citcu::TestCaseGroup*	createDataSpillTests(tcu::TestContext& testCtx)
2690e5c31af7Sopenharmony_ci{
2691e5c31af7Sopenharmony_ci	// Ray tracing tests for data spilling and unspilling around shader calls
2692e5c31af7Sopenharmony_ci	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "data_spill"));
2693e5c31af7Sopenharmony_ci
2694e5c31af7Sopenharmony_ci	struct
2695e5c31af7Sopenharmony_ci	{
2696e5c31af7Sopenharmony_ci		CallType callType;
2697e5c31af7Sopenharmony_ci		const char* name;
2698e5c31af7Sopenharmony_ci	} callTypes[] =
2699e5c31af7Sopenharmony_ci	{
2700e5c31af7Sopenharmony_ci		{ CallType::EXECUTE_CALLABLE,		"execute_callable"		},
2701e5c31af7Sopenharmony_ci		{ CallType::TRACE_RAY,				"trace_ray"				},
2702e5c31af7Sopenharmony_ci		{ CallType::REPORT_INTERSECTION,	"report_intersection"	},
2703e5c31af7Sopenharmony_ci	};
2704e5c31af7Sopenharmony_ci
2705e5c31af7Sopenharmony_ci	struct
2706e5c31af7Sopenharmony_ci	{
2707e5c31af7Sopenharmony_ci		DataType dataType;
2708e5c31af7Sopenharmony_ci		const char* name;
2709e5c31af7Sopenharmony_ci	} dataTypes[] =
2710e5c31af7Sopenharmony_ci	{
2711e5c31af7Sopenharmony_ci		{ DataType::INT32,				"int32"			},
2712e5c31af7Sopenharmony_ci		{ DataType::UINT32,				"uint32"		},
2713e5c31af7Sopenharmony_ci		{ DataType::INT64,				"int64"			},
2714e5c31af7Sopenharmony_ci		{ DataType::UINT64,				"uint64"		},
2715e5c31af7Sopenharmony_ci		{ DataType::INT16,				"int16"			},
2716e5c31af7Sopenharmony_ci		{ DataType::UINT16,				"uint16"		},
2717e5c31af7Sopenharmony_ci		{ DataType::INT8,				"int8"			},
2718e5c31af7Sopenharmony_ci		{ DataType::UINT8,				"uint8"			},
2719e5c31af7Sopenharmony_ci		{ DataType::FLOAT32,			"float32"		},
2720e5c31af7Sopenharmony_ci		{ DataType::FLOAT64,			"float64"		},
2721e5c31af7Sopenharmony_ci		{ DataType::FLOAT16,			"float16"		},
2722e5c31af7Sopenharmony_ci		{ DataType::STRUCT,				"struct"		},
2723e5c31af7Sopenharmony_ci		{ DataType::SAMPLER,			"sampler"		},
2724e5c31af7Sopenharmony_ci		{ DataType::IMAGE,				"image"			},
2725e5c31af7Sopenharmony_ci		{ DataType::SAMPLED_IMAGE,		"combined"		},
2726e5c31af7Sopenharmony_ci		{ DataType::PTR_IMAGE,			"ptr_image"		},
2727e5c31af7Sopenharmony_ci		{ DataType::PTR_SAMPLER,		"ptr_sampler"	},
2728e5c31af7Sopenharmony_ci		{ DataType::PTR_SAMPLED_IMAGE,	"ptr_combined"	},
2729e5c31af7Sopenharmony_ci		{ DataType::PTR_TEXEL,			"ptr_texel"		},
2730e5c31af7Sopenharmony_ci		{ DataType::OP_NULL,			"op_null"		},
2731e5c31af7Sopenharmony_ci		{ DataType::OP_UNDEF,			"op_undef"		},
2732e5c31af7Sopenharmony_ci	};
2733e5c31af7Sopenharmony_ci
2734e5c31af7Sopenharmony_ci	struct
2735e5c31af7Sopenharmony_ci	{
2736e5c31af7Sopenharmony_ci		VectorType vectorType;
2737e5c31af7Sopenharmony_ci		const char* prefix;
2738e5c31af7Sopenharmony_ci	} vectorTypes[] =
2739e5c31af7Sopenharmony_ci	{
2740e5c31af7Sopenharmony_ci		{ VectorType::SCALAR,	""		},
2741e5c31af7Sopenharmony_ci		{ VectorType::V2,		"v2"	},
2742e5c31af7Sopenharmony_ci		{ VectorType::V3,		"v3"	},
2743e5c31af7Sopenharmony_ci		{ VectorType::V4,		"v4"	},
2744e5c31af7Sopenharmony_ci		{ VectorType::A5,		"a5"	},
2745e5c31af7Sopenharmony_ci	};
2746e5c31af7Sopenharmony_ci
2747e5c31af7Sopenharmony_ci	for (int callTypeIdx = 0; callTypeIdx < DE_LENGTH_OF_ARRAY(callTypes); ++callTypeIdx)
2748e5c31af7Sopenharmony_ci	{
2749e5c31af7Sopenharmony_ci		const auto& entryCallTypes = callTypes[callTypeIdx];
2750e5c31af7Sopenharmony_ci
2751e5c31af7Sopenharmony_ci		de::MovePtr<tcu::TestCaseGroup> callTypeGroup(new tcu::TestCaseGroup(testCtx, entryCallTypes.name));
2752e5c31af7Sopenharmony_ci		for (int dataTypeIdx = 0; dataTypeIdx < DE_LENGTH_OF_ARRAY(dataTypes); ++dataTypeIdx)
2753e5c31af7Sopenharmony_ci		{
2754e5c31af7Sopenharmony_ci			const auto& entryDataTypes = dataTypes[dataTypeIdx];
2755e5c31af7Sopenharmony_ci
2756e5c31af7Sopenharmony_ci			for (int vectorTypeIdx = 0; vectorTypeIdx < DE_LENGTH_OF_ARRAY(vectorTypes); ++vectorTypeIdx)
2757e5c31af7Sopenharmony_ci			{
2758e5c31af7Sopenharmony_ci				const auto& entryVectorTypes = vectorTypes[vectorTypeIdx];
2759e5c31af7Sopenharmony_ci
2760e5c31af7Sopenharmony_ci				if ((samplersNeeded(entryDataTypes.dataType)
2761e5c31af7Sopenharmony_ci					 || storageImageNeeded(entryDataTypes.dataType)
2762e5c31af7Sopenharmony_ci					 || entryDataTypes.dataType == DataType::STRUCT
2763e5c31af7Sopenharmony_ci					 || entryDataTypes.dataType == DataType::OP_NULL
2764e5c31af7Sopenharmony_ci					 || entryDataTypes.dataType == DataType::OP_UNDEF)
2765e5c31af7Sopenharmony_ci					&& entryVectorTypes.vectorType != VectorType::SCALAR)
2766e5c31af7Sopenharmony_ci				{
2767e5c31af7Sopenharmony_ci					continue;
2768e5c31af7Sopenharmony_ci				}
2769e5c31af7Sopenharmony_ci
2770e5c31af7Sopenharmony_ci				DataSpillTestCase::TestParams params;
2771e5c31af7Sopenharmony_ci				params.callType		= entryCallTypes.callType;
2772e5c31af7Sopenharmony_ci				params.dataType		= entryDataTypes.dataType;
2773e5c31af7Sopenharmony_ci				params.vectorType	= entryVectorTypes.vectorType;
2774e5c31af7Sopenharmony_ci
2775e5c31af7Sopenharmony_ci				const auto testName = std::string(entryVectorTypes.prefix) + entryDataTypes.name;
2776e5c31af7Sopenharmony_ci
2777e5c31af7Sopenharmony_ci				callTypeGroup->addChild(new DataSpillTestCase(testCtx, testName, params));
2778e5c31af7Sopenharmony_ci			}
2779e5c31af7Sopenharmony_ci		}
2780e5c31af7Sopenharmony_ci
2781e5c31af7Sopenharmony_ci		group->addChild(callTypeGroup.release());
2782e5c31af7Sopenharmony_ci	}
2783e5c31af7Sopenharmony_ci
2784e5c31af7Sopenharmony_ci	// Pipeline interface tests.
2785e5c31af7Sopenharmony_ci	de::MovePtr<tcu::TestCaseGroup> pipelineInterfaceGroup(new tcu::TestCaseGroup(testCtx, "pipeline_interface", "Test data spilling and unspilling of pipeline interface variables"));
2786e5c31af7Sopenharmony_ci
2787e5c31af7Sopenharmony_ci	struct
2788e5c31af7Sopenharmony_ci	{
2789e5c31af7Sopenharmony_ci		InterfaceType	interfaceType;
2790e5c31af7Sopenharmony_ci		const char*		name;
2791e5c31af7Sopenharmony_ci	} interfaceTypes[] =
2792e5c31af7Sopenharmony_ci	{
2793e5c31af7Sopenharmony_ci		{ InterfaceType::RAY_PAYLOAD,				"ray_payload"				},
2794e5c31af7Sopenharmony_ci		{ InterfaceType::CALLABLE_DATA,				"callable_data"				},
2795e5c31af7Sopenharmony_ci		{ InterfaceType::HIT_ATTRIBUTES,			"hit_attributes"			},
2796e5c31af7Sopenharmony_ci		{ InterfaceType::SHADER_RECORD_BUFFER_RGEN,	"shader_record_buffer_rgen"	},
2797e5c31af7Sopenharmony_ci		{ InterfaceType::SHADER_RECORD_BUFFER_CALL,	"shader_record_buffer_call"	},
2798e5c31af7Sopenharmony_ci		{ InterfaceType::SHADER_RECORD_BUFFER_MISS,	"shader_record_buffer_miss"	},
2799e5c31af7Sopenharmony_ci		{ InterfaceType::SHADER_RECORD_BUFFER_HIT,	"shader_record_buffer_hit"	},
2800e5c31af7Sopenharmony_ci	};
2801e5c31af7Sopenharmony_ci
2802e5c31af7Sopenharmony_ci	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(interfaceTypes); ++idx)
2803e5c31af7Sopenharmony_ci	{
2804e5c31af7Sopenharmony_ci		const auto&										entry	= interfaceTypes[idx];
2805e5c31af7Sopenharmony_ci		DataSpillPipelineInterfaceTestCase::TestParams	params;
2806e5c31af7Sopenharmony_ci
2807e5c31af7Sopenharmony_ci		params.interfaceType = entry.interfaceType;
2808e5c31af7Sopenharmony_ci
2809e5c31af7Sopenharmony_ci		pipelineInterfaceGroup->addChild(new DataSpillPipelineInterfaceTestCase(testCtx, entry.name, params));
2810e5c31af7Sopenharmony_ci	}
2811e5c31af7Sopenharmony_ci
2812e5c31af7Sopenharmony_ci	group->addChild(pipelineInterfaceGroup.release());
2813e5c31af7Sopenharmony_ci
2814e5c31af7Sopenharmony_ci	return group.release();
2815e5c31af7Sopenharmony_ci}
2816e5c31af7Sopenharmony_ci
2817e5c31af7Sopenharmony_ci} // RayTracing
2818e5c31af7Sopenharmony_ci} // vkt
2819e5c31af7Sopenharmony_ci
2820