1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests
3e5c31af7Sopenharmony_ci * ------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2020 The Khronos Group Inc.
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *	  http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief Ray Tracing Builtin and specialization constant tests
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "vktRayTracingBuiltinTests.hpp"
25e5c31af7Sopenharmony_ci
26e5c31af7Sopenharmony_ci#include "vkDefs.hpp"
27e5c31af7Sopenharmony_ci
28e5c31af7Sopenharmony_ci#include "vktTestCase.hpp"
29e5c31af7Sopenharmony_ci#include "vkCmdUtil.hpp"
30e5c31af7Sopenharmony_ci#include "vkObjUtil.hpp"
31e5c31af7Sopenharmony_ci#include "vkBuilderUtil.hpp"
32e5c31af7Sopenharmony_ci#include "vkBarrierUtil.hpp"
33e5c31af7Sopenharmony_ci#include "vkBufferWithMemory.hpp"
34e5c31af7Sopenharmony_ci#include "vkImageWithMemory.hpp"
35e5c31af7Sopenharmony_ci#include "vkTypeUtil.hpp"
36e5c31af7Sopenharmony_ci#include "vkImageUtil.hpp"
37e5c31af7Sopenharmony_ci#include "vkPipelineConstructionUtil.hpp"
38e5c31af7Sopenharmony_ci
39e5c31af7Sopenharmony_ci#include "vkRayTracingUtil.hpp"
40e5c31af7Sopenharmony_ci
41e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
42e5c31af7Sopenharmony_ci#include "tcuMatrix.hpp"
43e5c31af7Sopenharmony_ci
44e5c31af7Sopenharmony_ci#include "deMath.h"
45e5c31af7Sopenharmony_ci
46e5c31af7Sopenharmony_cinamespace vkt
47e5c31af7Sopenharmony_ci{
48e5c31af7Sopenharmony_cinamespace RayTracing
49e5c31af7Sopenharmony_ci{
50e5c31af7Sopenharmony_cinamespace
51e5c31af7Sopenharmony_ci{
52e5c31af7Sopenharmony_ciusing namespace vk;
53e5c31af7Sopenharmony_ciusing namespace std;
54e5c31af7Sopenharmony_ci
55e5c31af7Sopenharmony_cistatic const VkFlags	ALL_RAY_TRACING_STAGES	= VK_SHADER_STAGE_RAYGEN_BIT_KHR
56e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_ANY_HIT_BIT_KHR
57e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
58e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_MISS_BIT_KHR
59e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_INTERSECTION_BIT_KHR
60e5c31af7Sopenharmony_ci												| VK_SHADER_STAGE_CALLABLE_BIT_KHR;
61e5c31af7Sopenharmony_ci
62e5c31af7Sopenharmony_cienum GeomType
63e5c31af7Sopenharmony_ci{
64e5c31af7Sopenharmony_ci	GEOM_TYPE_TRIANGLES,
65e5c31af7Sopenharmony_ci	GEOM_TYPE_AABBS,
66e5c31af7Sopenharmony_ci};
67e5c31af7Sopenharmony_ci
68e5c31af7Sopenharmony_cienum TestId
69e5c31af7Sopenharmony_ci{
70e5c31af7Sopenharmony_ci	TEST_ID_LAUNCH_ID_EXT				= 0,
71e5c31af7Sopenharmony_ci	TEST_ID_LAUNCH_SIZE_EXT,
72e5c31af7Sopenharmony_ci	TEST_ID_PRIMITIVE_ID,
73e5c31af7Sopenharmony_ci	TEST_ID_INSTANCE_ID,
74e5c31af7Sopenharmony_ci	TEST_ID_INSTANCE_CUSTOM_INDEX_EXT,
75e5c31af7Sopenharmony_ci	TEST_ID_GEOMETRY_INDEX_EXT,
76e5c31af7Sopenharmony_ci	TEST_ID_WORLD_RAY_ORIGIN_EXT,
77e5c31af7Sopenharmony_ci	TEST_ID_WORLD_RAY_DIRECTION_EXT,
78e5c31af7Sopenharmony_ci	TEST_ID_OBJECT_RAY_ORIGIN_EXT,
79e5c31af7Sopenharmony_ci	TEST_ID_OBJECT_RAY_DIRECTION_EXT,
80e5c31af7Sopenharmony_ci	TEST_ID_RAY_T_MIN_EXT,
81e5c31af7Sopenharmony_ci	TEST_ID_RAY_T_MAX_EXT,
82e5c31af7Sopenharmony_ci	TEST_ID_INCOMING_RAY_FLAGS_EXT,
83e5c31af7Sopenharmony_ci	TEST_ID_HIT_T_EXT,
84e5c31af7Sopenharmony_ci	TEST_ID_HIT_KIND_EXT,
85e5c31af7Sopenharmony_ci	TEST_ID_OBJECT_TO_WORLD_EXT,
86e5c31af7Sopenharmony_ci	TEST_ID_OBJECT_TO_WORLD_3X4_EXT,
87e5c31af7Sopenharmony_ci	TEST_ID_WORLD_TO_OBJECT_EXT,
88e5c31af7Sopenharmony_ci	TEST_ID_WORLD_TO_OBJECT_3X4_EXT,
89e5c31af7Sopenharmony_ci	TEST_ID_INDICES_INDIRECT,
90e5c31af7Sopenharmony_ci	TEST_ID_TRANSFORMS_INDIRECT,
91e5c31af7Sopenharmony_ci	TEST_ID_TMINMAX_INDIRECT,
92e5c31af7Sopenharmony_ci	TEST_ID_INCOMING_RAY_FLAGS_INDIRECT,
93e5c31af7Sopenharmony_ci	TEST_ID_HIT_KIND_INDIRECT,
94e5c31af7Sopenharmony_ci	TEST_ID_LAST
95e5c31af7Sopenharmony_ci};
96e5c31af7Sopenharmony_ci
97e5c31af7Sopenharmony_cienum RayFlagBits
98e5c31af7Sopenharmony_ci{
99e5c31af7Sopenharmony_ci	RAY_FLAG_BIT_OPAQUE_EXT							= 0,	//  const uint gl_RayFlagsOpaqueEXT = 1U;
100e5c31af7Sopenharmony_ci	RAY_FLAG_BIT_NO_OPAQUE_EXT						= 1,	//  const uint gl_RayFlagsNoOpaqueEXT = 2U;
101e5c31af7Sopenharmony_ci	RAY_FLAG_BIT_TERMINATE_ON_FIRST_HIT_EXT			= 2,	//  const uint gl_RayFlagsTerminateOnFirstHitEXT = 4U;
102e5c31af7Sopenharmony_ci	RAY_FLAG_BIT_SKIP_CLOSEST_HIT_SHADER_EXT		= 3,	//  const uint gl_RayFlagsSkipClosestHitShaderEXT = 8U;
103e5c31af7Sopenharmony_ci	RAY_FLAG_BIT_CULL_BACK_FACING_TRIANGLES_EXT		= 4,	//  const uint gl_RayFlagsCullBackFacingTrianglesEXT = 16U;
104e5c31af7Sopenharmony_ci	RAY_FLAG_BIT_CULL_FRONT_FACING_TRIANGLES_EXT	= 5,	//  const uint gl_RayFlagsCullFrontFacingTrianglesEXT = 32U;
105e5c31af7Sopenharmony_ci	RAY_FLAG_BIT_CULL_OPAQUE_EXT					= 6,	//  const uint gl_RayFlagsCullOpaqueEXT = 64U;
106e5c31af7Sopenharmony_ci	RAY_FLAG_BIT_CULL_NO_OPAQUE_EXT					= 7,	//  const uint gl_RayFlagsCullNoOpaqueEXT = 128U;
107e5c31af7Sopenharmony_ci	RAY_FLAG_BIT_LAST_PER_TEST,
108e5c31af7Sopenharmony_ci	RAY_FLAG_BIT_SKIP_TRIANGLES_EXT					= 8,	//  const uint gl_RayFlagsSkipTrianglesEXT = 256U;
109e5c31af7Sopenharmony_ci	RAY_FLAG_BIT_SKIP_AABB_EXT						= 9,	//  const uint gl_RayFlagsSkipAABBEXT = 512U;
110e5c31af7Sopenharmony_ci	RAY_FLAG_BIT_LAST
111e5c31af7Sopenharmony_ci};
112e5c31af7Sopenharmony_ci
113e5c31af7Sopenharmony_cistruct CaseDef
114e5c31af7Sopenharmony_ci{
115e5c31af7Sopenharmony_ci	TestId					id;
116e5c31af7Sopenharmony_ci	const char*				name;
117e5c31af7Sopenharmony_ci	deUint32				width;
118e5c31af7Sopenharmony_ci	deUint32				height;
119e5c31af7Sopenharmony_ci	deUint32				depth;
120e5c31af7Sopenharmony_ci	deUint32				raysDepth;
121e5c31af7Sopenharmony_ci	VkFormat				format;
122e5c31af7Sopenharmony_ci	bool					fixedPointScalarOutput;
123e5c31af7Sopenharmony_ci	bool					fixedPointVectorOutput;
124e5c31af7Sopenharmony_ci	bool					fixedPointMatrixOutput;
125e5c31af7Sopenharmony_ci	GeomType				geomType;
126e5c31af7Sopenharmony_ci	deUint32				squaresGroupCount;
127e5c31af7Sopenharmony_ci	deUint32				geometriesGroupCount;
128e5c31af7Sopenharmony_ci	deUint32				instancesGroupCount;
129e5c31af7Sopenharmony_ci	VkShaderStageFlagBits	stage;
130e5c31af7Sopenharmony_ci	bool					rayFlagSkipTriangles;
131e5c31af7Sopenharmony_ci	bool					rayFlagSkipAABSs;
132e5c31af7Sopenharmony_ci	bool					opaque;
133e5c31af7Sopenharmony_ci	bool					frontFace;
134e5c31af7Sopenharmony_ci	VkPipelineCreateFlags	pipelineCreateFlags;
135e5c31af7Sopenharmony_ci	bool					useSpecConstants;
136e5c31af7Sopenharmony_ci	bool					skipClosestHit;
137e5c31af7Sopenharmony_ci	bool					useMaintenance5;
138e5c31af7Sopenharmony_ci};
139e5c31af7Sopenharmony_ci
140e5c31af7Sopenharmony_ciconst deUint32	DEFAULT_UINT_CLEAR_VALUE	= 0x8000;
141e5c31af7Sopenharmony_ciconst deUint32	FIXED_POINT_DIVISOR			= 1024 * 1024;
142e5c31af7Sopenharmony_ciconst deUint32	FIXED_POINT_ALLOWED_ERROR	= 4;
143e5c31af7Sopenharmony_ci
144e5c31af7Sopenharmony_cibool isPlain (const deUint32 width, const deUint32 height, const deUint32 depth)
145e5c31af7Sopenharmony_ci{
146e5c31af7Sopenharmony_ci	return (width == 1 || height == 1 || depth == 1);
147e5c31af7Sopenharmony_ci}
148e5c31af7Sopenharmony_ci
149e5c31af7Sopenharmony_cideUint32 getShaderGroupSize (const InstanceInterface&	vki,
150e5c31af7Sopenharmony_ci							 const VkPhysicalDevice		physicalDevice)
151e5c31af7Sopenharmony_ci{
152e5c31af7Sopenharmony_ci	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
153e5c31af7Sopenharmony_ci
154e5c31af7Sopenharmony_ci	rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physicalDevice);
155e5c31af7Sopenharmony_ci	return rayTracingPropertiesKHR->getShaderGroupHandleSize();
156e5c31af7Sopenharmony_ci}
157e5c31af7Sopenharmony_ci
158e5c31af7Sopenharmony_cideUint32 getShaderGroupBaseAlignment (const InstanceInterface&	vki,
159e5c31af7Sopenharmony_ci									  const VkPhysicalDevice	physicalDevice)
160e5c31af7Sopenharmony_ci{
161e5c31af7Sopenharmony_ci	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;
162e5c31af7Sopenharmony_ci
163e5c31af7Sopenharmony_ci	rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);
164e5c31af7Sopenharmony_ci	return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
165e5c31af7Sopenharmony_ci}
166e5c31af7Sopenharmony_ci
167e5c31af7Sopenharmony_ciVkImageCreateInfo makeImageCreateInfo (deUint32 width, deUint32 height, deUint32 depth, VkFormat format)
168e5c31af7Sopenharmony_ci{
169e5c31af7Sopenharmony_ci	const VkImageType		imageType		= VK_IMAGE_TYPE_3D;
170e5c31af7Sopenharmony_ci	const VkImageUsageFlags	usage			= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
171e5c31af7Sopenharmony_ci	const VkImageCreateInfo	imageCreateInfo	=
172e5c31af7Sopenharmony_ci	{
173e5c31af7Sopenharmony_ci		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType;
174e5c31af7Sopenharmony_ci		DE_NULL,								// const void*				pNext;
175e5c31af7Sopenharmony_ci		(VkImageCreateFlags)0u,					// VkImageCreateFlags		flags;
176e5c31af7Sopenharmony_ci		imageType,								// VkImageType				imageType;
177e5c31af7Sopenharmony_ci		format,									// VkFormat					format;
178e5c31af7Sopenharmony_ci		makeExtent3D(width, height, depth),		// VkExtent3D				extent;
179e5c31af7Sopenharmony_ci		1u,										// deUint32					mipLevels;
180e5c31af7Sopenharmony_ci		1u,										// deUint32					arrayLayers;
181e5c31af7Sopenharmony_ci		VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples;
182e5c31af7Sopenharmony_ci		VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling;
183e5c31af7Sopenharmony_ci		usage,									// VkImageUsageFlags		usage;
184e5c31af7Sopenharmony_ci		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode;
185e5c31af7Sopenharmony_ci		0u,										// deUint32					queueFamilyIndexCount;
186e5c31af7Sopenharmony_ci		DE_NULL,								// const deUint32*			pQueueFamilyIndices;
187e5c31af7Sopenharmony_ci		VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout;
188e5c31af7Sopenharmony_ci	};
189e5c31af7Sopenharmony_ci
190e5c31af7Sopenharmony_ci	return imageCreateInfo;
191e5c31af7Sopenharmony_ci}
192e5c31af7Sopenharmony_ci
193e5c31af7Sopenharmony_ciclass RayTracingBuiltinLaunchTestInstance : public TestInstance
194e5c31af7Sopenharmony_ci{
195e5c31af7Sopenharmony_cipublic:
196e5c31af7Sopenharmony_ci																RayTracingBuiltinLaunchTestInstance		(Context& context, const CaseDef& data);
197e5c31af7Sopenharmony_ci																~RayTracingBuiltinLaunchTestInstance	(void);
198e5c31af7Sopenharmony_ci	tcu::TestStatus												iterate									(void);
199e5c31af7Sopenharmony_ci
200e5c31af7Sopenharmony_ciprotected:
201e5c31af7Sopenharmony_ci	void														checkSupportInInstance					(void) const;
202e5c31af7Sopenharmony_ci	Move<VkPipeline>											makePipeline							(de::MovePtr<RayTracingPipeline>&							rayTracingPipeline,
203e5c31af7Sopenharmony_ci																										 VkPipelineLayout											pipelineLayout,
204e5c31af7Sopenharmony_ci																										 const VkSpecializationInfo*								specializationInfo);
205e5c31af7Sopenharmony_ci	std::vector<deInt32>										expectedIntValuesBuffer					(void);
206e5c31af7Sopenharmony_ci	std::vector<float>											expectedFloatValuesBuffer				(void);
207e5c31af7Sopenharmony_ci	std::vector<float>											expectedVectorValuesBuffer				(void);
208e5c31af7Sopenharmony_ci	std::vector<float>											expectedMatrixValuesBuffer				(void);
209e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>								runTest									(void);
210e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>								createShaderBindingTable				(const InstanceInterface&									vki,
211e5c31af7Sopenharmony_ci																										 const DeviceInterface&										vkd,
212e5c31af7Sopenharmony_ci																										 const VkDevice												device,
213e5c31af7Sopenharmony_ci																										 const VkPhysicalDevice										physicalDevice,
214e5c31af7Sopenharmony_ci																										 const VkPipeline											pipeline,
215e5c31af7Sopenharmony_ci																										 Allocator&													allocator,
216e5c31af7Sopenharmony_ci																										 de::MovePtr<RayTracingPipeline>&							rayTracingPipeline,
217e5c31af7Sopenharmony_ci																										 const deUint32												group);
218e5c31af7Sopenharmony_ci
219e5c31af7Sopenharmony_ci	bool														validateIntBuffer						(de::MovePtr<BufferWithMemory>								buffer);
220e5c31af7Sopenharmony_ci	bool														validateFloatBuffer						(de::MovePtr<BufferWithMemory>								buffer);
221e5c31af7Sopenharmony_ci	bool														validateVectorBuffer					(de::MovePtr<BufferWithMemory>								buffer);
222e5c31af7Sopenharmony_ci	bool														validateMatrixBuffer					(de::MovePtr<BufferWithMemory>								buffer);
223e5c31af7Sopenharmony_ci
224e5c31af7Sopenharmony_ci	de::MovePtr<TopLevelAccelerationStructure>					initTopAccelerationStructure			(VkCommandBuffer											cmdBuffer,
225e5c31af7Sopenharmony_ci																										 vector<de::SharedPtr<BottomLevelAccelerationStructure> >&	bottomLevelAccelerationStructures);
226e5c31af7Sopenharmony_ci	vector<de::SharedPtr<BottomLevelAccelerationStructure>	>	initBottomAccelerationStructures		(VkCommandBuffer	cmdBuffer);
227e5c31af7Sopenharmony_ci	de::MovePtr<BottomLevelAccelerationStructure>				initBottomAccelerationStructure			(VkCommandBuffer	cmdBuffer,
228e5c31af7Sopenharmony_ci																										 tcu::UVec2&		startPos);
229e5c31af7Sopenharmony_ci
230e5c31af7Sopenharmony_ciprivate:
231e5c31af7Sopenharmony_ci	CaseDef														m_data;
232e5c31af7Sopenharmony_ci	VkShaderStageFlags											m_shaders;
233e5c31af7Sopenharmony_ci	deUint32													m_raygenShaderGroup;
234e5c31af7Sopenharmony_ci	deUint32													m_missShaderGroup;
235e5c31af7Sopenharmony_ci	deUint32													m_hitShaderGroup;
236e5c31af7Sopenharmony_ci	deUint32													m_callableShaderGroup;
237e5c31af7Sopenharmony_ci	deUint32													m_shaderGroupCount;
238e5c31af7Sopenharmony_ci};
239e5c31af7Sopenharmony_ci
240e5c31af7Sopenharmony_ciRayTracingBuiltinLaunchTestInstance::RayTracingBuiltinLaunchTestInstance (Context& context, const CaseDef& data)
241e5c31af7Sopenharmony_ci	: vkt::TestInstance		(context)
242e5c31af7Sopenharmony_ci	, m_data				(data)
243e5c31af7Sopenharmony_ci	, m_shaders				(0)
244e5c31af7Sopenharmony_ci	, m_raygenShaderGroup	(~0u)
245e5c31af7Sopenharmony_ci	, m_missShaderGroup		(~0u)
246e5c31af7Sopenharmony_ci	, m_hitShaderGroup		(~0u)
247e5c31af7Sopenharmony_ci	, m_callableShaderGroup	(~0u)
248e5c31af7Sopenharmony_ci	, m_shaderGroupCount	(0)
249e5c31af7Sopenharmony_ci{
250e5c31af7Sopenharmony_ci	const VkShaderStageFlags	hitStages	= VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
251e5c31af7Sopenharmony_ci	BinaryCollection&			collection	= m_context.getBinaryCollection();
252e5c31af7Sopenharmony_ci	deUint32					group		= 0;
253e5c31af7Sopenharmony_ci	deUint32					shaderCount	= 0;
254e5c31af7Sopenharmony_ci
255e5c31af7Sopenharmony_ci	if (collection.contains("rgen")) m_shaders |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
256e5c31af7Sopenharmony_ci	if (collection.contains("ahit")) m_shaders |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
257e5c31af7Sopenharmony_ci	if (collection.contains("chit")) m_shaders |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
258e5c31af7Sopenharmony_ci	if (collection.contains("miss")) m_shaders |= VK_SHADER_STAGE_MISS_BIT_KHR;
259e5c31af7Sopenharmony_ci	if (collection.contains("sect")) m_shaders |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
260e5c31af7Sopenharmony_ci	if (collection.contains("call")) m_shaders |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
261e5c31af7Sopenharmony_ci
262e5c31af7Sopenharmony_ci	for (BinaryCollection::Iterator it =  collection.begin(); it != collection.end(); ++it)
263e5c31af7Sopenharmony_ci		shaderCount++;
264e5c31af7Sopenharmony_ci
265e5c31af7Sopenharmony_ci	if (shaderCount != (deUint32)dePop32(m_shaders))
266e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "Unused shaders detected in the collection");
267e5c31af7Sopenharmony_ci
268e5c31af7Sopenharmony_ci	if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))
269e5c31af7Sopenharmony_ci		m_raygenShaderGroup		= group++;
270e5c31af7Sopenharmony_ci
271e5c31af7Sopenharmony_ci	if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))
272e5c31af7Sopenharmony_ci		m_missShaderGroup		= group++;
273e5c31af7Sopenharmony_ci
274e5c31af7Sopenharmony_ci	if (0 != (m_shaders & hitStages))
275e5c31af7Sopenharmony_ci		m_hitShaderGroup		= group++;
276e5c31af7Sopenharmony_ci
277e5c31af7Sopenharmony_ci	if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))
278e5c31af7Sopenharmony_ci		m_callableShaderGroup	= group++;
279e5c31af7Sopenharmony_ci
280e5c31af7Sopenharmony_ci	m_shaderGroupCount = group;
281e5c31af7Sopenharmony_ci}
282e5c31af7Sopenharmony_ci
283e5c31af7Sopenharmony_ciRayTracingBuiltinLaunchTestInstance::~RayTracingBuiltinLaunchTestInstance (void)
284e5c31af7Sopenharmony_ci{
285e5c31af7Sopenharmony_ci}
286e5c31af7Sopenharmony_ci
287e5c31af7Sopenharmony_ciclass RayTracingTestCase : public TestCase
288e5c31af7Sopenharmony_ci{
289e5c31af7Sopenharmony_ci	public:
290e5c31af7Sopenharmony_ci										RayTracingTestCase			(tcu::TestContext& context, const char* name, const CaseDef data);
291e5c31af7Sopenharmony_ci										~RayTracingTestCase			(void);
292e5c31af7Sopenharmony_ci
293e5c31af7Sopenharmony_ci	virtual	void						initPrograms				(SourceCollections& programCollection) const;
294e5c31af7Sopenharmony_ci	virtual TestInstance*				createInstance				(Context& context) const;
295e5c31af7Sopenharmony_ci	virtual void						checkSupport				(Context& context) const;
296e5c31af7Sopenharmony_ci
297e5c31af7Sopenharmony_ciprivate:
298e5c31af7Sopenharmony_ci	static inline const std::string		getIntersectionPassthrough	(void);
299e5c31af7Sopenharmony_ci	static inline const std::string		getMissPassthrough			(void);
300e5c31af7Sopenharmony_ci	static inline const std::string		getHitPassthrough			(void);
301e5c31af7Sopenharmony_ci
302e5c31af7Sopenharmony_ci	CaseDef								m_data;
303e5c31af7Sopenharmony_ci};
304e5c31af7Sopenharmony_ci
305e5c31af7Sopenharmony_ciRayTracingTestCase::RayTracingTestCase (tcu::TestContext& context, const char* name, const CaseDef data)
306e5c31af7Sopenharmony_ci	: vkt::TestCase	(context, name)
307e5c31af7Sopenharmony_ci	, m_data		(data)
308e5c31af7Sopenharmony_ci{
309e5c31af7Sopenharmony_ci}
310e5c31af7Sopenharmony_ci
311e5c31af7Sopenharmony_ciRayTracingTestCase::~RayTracingTestCase	(void)
312e5c31af7Sopenharmony_ci{
313e5c31af7Sopenharmony_ci}
314e5c31af7Sopenharmony_ci
315e5c31af7Sopenharmony_civoid RayTracingTestCase::checkSupport(Context& context) const
316e5c31af7Sopenharmony_ci{
317e5c31af7Sopenharmony_ci	const bool	pipelineFlagSkipTriangles	= ((m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR) != 0);
318e5c31af7Sopenharmony_ci	const bool	pipelineFlagSkipAABSs		= ((m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR) != 0);
319e5c31af7Sopenharmony_ci	const bool	cullingFlags				=  m_data.rayFlagSkipTriangles
320e5c31af7Sopenharmony_ci											|| m_data.rayFlagSkipAABSs
321e5c31af7Sopenharmony_ci											|| pipelineFlagSkipTriangles
322e5c31af7Sopenharmony_ci											|| pipelineFlagSkipAABSs;
323e5c31af7Sopenharmony_ci
324e5c31af7Sopenharmony_ci	context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
325e5c31af7Sopenharmony_ci	context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
326e5c31af7Sopenharmony_ci
327e5c31af7Sopenharmony_ci	const VkPhysicalDeviceRayTracingPipelineFeaturesKHR&	rayTracingPipelineFeaturesKHR		= context.getRayTracingPipelineFeatures();
328e5c31af7Sopenharmony_ci	if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE )
329e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
330e5c31af7Sopenharmony_ci
331e5c31af7Sopenharmony_ci	const VkPhysicalDeviceAccelerationStructureFeaturesKHR&	accelerationStructureFeaturesKHR	= context.getAccelerationStructureFeatures();
332e5c31af7Sopenharmony_ci	if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
333e5c31af7Sopenharmony_ci		TCU_THROW(TestError, "VK_KHR_ray_tracing_pipeline requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
334e5c31af7Sopenharmony_ci
335e5c31af7Sopenharmony_ci	if (cullingFlags && rayTracingPipelineFeaturesKHR.rayTraversalPrimitiveCulling == DE_FALSE)
336e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTraversalPrimitiveCulling");
337e5c31af7Sopenharmony_ci
338e5c31af7Sopenharmony_ci	if (m_data.useMaintenance5)
339e5c31af7Sopenharmony_ci		context.requireDeviceFunctionality("VK_KHR_maintenance5");
340e5c31af7Sopenharmony_ci}
341e5c31af7Sopenharmony_ci
342e5c31af7Sopenharmony_ciconst std::string RayTracingTestCase::getIntersectionPassthrough (void)
343e5c31af7Sopenharmony_ci{
344e5c31af7Sopenharmony_ci	const std::string intersectionPassthrough =
345e5c31af7Sopenharmony_ci		"#version 460 core\n"
346e5c31af7Sopenharmony_ci		"#extension GL_EXT_ray_tracing : require\n"
347e5c31af7Sopenharmony_ci		"hitAttributeEXT vec3 hitAttribute;\n"
348e5c31af7Sopenharmony_ci		"\n"
349e5c31af7Sopenharmony_ci		"void main()\n"
350e5c31af7Sopenharmony_ci		"{\n"
351e5c31af7Sopenharmony_ci		"  reportIntersectionEXT(0.95f, 0x7Eu);\n"
352e5c31af7Sopenharmony_ci		"}\n";
353e5c31af7Sopenharmony_ci
354e5c31af7Sopenharmony_ci	return intersectionPassthrough;
355e5c31af7Sopenharmony_ci}
356e5c31af7Sopenharmony_ci
357e5c31af7Sopenharmony_ciconst std::string RayTracingTestCase::getMissPassthrough (void)
358e5c31af7Sopenharmony_ci{
359e5c31af7Sopenharmony_ci	const std::string missPassthrough =
360e5c31af7Sopenharmony_ci		"#version 460 core\n"
361e5c31af7Sopenharmony_ci		"#extension GL_EXT_ray_tracing : require\n"
362e5c31af7Sopenharmony_ci		"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
363e5c31af7Sopenharmony_ci		"\n"
364e5c31af7Sopenharmony_ci		"void main()\n"
365e5c31af7Sopenharmony_ci		"{\n"
366e5c31af7Sopenharmony_ci		"}\n";
367e5c31af7Sopenharmony_ci
368e5c31af7Sopenharmony_ci	return missPassthrough;
369e5c31af7Sopenharmony_ci}
370e5c31af7Sopenharmony_ci
371e5c31af7Sopenharmony_ciconst std::string RayTracingTestCase::getHitPassthrough (void)
372e5c31af7Sopenharmony_ci{
373e5c31af7Sopenharmony_ci	const std::string hitPassthrough =
374e5c31af7Sopenharmony_ci		"#version 460 core\n"
375e5c31af7Sopenharmony_ci		"#extension GL_EXT_ray_tracing : require\n"
376e5c31af7Sopenharmony_ci		"hitAttributeEXT vec3 attribs;\n"
377e5c31af7Sopenharmony_ci		"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
378e5c31af7Sopenharmony_ci		"\n"
379e5c31af7Sopenharmony_ci		"void main()\n"
380e5c31af7Sopenharmony_ci		"{\n"
381e5c31af7Sopenharmony_ci		"}\n";
382e5c31af7Sopenharmony_ci
383e5c31af7Sopenharmony_ci	return hitPassthrough;
384e5c31af7Sopenharmony_ci}
385e5c31af7Sopenharmony_ci
386e5c31af7Sopenharmony_civoid RayTracingTestCase::initPrograms (SourceCollections& programCollection) const
387e5c31af7Sopenharmony_ci{
388e5c31af7Sopenharmony_ci	const bool useSC = m_data.useSpecConstants;
389e5c31af7Sopenharmony_ci	DE_ASSERT(!useSC || m_data.id == TEST_ID_LAUNCH_ID_EXT);
390e5c31af7Sopenharmony_ci
391e5c31af7Sopenharmony_ci	const vk::ShaderBuildOptions	buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
392e5c31af7Sopenharmony_ci
393e5c31af7Sopenharmony_ci	if (m_data.id == TEST_ID_LAUNCH_ID_EXT || m_data.id == TEST_ID_LAUNCH_SIZE_EXT)
394e5c31af7Sopenharmony_ci	{
395e5c31af7Sopenharmony_ci		const std::string	specConstants	=
396e5c31af7Sopenharmony_ci			"layout (constant_id=0) const highp int factor1 = 1;\n"
397e5c31af7Sopenharmony_ci			"layout (constant_id=1) const highp float factor2 = 2.0;\n"
398e5c31af7Sopenharmony_ci			;
399e5c31af7Sopenharmony_ci
400e5c31af7Sopenharmony_ci		const std::string	updateImage		=
401e5c31af7Sopenharmony_ci			"  ivec3 p = ivec3(gl_LaunchIDEXT);\n"
402e5c31af7Sopenharmony_ci			"  ivec3 v = ivec3(gl_" + std::string(m_data.name) + ");\n"
403e5c31af7Sopenharmony_ci			"  int   r = v.x + " + (useSC ? "factor1" : "256") + " * (v.y + " + (useSC ? "int(factor2)" : "256") + " * v.z) + 1;\n"
404e5c31af7Sopenharmony_ci			"  ivec4 c = ivec4(r,0,0,1);\n"
405e5c31af7Sopenharmony_ci			"  imageStore(result, p, c);\n";
406e5c31af7Sopenharmony_ci
407e5c31af7Sopenharmony_ci		switch (m_data.stage)
408e5c31af7Sopenharmony_ci		{
409e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
410e5c31af7Sopenharmony_ci			{
411e5c31af7Sopenharmony_ci				std::stringstream css;
412e5c31af7Sopenharmony_ci				css <<
413e5c31af7Sopenharmony_ci					"#version 460 core\n"
414e5c31af7Sopenharmony_ci					"#extension GL_EXT_ray_tracing : require\n"
415e5c31af7Sopenharmony_ci					<< (useSC ? specConstants : "") <<
416e5c31af7Sopenharmony_ci					"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
417e5c31af7Sopenharmony_ci					"\n"
418e5c31af7Sopenharmony_ci					"void main()\n"
419e5c31af7Sopenharmony_ci					"{\n"
420e5c31af7Sopenharmony_ci					<< updateImage <<
421e5c31af7Sopenharmony_ci					"}\n";
422e5c31af7Sopenharmony_ci
423e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
424e5c31af7Sopenharmony_ci
425e5c31af7Sopenharmony_ci				break;
426e5c31af7Sopenharmony_ci			}
427e5c31af7Sopenharmony_ci
428e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
429e5c31af7Sopenharmony_ci			{
430e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
431e5c31af7Sopenharmony_ci
432e5c31af7Sopenharmony_ci				{
433e5c31af7Sopenharmony_ci					std::stringstream css;
434e5c31af7Sopenharmony_ci					css <<
435e5c31af7Sopenharmony_ci						"#version 460 core\n"
436e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
437e5c31af7Sopenharmony_ci						<< (useSC ? specConstants : "") <<
438e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 attribs;\n"
439e5c31af7Sopenharmony_ci						"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
440e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
441e5c31af7Sopenharmony_ci						"\n"
442e5c31af7Sopenharmony_ci						"void main()\n"
443e5c31af7Sopenharmony_ci						"{\n"
444e5c31af7Sopenharmony_ci						<< updateImage <<
445e5c31af7Sopenharmony_ci						"}\n";
446e5c31af7Sopenharmony_ci
447e5c31af7Sopenharmony_ci					programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
448e5c31af7Sopenharmony_ci				}
449e5c31af7Sopenharmony_ci
450e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
451e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
452e5c31af7Sopenharmony_ci
453e5c31af7Sopenharmony_ci				break;
454e5c31af7Sopenharmony_ci			}
455e5c31af7Sopenharmony_ci
456e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
457e5c31af7Sopenharmony_ci			{
458e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
459e5c31af7Sopenharmony_ci
460e5c31af7Sopenharmony_ci				{
461e5c31af7Sopenharmony_ci					std::stringstream css;
462e5c31af7Sopenharmony_ci					css <<
463e5c31af7Sopenharmony_ci						"#version 460 core\n"
464e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
465e5c31af7Sopenharmony_ci						<< (useSC ? specConstants : "") <<
466e5c31af7Sopenharmony_ci						"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
467e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 attribs;\n"
468e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
469e5c31af7Sopenharmony_ci						"\n"
470e5c31af7Sopenharmony_ci						"void main()\n"
471e5c31af7Sopenharmony_ci						"{\n"
472e5c31af7Sopenharmony_ci						<< updateImage <<
473e5c31af7Sopenharmony_ci						"}\n";
474e5c31af7Sopenharmony_ci
475e5c31af7Sopenharmony_ci					programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
476e5c31af7Sopenharmony_ci				}
477e5c31af7Sopenharmony_ci
478e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
479e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
480e5c31af7Sopenharmony_ci
481e5c31af7Sopenharmony_ci				break;
482e5c31af7Sopenharmony_ci			}
483e5c31af7Sopenharmony_ci
484e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
485e5c31af7Sopenharmony_ci			{
486e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
487e5c31af7Sopenharmony_ci
488e5c31af7Sopenharmony_ci				{
489e5c31af7Sopenharmony_ci					std::stringstream css;
490e5c31af7Sopenharmony_ci					css <<
491e5c31af7Sopenharmony_ci						"#version 460 core\n"
492e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
493e5c31af7Sopenharmony_ci						<< (useSC ? specConstants : "") <<
494e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 hitAttribute;\n"
495e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
496e5c31af7Sopenharmony_ci						"\n"
497e5c31af7Sopenharmony_ci						"void main()\n"
498e5c31af7Sopenharmony_ci						"{\n"
499e5c31af7Sopenharmony_ci						<< updateImage <<
500e5c31af7Sopenharmony_ci						"  hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n"
501e5c31af7Sopenharmony_ci						"  reportIntersectionEXT(1.0f, 0);\n"
502e5c31af7Sopenharmony_ci						"}\n";
503e5c31af7Sopenharmony_ci
504e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
505e5c31af7Sopenharmony_ci				}
506e5c31af7Sopenharmony_ci
507e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
508e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
509e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
510e5c31af7Sopenharmony_ci
511e5c31af7Sopenharmony_ci				break;
512e5c31af7Sopenharmony_ci			}
513e5c31af7Sopenharmony_ci
514e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_MISS_BIT_KHR:
515e5c31af7Sopenharmony_ci			{
516e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
517e5c31af7Sopenharmony_ci
518e5c31af7Sopenharmony_ci				{
519e5c31af7Sopenharmony_ci					std::stringstream css;
520e5c31af7Sopenharmony_ci					css <<
521e5c31af7Sopenharmony_ci						"#version 460 core\n"
522e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
523e5c31af7Sopenharmony_ci						<< (useSC ? specConstants : "") <<
524e5c31af7Sopenharmony_ci						"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
525e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
526e5c31af7Sopenharmony_ci						"\n"
527e5c31af7Sopenharmony_ci						"void main()\n"
528e5c31af7Sopenharmony_ci						"{\n"
529e5c31af7Sopenharmony_ci						<< updateImage <<
530e5c31af7Sopenharmony_ci						"}\n";
531e5c31af7Sopenharmony_ci
532e5c31af7Sopenharmony_ci					programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
533e5c31af7Sopenharmony_ci				}
534e5c31af7Sopenharmony_ci
535e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
536e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
537e5c31af7Sopenharmony_ci
538e5c31af7Sopenharmony_ci				break;
539e5c31af7Sopenharmony_ci			}
540e5c31af7Sopenharmony_ci
541e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
542e5c31af7Sopenharmony_ci			{
543e5c31af7Sopenharmony_ci				{
544e5c31af7Sopenharmony_ci					std::stringstream css;
545e5c31af7Sopenharmony_ci					css <<
546e5c31af7Sopenharmony_ci						"#version 460 core\n"
547e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
548e5c31af7Sopenharmony_ci						"layout(location = 0) callableDataEXT float dummy;"
549e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
550e5c31af7Sopenharmony_ci						"\n"
551e5c31af7Sopenharmony_ci						"void main()\n"
552e5c31af7Sopenharmony_ci						"{\n"
553e5c31af7Sopenharmony_ci						"  executeCallableEXT(0, 0);\n"
554e5c31af7Sopenharmony_ci						"}\n";
555e5c31af7Sopenharmony_ci
556e5c31af7Sopenharmony_ci					programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
557e5c31af7Sopenharmony_ci				}
558e5c31af7Sopenharmony_ci
559e5c31af7Sopenharmony_ci				{
560e5c31af7Sopenharmony_ci					std::stringstream css;
561e5c31af7Sopenharmony_ci					css <<
562e5c31af7Sopenharmony_ci						"#version 460 core\n"
563e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
564e5c31af7Sopenharmony_ci						<< (useSC ? specConstants : "") <<
565e5c31af7Sopenharmony_ci						"layout(location = 0) callableDataInEXT float dummy;"
566e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
567e5c31af7Sopenharmony_ci						"\n"
568e5c31af7Sopenharmony_ci						"void main()\n"
569e5c31af7Sopenharmony_ci						"{\n"
570e5c31af7Sopenharmony_ci						<< updateImage <<
571e5c31af7Sopenharmony_ci						"}\n";
572e5c31af7Sopenharmony_ci
573e5c31af7Sopenharmony_ci					programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
574e5c31af7Sopenharmony_ci				}
575e5c31af7Sopenharmony_ci
576e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
577e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
578e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
579e5c31af7Sopenharmony_ci
580e5c31af7Sopenharmony_ci				break;
581e5c31af7Sopenharmony_ci			}
582e5c31af7Sopenharmony_ci
583e5c31af7Sopenharmony_ci			default:
584e5c31af7Sopenharmony_ci				TCU_THROW(InternalError, "Unknown stage");
585e5c31af7Sopenharmony_ci		}
586e5c31af7Sopenharmony_ci	}
587e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_GEOMETRY_INDEX_EXT		||
588e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_PRIMITIVE_ID				||
589e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_INSTANCE_ID				||
590e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_INSTANCE_CUSTOM_INDEX_EXT	||
591e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_HIT_KIND_EXT				)
592e5c31af7Sopenharmony_ci	{
593e5c31af7Sopenharmony_ci		const std::string	conditionGeometryIndex	= "  int   n = int(gl_LaunchIDEXT.x + gl_LaunchSizeEXT.x * (gl_LaunchIDEXT.y + gl_LaunchSizeEXT.y * gl_LaunchIDEXT.z));\n"
594e5c31af7Sopenharmony_ci													  "  int   m = (n / " + de::toString(m_data.squaresGroupCount) + ") % " + de::toString(m_data.geometriesGroupCount) + ";\n"
595e5c31af7Sopenharmony_ci													  "  if (r == m)";
596e5c31af7Sopenharmony_ci		const std::string	conditionPrimitiveId	= "  int   n = int(gl_LaunchIDEXT.x + gl_LaunchSizeEXT.x * (gl_LaunchIDEXT.y + gl_LaunchSizeEXT.y * gl_LaunchIDEXT.z));\n"
597e5c31af7Sopenharmony_ci													  "  int   m = n % " + de::toString(m_data.squaresGroupCount) + ";\n"
598e5c31af7Sopenharmony_ci													  "  if (r == m)";
599e5c31af7Sopenharmony_ci		const std::string	condition				= (m_data.id == TEST_ID_GEOMETRY_INDEX_EXT) && (m_data.geomType == GEOM_TYPE_AABBS) ? conditionGeometryIndex
600e5c31af7Sopenharmony_ci													: (m_data.id == TEST_ID_PRIMITIVE_ID) && (m_data.geomType == GEOM_TYPE_AABBS) ? conditionPrimitiveId
601e5c31af7Sopenharmony_ci													: "";
602e5c31af7Sopenharmony_ci		const std::string	updateImage				=
603e5c31af7Sopenharmony_ci			"  ivec3 p = ivec3(gl_LaunchIDEXT);\n"
604e5c31af7Sopenharmony_ci			"  int   r = int(gl_" + std::string(m_data.name) + ");\n"
605e5c31af7Sopenharmony_ci			"  ivec4 c = ivec4(r,0,0,1);\n"
606e5c31af7Sopenharmony_ci			+ condition + "  imageStore(result, p, c);\n";
607e5c31af7Sopenharmony_ci
608e5c31af7Sopenharmony_ci		switch (m_data.stage)
609e5c31af7Sopenharmony_ci		{
610e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
611e5c31af7Sopenharmony_ci			{
612e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
613e5c31af7Sopenharmony_ci
614e5c31af7Sopenharmony_ci				{
615e5c31af7Sopenharmony_ci					std::stringstream css;
616e5c31af7Sopenharmony_ci					css <<
617e5c31af7Sopenharmony_ci						"#version 460 core\n"
618e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
619e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 attribs;\n"
620e5c31af7Sopenharmony_ci						"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
621e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
622e5c31af7Sopenharmony_ci						"\n"
623e5c31af7Sopenharmony_ci						"void main()\n"
624e5c31af7Sopenharmony_ci						"{\n"
625e5c31af7Sopenharmony_ci						<< updateImage <<
626e5c31af7Sopenharmony_ci						"}\n";
627e5c31af7Sopenharmony_ci
628e5c31af7Sopenharmony_ci					programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
629e5c31af7Sopenharmony_ci				}
630e5c31af7Sopenharmony_ci
631e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
632e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
633e5c31af7Sopenharmony_ci
634e5c31af7Sopenharmony_ci				if (m_data.geomType == GEOM_TYPE_AABBS)
635e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(getIntersectionPassthrough())) << buildOptions;
636e5c31af7Sopenharmony_ci
637e5c31af7Sopenharmony_ci				break;
638e5c31af7Sopenharmony_ci			}
639e5c31af7Sopenharmony_ci
640e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
641e5c31af7Sopenharmony_ci			{
642e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
643e5c31af7Sopenharmony_ci
644e5c31af7Sopenharmony_ci				{
645e5c31af7Sopenharmony_ci					std::stringstream css;
646e5c31af7Sopenharmony_ci					css <<
647e5c31af7Sopenharmony_ci						"#version 460 core\n"
648e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
649e5c31af7Sopenharmony_ci						"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
650e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 attribs;\n"
651e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
652e5c31af7Sopenharmony_ci						"\n"
653e5c31af7Sopenharmony_ci						"void main()\n"
654e5c31af7Sopenharmony_ci						"{\n"
655e5c31af7Sopenharmony_ci						<< updateImage <<
656e5c31af7Sopenharmony_ci						"}\n";
657e5c31af7Sopenharmony_ci
658e5c31af7Sopenharmony_ci					programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
659e5c31af7Sopenharmony_ci				}
660e5c31af7Sopenharmony_ci
661e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
662e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
663e5c31af7Sopenharmony_ci
664e5c31af7Sopenharmony_ci				if (m_data.geomType == GEOM_TYPE_AABBS)
665e5c31af7Sopenharmony_ci				{
666e5c31af7Sopenharmony_ci					const std::string intersectionShaderSingle	=
667e5c31af7Sopenharmony_ci						"#version 460 core\n"
668e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
669e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 hitAttribute;\n"
670e5c31af7Sopenharmony_ci						"\n"
671e5c31af7Sopenharmony_ci						"void main()\n"
672e5c31af7Sopenharmony_ci						"{\n"
673e5c31af7Sopenharmony_ci						"  int r = int(gl_" + std::string(m_data.name) + ");\n"
674e5c31af7Sopenharmony_ci						+ condition + "  reportIntersectionEXT(0.95f, 0x7Eu);\n"
675e5c31af7Sopenharmony_ci						"}\n";
676e5c31af7Sopenharmony_ci					const std::string intersectionShader		= condition.empty() ? getIntersectionPassthrough() : intersectionShaderSingle;
677e5c31af7Sopenharmony_ci
678e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
679e5c31af7Sopenharmony_ci				}
680e5c31af7Sopenharmony_ci
681e5c31af7Sopenharmony_ci				break;
682e5c31af7Sopenharmony_ci			}
683e5c31af7Sopenharmony_ci
684e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
685e5c31af7Sopenharmony_ci			{
686e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
687e5c31af7Sopenharmony_ci
688e5c31af7Sopenharmony_ci				{
689e5c31af7Sopenharmony_ci					std::stringstream css;
690e5c31af7Sopenharmony_ci					css <<
691e5c31af7Sopenharmony_ci						"#version 460 core\n"
692e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
693e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 hitAttribute;\n"
694e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
695e5c31af7Sopenharmony_ci						"\n"
696e5c31af7Sopenharmony_ci						"void main()\n"
697e5c31af7Sopenharmony_ci						"{\n"
698e5c31af7Sopenharmony_ci						<< updateImage <<
699e5c31af7Sopenharmony_ci						"  reportIntersectionEXT(0.95f, 0);\n"
700e5c31af7Sopenharmony_ci						"}\n";
701e5c31af7Sopenharmony_ci
702e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
703e5c31af7Sopenharmony_ci				}
704e5c31af7Sopenharmony_ci
705e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
706e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
707e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
708e5c31af7Sopenharmony_ci
709e5c31af7Sopenharmony_ci				break;
710e5c31af7Sopenharmony_ci			}
711e5c31af7Sopenharmony_ci
712e5c31af7Sopenharmony_ci			default:
713e5c31af7Sopenharmony_ci				TCU_THROW(InternalError, "Unknown stage");
714e5c31af7Sopenharmony_ci		}
715e5c31af7Sopenharmony_ci	}
716e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_EXT)
717e5c31af7Sopenharmony_ci	{
718e5c31af7Sopenharmony_ci		const bool			cullingFlags			= m_data.rayFlagSkipTriangles || m_data.rayFlagSkipAABSs;
719e5c31af7Sopenharmony_ci		const std::string	cullingFlagsInit		= (m_data.rayFlagSkipTriangles && m_data.rayFlagSkipAABSs) ? "gl_RayFlagsSkipTrianglesEXT|gl_RayFlagsSkipAABBEXT"
720e5c31af7Sopenharmony_ci													: m_data.rayFlagSkipTriangles ? "gl_RayFlagsSkipTrianglesEXT"
721e5c31af7Sopenharmony_ci													: m_data.rayFlagSkipAABSs ? "gl_RayFlagsSkipAABBEXT"
722e5c31af7Sopenharmony_ci													: "gl_RayFlagsNoneEXT";
723e5c31af7Sopenharmony_ci		const std::string	updateImage				=
724e5c31af7Sopenharmony_ci			"  ivec3 p = ivec3(gl_LaunchIDEXT);\n"
725e5c31af7Sopenharmony_ci			"  int   r = int(gl_" + std::string(m_data.name) + ");\n"
726e5c31af7Sopenharmony_ci			"  ivec4 c = ivec4(r,0,0,1);\n"
727e5c31af7Sopenharmony_ci			"  imageStore(result, p, c);\n";
728e5c31af7Sopenharmony_ci		const std::string	intersectionShader		=
729e5c31af7Sopenharmony_ci			"#version 460 core\n"
730e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
731e5c31af7Sopenharmony_ci			"hitAttributeEXT vec3 hitAttribute;\n"
732e5c31af7Sopenharmony_ci			"\n"
733e5c31af7Sopenharmony_ci			"void main()\n"
734e5c31af7Sopenharmony_ci			"{\n"
735e5c31af7Sopenharmony_ci			"  uint hitKind = " + std::string(m_data.frontFace ? "0x7Eu" : "0x7Fu") + ";\n"
736e5c31af7Sopenharmony_ci			"  reportIntersectionEXT(0.95f, hitKind);\n"
737e5c31af7Sopenharmony_ci			"}\n";
738e5c31af7Sopenharmony_ci		const std::string	raygenFlagsFragment		=
739e5c31af7Sopenharmony_ci			"\n"
740e5c31af7Sopenharmony_ci			"  if      (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_OPAQUE_EXT                     ) + "))) f = f | gl_RayFlagsOpaqueEXT;\n"
741e5c31af7Sopenharmony_ci			"  else if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_NO_OPAQUE_EXT                  ) + "))) f = f | gl_RayFlagsNoOpaqueEXT;\n"
742e5c31af7Sopenharmony_ci			"  else if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_CULL_OPAQUE_EXT                ) + "))) f = f | gl_RayFlagsCullOpaqueEXT;\n"
743e5c31af7Sopenharmony_ci			"  else if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_CULL_NO_OPAQUE_EXT             ) + "))) f = f | gl_RayFlagsCullNoOpaqueEXT;\n"
744e5c31af7Sopenharmony_ci			"\n"
745e5c31af7Sopenharmony_ci			"  if      (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_CULL_BACK_FACING_TRIANGLES_EXT ) + "))) f = f | gl_RayFlagsCullBackFacingTrianglesEXT;\n"
746e5c31af7Sopenharmony_ci			"  else if (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_CULL_FRONT_FACING_TRIANGLES_EXT) + "))) f = f | gl_RayFlagsCullFrontFacingTrianglesEXT;\n"
747e5c31af7Sopenharmony_ci			"\n"
748e5c31af7Sopenharmony_ci			"  if      (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_TERMINATE_ON_FIRST_HIT_EXT     ) + "))) f = f | gl_RayFlagsTerminateOnFirstHitEXT;\n"
749e5c31af7Sopenharmony_ci			"  if      (0 != (n & (1<<" + de::toString(RAY_FLAG_BIT_SKIP_CLOSEST_HIT_SHADER_EXT    ) + "))) f = f | gl_RayFlagsSkipClosestHitShaderEXT;\n"
750e5c31af7Sopenharmony_ci			"\n";
751e5c31af7Sopenharmony_ci		const std::string	raygenShader			=
752e5c31af7Sopenharmony_ci			"#version 460 core\n"
753e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
754e5c31af7Sopenharmony_ci			+ (cullingFlags ? std::string("#extension GL_EXT_ray_flags_primitive_culling : require\n") : "") +
755e5c31af7Sopenharmony_ci			"layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
756e5c31af7Sopenharmony_ci			"layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
757e5c31af7Sopenharmony_ci			"\n"
758e5c31af7Sopenharmony_ci			"void main()\n"
759e5c31af7Sopenharmony_ci			"{\n"
760e5c31af7Sopenharmony_ci			"  uint  n        = gl_LaunchIDEXT.x + gl_LaunchSizeEXT.x * (gl_LaunchIDEXT.y + gl_LaunchSizeEXT.y * gl_LaunchIDEXT.z);\n"
761e5c31af7Sopenharmony_ci			"  uint  f        = " + cullingFlagsInit + ";\n"
762e5c31af7Sopenharmony_ci			+ raygenFlagsFragment +
763e5c31af7Sopenharmony_ci			"  uint  rayFlags = f;\n"
764e5c31af7Sopenharmony_ci			"  uint  cullMask = 0xFF;\n"
765e5c31af7Sopenharmony_ci			"  float tmin     = 0.0;\n"
766e5c31af7Sopenharmony_ci			"  float tmax     = 9.0;\n"
767e5c31af7Sopenharmony_ci			"  vec3  origin   = vec3((float(gl_LaunchIDEXT.x) + 0.5f) / float(gl_LaunchSizeEXT.x), (float(gl_LaunchIDEXT.y) + 0.5f) / float(gl_LaunchSizeEXT.y), 0.0);\n"
768e5c31af7Sopenharmony_ci			"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
769e5c31af7Sopenharmony_ci			"  traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
770e5c31af7Sopenharmony_ci			"}\n";
771e5c31af7Sopenharmony_ci
772e5c31af7Sopenharmony_ci		switch (m_data.stage)
773e5c31af7Sopenharmony_ci		{
774e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
775e5c31af7Sopenharmony_ci			{
776e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
777e5c31af7Sopenharmony_ci
778e5c31af7Sopenharmony_ci				{
779e5c31af7Sopenharmony_ci					std::stringstream css;
780e5c31af7Sopenharmony_ci					css <<
781e5c31af7Sopenharmony_ci						"#version 460 core\n"
782e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
783e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 hitAttribute;\n"
784e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
785e5c31af7Sopenharmony_ci						"\n"
786e5c31af7Sopenharmony_ci						"void main()\n"
787e5c31af7Sopenharmony_ci						"{\n"
788e5c31af7Sopenharmony_ci						<< updateImage <<
789e5c31af7Sopenharmony_ci						"}\n";
790e5c31af7Sopenharmony_ci
791e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
792e5c31af7Sopenharmony_ci				}
793e5c31af7Sopenharmony_ci
794e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
795e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
796e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
797e5c31af7Sopenharmony_ci
798e5c31af7Sopenharmony_ci				break;
799e5c31af7Sopenharmony_ci			}
800e5c31af7Sopenharmony_ci
801e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
802e5c31af7Sopenharmony_ci			{
803e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
804e5c31af7Sopenharmony_ci
805e5c31af7Sopenharmony_ci				{
806e5c31af7Sopenharmony_ci					std::stringstream css;
807e5c31af7Sopenharmony_ci					css <<
808e5c31af7Sopenharmony_ci						"#version 460 core\n"
809e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
810e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 attribs;\n"
811e5c31af7Sopenharmony_ci						"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
812e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
813e5c31af7Sopenharmony_ci						"\n"
814e5c31af7Sopenharmony_ci						"void main()\n"
815e5c31af7Sopenharmony_ci						"{\n"
816e5c31af7Sopenharmony_ci						<< updateImage <<
817e5c31af7Sopenharmony_ci						"}\n";
818e5c31af7Sopenharmony_ci
819e5c31af7Sopenharmony_ci					programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
820e5c31af7Sopenharmony_ci				}
821e5c31af7Sopenharmony_ci
822e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
823e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
824e5c31af7Sopenharmony_ci
825e5c31af7Sopenharmony_ci				if (m_data.geomType == GEOM_TYPE_AABBS)
826e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
827e5c31af7Sopenharmony_ci
828e5c31af7Sopenharmony_ci				break;
829e5c31af7Sopenharmony_ci			}
830e5c31af7Sopenharmony_ci
831e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
832e5c31af7Sopenharmony_ci			{
833e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
834e5c31af7Sopenharmony_ci
835e5c31af7Sopenharmony_ci				{
836e5c31af7Sopenharmony_ci					std::stringstream css;
837e5c31af7Sopenharmony_ci					css <<
838e5c31af7Sopenharmony_ci						"#version 460 core\n"
839e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
840e5c31af7Sopenharmony_ci						"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
841e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 attribs;\n"
842e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
843e5c31af7Sopenharmony_ci						"\n"
844e5c31af7Sopenharmony_ci						"void main()\n"
845e5c31af7Sopenharmony_ci						"{\n"
846e5c31af7Sopenharmony_ci						<< updateImage <<
847e5c31af7Sopenharmony_ci						"}\n";
848e5c31af7Sopenharmony_ci
849e5c31af7Sopenharmony_ci					programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
850e5c31af7Sopenharmony_ci				}
851e5c31af7Sopenharmony_ci
852e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
853e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
854e5c31af7Sopenharmony_ci
855e5c31af7Sopenharmony_ci				if (m_data.geomType == GEOM_TYPE_AABBS)
856e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
857e5c31af7Sopenharmony_ci
858e5c31af7Sopenharmony_ci				break;
859e5c31af7Sopenharmony_ci			}
860e5c31af7Sopenharmony_ci
861e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_MISS_BIT_KHR:
862e5c31af7Sopenharmony_ci			{
863e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
864e5c31af7Sopenharmony_ci
865e5c31af7Sopenharmony_ci				{
866e5c31af7Sopenharmony_ci					std::stringstream css;
867e5c31af7Sopenharmony_ci					css <<
868e5c31af7Sopenharmony_ci						"#version 460 core\n"
869e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
870e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
871e5c31af7Sopenharmony_ci						"\n"
872e5c31af7Sopenharmony_ci						"void main()\n"
873e5c31af7Sopenharmony_ci						"{\n"
874e5c31af7Sopenharmony_ci						<< updateImage <<
875e5c31af7Sopenharmony_ci						"}\n";
876e5c31af7Sopenharmony_ci
877e5c31af7Sopenharmony_ci					programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
878e5c31af7Sopenharmony_ci				}
879e5c31af7Sopenharmony_ci
880e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
881e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
882e5c31af7Sopenharmony_ci
883e5c31af7Sopenharmony_ci				if (m_data.geomType == GEOM_TYPE_AABBS)
884e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
885e5c31af7Sopenharmony_ci
886e5c31af7Sopenharmony_ci				break;
887e5c31af7Sopenharmony_ci			}
888e5c31af7Sopenharmony_ci
889e5c31af7Sopenharmony_ci			default:
890e5c31af7Sopenharmony_ci				TCU_THROW(InternalError, "Unknown stage");
891e5c31af7Sopenharmony_ci		}
892e5c31af7Sopenharmony_ci	}
893e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_HIT_T_EXT		||
894e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_RAY_T_MIN_EXT	||
895e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_RAY_T_MAX_EXT	)
896e5c31af7Sopenharmony_ci	{
897e5c31af7Sopenharmony_ci		const std::string	raygenShader		=
898e5c31af7Sopenharmony_ci			"#version 460 core\n"
899e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
900e5c31af7Sopenharmony_ci			"layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
901e5c31af7Sopenharmony_ci			"layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
902e5c31af7Sopenharmony_ci			"\n"
903e5c31af7Sopenharmony_ci			"void main()\n"
904e5c31af7Sopenharmony_ci			"{\n"
905e5c31af7Sopenharmony_ci			"  uint  cullMask = 0xFF;\n"
906e5c31af7Sopenharmony_ci			"  float a      = float(gl_LaunchIDEXT.x) / gl_LaunchSizeEXT.x;\n"
907e5c31af7Sopenharmony_ci			"  float b      = 1.0f + float(gl_LaunchIDEXT.y) / gl_LaunchSizeEXT.y;\n"
908e5c31af7Sopenharmony_ci			"  float c      = 0.25f * a / b;\n"
909e5c31af7Sopenharmony_ci			"  float tmin   = c;\n"
910e5c31af7Sopenharmony_ci			"  float tmax   = 0.75f + c;\n"
911e5c31af7Sopenharmony_ci			"  vec3  origin = vec3((float(gl_LaunchIDEXT.x) + 0.5f) / float(gl_LaunchSizeEXT.x), (float(gl_LaunchIDEXT.y) + 0.5f) / float(gl_LaunchSizeEXT.y), 0.0);\n"
912e5c31af7Sopenharmony_ci			"  vec3  direct = vec3(0.0, 0.0, -1.0);\n"
913e5c31af7Sopenharmony_ci			"  traceRayEXT(topLevelAS, gl_RayFlagsNoneEXT, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
914e5c31af7Sopenharmony_ci			"}\n";
915e5c31af7Sopenharmony_ci		const std::string	intersectionShader	=
916e5c31af7Sopenharmony_ci			"#version 460 core\n"
917e5c31af7Sopenharmony_ci			"#extension GL_EXT_ray_tracing : require\n"
918e5c31af7Sopenharmony_ci			"hitAttributeEXT vec3 hitAttribute;\n"
919e5c31af7Sopenharmony_ci			"\n"
920e5c31af7Sopenharmony_ci			"void main()\n"
921e5c31af7Sopenharmony_ci			"{\n"
922e5c31af7Sopenharmony_ci			"  float a = float(gl_LaunchIDEXT.x) / gl_LaunchSizeEXT.x;\n"
923e5c31af7Sopenharmony_ci			"  float b = 1.0f + float(gl_LaunchIDEXT.y) / gl_LaunchSizeEXT.y;\n"
924e5c31af7Sopenharmony_ci			"  float c = 0.25f * a / b;\n"
925e5c31af7Sopenharmony_ci			"  reportIntersectionEXT(0.03125f + c, 0);\n"
926e5c31af7Sopenharmony_ci			"}\n";
927e5c31af7Sopenharmony_ci		const std::string	updateImage			=
928e5c31af7Sopenharmony_ci			"  ivec3 p = ivec3(gl_LaunchIDEXT);\n"
929e5c31af7Sopenharmony_ci			"  int   r = int(" +de::toString(FIXED_POINT_DIVISOR) + ".0f * gl_" + std::string(m_data.name) + ");\n"
930e5c31af7Sopenharmony_ci			"  ivec4 c = ivec4(r,0,0,1);\n"
931e5c31af7Sopenharmony_ci			"  imageStore(result, p, c);\n";
932e5c31af7Sopenharmony_ci
933e5c31af7Sopenharmony_ci		switch (m_data.stage)
934e5c31af7Sopenharmony_ci		{
935e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
936e5c31af7Sopenharmony_ci			{
937e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
938e5c31af7Sopenharmony_ci
939e5c31af7Sopenharmony_ci				{
940e5c31af7Sopenharmony_ci					std::stringstream css;
941e5c31af7Sopenharmony_ci					css <<
942e5c31af7Sopenharmony_ci						"#version 460 core\n"
943e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
944e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 attribs;\n"
945e5c31af7Sopenharmony_ci						"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
946e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
947e5c31af7Sopenharmony_ci						"\n"
948e5c31af7Sopenharmony_ci						"void main()\n"
949e5c31af7Sopenharmony_ci						"{\n"
950e5c31af7Sopenharmony_ci						<< updateImage <<
951e5c31af7Sopenharmony_ci						"}\n";
952e5c31af7Sopenharmony_ci
953e5c31af7Sopenharmony_ci					programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
954e5c31af7Sopenharmony_ci				}
955e5c31af7Sopenharmony_ci
956e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
957e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
958e5c31af7Sopenharmony_ci
959e5c31af7Sopenharmony_ci				if (m_data.geomType == GEOM_TYPE_AABBS)
960e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
961e5c31af7Sopenharmony_ci
962e5c31af7Sopenharmony_ci				break;
963e5c31af7Sopenharmony_ci			}
964e5c31af7Sopenharmony_ci
965e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
966e5c31af7Sopenharmony_ci			{
967e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
968e5c31af7Sopenharmony_ci
969e5c31af7Sopenharmony_ci				{
970e5c31af7Sopenharmony_ci					std::stringstream css;
971e5c31af7Sopenharmony_ci					css <<
972e5c31af7Sopenharmony_ci						"#version 460 core\n"
973e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
974e5c31af7Sopenharmony_ci						"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
975e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 attribs;\n"
976e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
977e5c31af7Sopenharmony_ci						"\n"
978e5c31af7Sopenharmony_ci						"void main()\n"
979e5c31af7Sopenharmony_ci						"{\n"
980e5c31af7Sopenharmony_ci						<< updateImage <<
981e5c31af7Sopenharmony_ci						"}\n";
982e5c31af7Sopenharmony_ci
983e5c31af7Sopenharmony_ci					programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
984e5c31af7Sopenharmony_ci				}
985e5c31af7Sopenharmony_ci
986e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
987e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
988e5c31af7Sopenharmony_ci
989e5c31af7Sopenharmony_ci				if (m_data.geomType == GEOM_TYPE_AABBS)
990e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
991e5c31af7Sopenharmony_ci
992e5c31af7Sopenharmony_ci				break;
993e5c31af7Sopenharmony_ci			}
994e5c31af7Sopenharmony_ci
995e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
996e5c31af7Sopenharmony_ci			{
997e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
998e5c31af7Sopenharmony_ci
999e5c31af7Sopenharmony_ci				{
1000e5c31af7Sopenharmony_ci					std::stringstream css;
1001e5c31af7Sopenharmony_ci					css <<
1002e5c31af7Sopenharmony_ci						"#version 460 core\n"
1003e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
1004e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 hitAttribute;\n"
1005e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1006e5c31af7Sopenharmony_ci						"\n"
1007e5c31af7Sopenharmony_ci						"void main()\n"
1008e5c31af7Sopenharmony_ci						"{\n"
1009e5c31af7Sopenharmony_ci						<< updateImage <<
1010e5c31af7Sopenharmony_ci						"\n"
1011e5c31af7Sopenharmony_ci						"  float a = float(gl_LaunchIDEXT.x) / gl_LaunchSizeEXT.x;\n"
1012e5c31af7Sopenharmony_ci						"  float b = 1.0f + float(gl_LaunchIDEXT.y) / gl_LaunchSizeEXT.y;\n"
1013e5c31af7Sopenharmony_ci						"  reportIntersectionEXT(0.4375f + 0.25f * a / b, 0x7Eu);\n"
1014e5c31af7Sopenharmony_ci						"}\n";
1015e5c31af7Sopenharmony_ci
1016e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1017e5c31af7Sopenharmony_ci				}
1018e5c31af7Sopenharmony_ci
1019e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1020e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1021e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1022e5c31af7Sopenharmony_ci
1023e5c31af7Sopenharmony_ci				break;
1024e5c31af7Sopenharmony_ci			}
1025e5c31af7Sopenharmony_ci
1026e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_MISS_BIT_KHR:
1027e5c31af7Sopenharmony_ci			{
1028e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(raygenShader)) << buildOptions;
1029e5c31af7Sopenharmony_ci
1030e5c31af7Sopenharmony_ci				{
1031e5c31af7Sopenharmony_ci					std::stringstream css;
1032e5c31af7Sopenharmony_ci					css <<
1033e5c31af7Sopenharmony_ci						"#version 460 core\n"
1034e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
1035e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1036e5c31af7Sopenharmony_ci						"\n"
1037e5c31af7Sopenharmony_ci						"void main()\n"
1038e5c31af7Sopenharmony_ci						"{\n"
1039e5c31af7Sopenharmony_ci						<< updateImage <<
1040e5c31af7Sopenharmony_ci						"}\n";
1041e5c31af7Sopenharmony_ci
1042e5c31af7Sopenharmony_ci					programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1043e5c31af7Sopenharmony_ci				}
1044e5c31af7Sopenharmony_ci
1045e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1046e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1047e5c31af7Sopenharmony_ci
1048e5c31af7Sopenharmony_ci				if (m_data.geomType == GEOM_TYPE_AABBS)
1049e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(intersectionShader)) << buildOptions;
1050e5c31af7Sopenharmony_ci
1051e5c31af7Sopenharmony_ci				break;
1052e5c31af7Sopenharmony_ci			}
1053e5c31af7Sopenharmony_ci
1054e5c31af7Sopenharmony_ci			default:
1055e5c31af7Sopenharmony_ci				TCU_THROW(InternalError, "Unknown stage");
1056e5c31af7Sopenharmony_ci		}
1057e5c31af7Sopenharmony_ci	}
1058e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_WORLD_RAY_ORIGIN_EXT		||
1059e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_WORLD_RAY_DIRECTION_EXT	||
1060e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_OBJECT_RAY_ORIGIN_EXT		||
1061e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_OBJECT_RAY_DIRECTION_EXT	||
1062e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT		||
1063e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT		||
1064e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT	||
1065e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT	)
1066e5c31af7Sopenharmony_ci	{
1067e5c31af7Sopenharmony_ci		const bool			matrix4x3			= (m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT || m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT);
1068e5c31af7Sopenharmony_ci		const bool			matrix3x4			= (m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT || m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT);
1069e5c31af7Sopenharmony_ci		const bool			matrixOutput		= matrix4x3 || matrix3x4;
1070e5c31af7Sopenharmony_ci		const std::string	vectorLoop			=
1071e5c31af7Sopenharmony_ci			"  for (int ndx = 0; ndx < 3; ndx++)\n"
1072e5c31af7Sopenharmony_ci			"  {\n";
1073e5c31af7Sopenharmony_ci		const std::string	matrixLoop4x3		=
1074e5c31af7Sopenharmony_ci			"  int ndx = -1;\n"
1075e5c31af7Sopenharmony_ci			"  for (int row = 0; row < 3; row++)\n"
1076e5c31af7Sopenharmony_ci			"  for (int col = 0; col < 4; col++)\n"
1077e5c31af7Sopenharmony_ci			"  {\n"
1078e5c31af7Sopenharmony_ci			"    ndx++;\n";
1079e5c31af7Sopenharmony_ci		const std::string	matrixLoop3x4		=
1080e5c31af7Sopenharmony_ci			"  int ndx = -1;\n"
1081e5c31af7Sopenharmony_ci			"  for (int col = 0; col < 3; col++)\n"
1082e5c31af7Sopenharmony_ci			"  for (int row = 0; row < 4; row++)\n"
1083e5c31af7Sopenharmony_ci			"  {\n"
1084e5c31af7Sopenharmony_ci			"    ndx++;\n";
1085e5c31af7Sopenharmony_ci		const std::string	loop				=
1086e5c31af7Sopenharmony_ci			matrix4x3 ? matrixLoop4x3 :
1087e5c31af7Sopenharmony_ci			matrix3x4 ? matrixLoop3x4 :
1088e5c31af7Sopenharmony_ci			vectorLoop;
1089e5c31af7Sopenharmony_ci		const std::string	index				=
1090e5c31af7Sopenharmony_ci			(matrixOutput ? "[col][row]" : "[ndx]");
1091e5c31af7Sopenharmony_ci		const std::string	updateImage			=
1092e5c31af7Sopenharmony_ci			"  float k = " +de::toString(FIXED_POINT_DIVISOR) + ".0f;\n"
1093e5c31af7Sopenharmony_ci			+ loop +
1094e5c31af7Sopenharmony_ci			"    ivec3 p = ivec3(gl_LaunchIDEXT.xy, ndx);\n"
1095e5c31af7Sopenharmony_ci			"    float r = k * gl_" + std::string(m_data.name) + index + ";\n"
1096e5c31af7Sopenharmony_ci			"    ivec4 c = ivec4(int(r),0,0,1);\n"
1097e5c31af7Sopenharmony_ci			"    imageStore(result, p, c);\n"
1098e5c31af7Sopenharmony_ci			"  }\n";
1099e5c31af7Sopenharmony_ci
1100e5c31af7Sopenharmony_ci		switch (m_data.stage)
1101e5c31af7Sopenharmony_ci		{
1102e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
1103e5c31af7Sopenharmony_ci			{
1104e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1105e5c31af7Sopenharmony_ci
1106e5c31af7Sopenharmony_ci				{
1107e5c31af7Sopenharmony_ci					std::stringstream css;
1108e5c31af7Sopenharmony_ci					css <<
1109e5c31af7Sopenharmony_ci						"#version 460 core\n"
1110e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
1111e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 attribs;\n"
1112e5c31af7Sopenharmony_ci						"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1113e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1114e5c31af7Sopenharmony_ci						"\n"
1115e5c31af7Sopenharmony_ci						"void main()\n"
1116e5c31af7Sopenharmony_ci						"{\n"
1117e5c31af7Sopenharmony_ci						<< updateImage <<
1118e5c31af7Sopenharmony_ci						"}\n";
1119e5c31af7Sopenharmony_ci
1120e5c31af7Sopenharmony_ci					programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1121e5c31af7Sopenharmony_ci				}
1122e5c31af7Sopenharmony_ci
1123e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1124e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1125e5c31af7Sopenharmony_ci
1126e5c31af7Sopenharmony_ci				if (m_data.geomType == GEOM_TYPE_AABBS)
1127e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(getIntersectionPassthrough())) << buildOptions;
1128e5c31af7Sopenharmony_ci
1129e5c31af7Sopenharmony_ci				break;
1130e5c31af7Sopenharmony_ci			}
1131e5c31af7Sopenharmony_ci
1132e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
1133e5c31af7Sopenharmony_ci			{
1134e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1135e5c31af7Sopenharmony_ci
1136e5c31af7Sopenharmony_ci				{
1137e5c31af7Sopenharmony_ci					std::stringstream css;
1138e5c31af7Sopenharmony_ci					css <<
1139e5c31af7Sopenharmony_ci						"#version 460 core\n"
1140e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
1141e5c31af7Sopenharmony_ci						"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
1142e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 attribs;\n"
1143e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1144e5c31af7Sopenharmony_ci						"\n"
1145e5c31af7Sopenharmony_ci						"void main()\n"
1146e5c31af7Sopenharmony_ci						"{\n"
1147e5c31af7Sopenharmony_ci						<< updateImage <<
1148e5c31af7Sopenharmony_ci						"}\n";
1149e5c31af7Sopenharmony_ci
1150e5c31af7Sopenharmony_ci					programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
1151e5c31af7Sopenharmony_ci				}
1152e5c31af7Sopenharmony_ci
1153e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1154e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1155e5c31af7Sopenharmony_ci
1156e5c31af7Sopenharmony_ci				if (m_data.geomType == GEOM_TYPE_AABBS)
1157e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(getIntersectionPassthrough())) << buildOptions;
1158e5c31af7Sopenharmony_ci
1159e5c31af7Sopenharmony_ci				break;
1160e5c31af7Sopenharmony_ci			}
1161e5c31af7Sopenharmony_ci
1162e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
1163e5c31af7Sopenharmony_ci			{
1164e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1165e5c31af7Sopenharmony_ci
1166e5c31af7Sopenharmony_ci				{
1167e5c31af7Sopenharmony_ci					std::stringstream css;
1168e5c31af7Sopenharmony_ci					css <<
1169e5c31af7Sopenharmony_ci						"#version 460 core\n"
1170e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
1171e5c31af7Sopenharmony_ci						"hitAttributeEXT vec3 hitAttribute;\n"
1172e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1173e5c31af7Sopenharmony_ci						"\n"
1174e5c31af7Sopenharmony_ci						"void main()\n"
1175e5c31af7Sopenharmony_ci						"{\n"
1176e5c31af7Sopenharmony_ci						<< updateImage <<
1177e5c31af7Sopenharmony_ci						"  reportIntersectionEXT(0.95f, 0);\n"
1178e5c31af7Sopenharmony_ci						"}\n";
1179e5c31af7Sopenharmony_ci
1180e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
1181e5c31af7Sopenharmony_ci				}
1182e5c31af7Sopenharmony_ci
1183e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1184e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1185e5c31af7Sopenharmony_ci				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;
1186e5c31af7Sopenharmony_ci
1187e5c31af7Sopenharmony_ci				break;
1188e5c31af7Sopenharmony_ci			}
1189e5c31af7Sopenharmony_ci
1190e5c31af7Sopenharmony_ci			case VK_SHADER_STAGE_MISS_BIT_KHR:
1191e5c31af7Sopenharmony_ci			{
1192e5c31af7Sopenharmony_ci				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;
1193e5c31af7Sopenharmony_ci
1194e5c31af7Sopenharmony_ci				{
1195e5c31af7Sopenharmony_ci					std::stringstream css;
1196e5c31af7Sopenharmony_ci					css <<
1197e5c31af7Sopenharmony_ci						"#version 460 core\n"
1198e5c31af7Sopenharmony_ci						"#extension GL_EXT_ray_tracing : require\n"
1199e5c31af7Sopenharmony_ci						"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
1200e5c31af7Sopenharmony_ci						"\n"
1201e5c31af7Sopenharmony_ci						"void main()\n"
1202e5c31af7Sopenharmony_ci						"{\n"
1203e5c31af7Sopenharmony_ci						<< updateImage <<
1204e5c31af7Sopenharmony_ci						"}\n";
1205e5c31af7Sopenharmony_ci
1206e5c31af7Sopenharmony_ci					programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
1207e5c31af7Sopenharmony_ci				}
1208e5c31af7Sopenharmony_ci
1209e5c31af7Sopenharmony_ci				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1210e5c31af7Sopenharmony_ci				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
1211e5c31af7Sopenharmony_ci
1212e5c31af7Sopenharmony_ci				if (m_data.geomType == GEOM_TYPE_AABBS)
1213e5c31af7Sopenharmony_ci					programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(getIntersectionPassthrough())) << buildOptions;
1214e5c31af7Sopenharmony_ci
1215e5c31af7Sopenharmony_ci				break;
1216e5c31af7Sopenharmony_ci			}
1217e5c31af7Sopenharmony_ci
1218e5c31af7Sopenharmony_ci			default:
1219e5c31af7Sopenharmony_ci				TCU_THROW(InternalError, "Unknown stage");
1220e5c31af7Sopenharmony_ci		}
1221e5c31af7Sopenharmony_ci	}
1222e5c31af7Sopenharmony_ci	else
1223e5c31af7Sopenharmony_ci	{
1224e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "Not implemented");
1225e5c31af7Sopenharmony_ci	}
1226e5c31af7Sopenharmony_ci}
1227e5c31af7Sopenharmony_ci
1228e5c31af7Sopenharmony_ciTestInstance* RayTracingTestCase::createInstance (Context& context) const
1229e5c31af7Sopenharmony_ci{
1230e5c31af7Sopenharmony_ci	return new RayTracingBuiltinLaunchTestInstance(context, m_data);
1231e5c31af7Sopenharmony_ci}
1232e5c31af7Sopenharmony_ci
1233e5c31af7Sopenharmony_cide::MovePtr<TopLevelAccelerationStructure> RayTracingBuiltinLaunchTestInstance::initTopAccelerationStructure (VkCommandBuffer											cmdBuffer,
1234e5c31af7Sopenharmony_ci																											  vector<de::SharedPtr<BottomLevelAccelerationStructure> >&	bottomLevelAccelerationStructures)
1235e5c31af7Sopenharmony_ci{
1236e5c31af7Sopenharmony_ci	const DeviceInterface&						vkd				= m_context.getDeviceInterface();
1237e5c31af7Sopenharmony_ci	const VkDevice								device			= m_context.getDevice();
1238e5c31af7Sopenharmony_ci	Allocator&									allocator		= m_context.getDefaultAllocator();
1239e5c31af7Sopenharmony_ci	de::MovePtr<TopLevelAccelerationStructure>	result			= makeTopLevelAccelerationStructure();
1240e5c31af7Sopenharmony_ci	const bool									transformTest	=  m_data.id == TEST_ID_WORLD_RAY_ORIGIN_EXT
1241e5c31af7Sopenharmony_ci																|| m_data.id == TEST_ID_WORLD_RAY_DIRECTION_EXT
1242e5c31af7Sopenharmony_ci																|| m_data.id == TEST_ID_OBJECT_RAY_ORIGIN_EXT
1243e5c31af7Sopenharmony_ci																|| m_data.id == TEST_ID_OBJECT_RAY_DIRECTION_EXT
1244e5c31af7Sopenharmony_ci																|| m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT
1245e5c31af7Sopenharmony_ci																|| m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT
1246e5c31af7Sopenharmony_ci																|| m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT
1247e5c31af7Sopenharmony_ci																|| m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT;
1248e5c31af7Sopenharmony_ci
1249e5c31af7Sopenharmony_ci	result->setInstanceCount(bottomLevelAccelerationStructures.size());
1250e5c31af7Sopenharmony_ci
1251e5c31af7Sopenharmony_ci	for (size_t structNdx = 0; structNdx < bottomLevelAccelerationStructures.size(); ++structNdx)
1252e5c31af7Sopenharmony_ci	{
1253e5c31af7Sopenharmony_ci		VkTransformMatrixKHR	transform	= identityMatrix3x4;
1254e5c31af7Sopenharmony_ci
1255e5c31af7Sopenharmony_ci		if (transformTest)
1256e5c31af7Sopenharmony_ci		{
1257e5c31af7Sopenharmony_ci			if (structNdx & 1)
1258e5c31af7Sopenharmony_ci				transform.matrix[0][3] = (1.0f /  8.0f) / float(m_data.width);
1259e5c31af7Sopenharmony_ci
1260e5c31af7Sopenharmony_ci			if (structNdx & 2)
1261e5c31af7Sopenharmony_ci				transform.matrix[1][3] = (1.0f / 16.0f) / float(m_data.height);
1262e5c31af7Sopenharmony_ci		}
1263e5c31af7Sopenharmony_ci
1264e5c31af7Sopenharmony_ci		result->addInstance(bottomLevelAccelerationStructures[structNdx], transform, deUint32(2 * structNdx));
1265e5c31af7Sopenharmony_ci	}
1266e5c31af7Sopenharmony_ci
1267e5c31af7Sopenharmony_ci	result->createAndBuild(vkd, device, cmdBuffer, allocator);
1268e5c31af7Sopenharmony_ci
1269e5c31af7Sopenharmony_ci	return result;
1270e5c31af7Sopenharmony_ci}
1271e5c31af7Sopenharmony_ci
1272e5c31af7Sopenharmony_cide::MovePtr<BottomLevelAccelerationStructure> RayTracingBuiltinLaunchTestInstance::initBottomAccelerationStructure (VkCommandBuffer	cmdBuffer,
1273e5c31af7Sopenharmony_ci																													tcu::UVec2&		startPos)
1274e5c31af7Sopenharmony_ci{
1275e5c31af7Sopenharmony_ci	const DeviceInterface&							vkd			= m_context.getDeviceInterface();
1276e5c31af7Sopenharmony_ci	const VkDevice									device		= m_context.getDevice();
1277e5c31af7Sopenharmony_ci	Allocator&										allocator	= m_context.getDefaultAllocator();
1278e5c31af7Sopenharmony_ci	de::MovePtr<BottomLevelAccelerationStructure>	result		= makeBottomLevelAccelerationStructure();
1279e5c31af7Sopenharmony_ci
1280e5c31af7Sopenharmony_ci	result->setGeometryCount(m_data.geometriesGroupCount);
1281e5c31af7Sopenharmony_ci
1282e5c31af7Sopenharmony_ci	if (m_data.id == TEST_ID_LAUNCH_ID_EXT || m_data.id == TEST_ID_LAUNCH_SIZE_EXT)
1283e5c31af7Sopenharmony_ci	{
1284e5c31af7Sopenharmony_ci		result->setDefaultGeometryData(m_data.stage);
1285e5c31af7Sopenharmony_ci	}
1286e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_GEOMETRY_INDEX_EXT		||
1287e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_PRIMITIVE_ID				||
1288e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_INSTANCE_ID				||
1289e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_INSTANCE_CUSTOM_INDEX_EXT	)
1290e5c31af7Sopenharmony_ci	{
1291e5c31af7Sopenharmony_ci		const bool	triangles	= (m_data.geomType == GEOM_TYPE_TRIANGLES);
1292e5c31af7Sopenharmony_ci		const bool	missShader	= (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1293e5c31af7Sopenharmony_ci		const float	z			= !missShader ? -1.0f : -100.0f;
1294e5c31af7Sopenharmony_ci
1295e5c31af7Sopenharmony_ci		DE_ASSERT(m_data.squaresGroupCount != 1);
1296e5c31af7Sopenharmony_ci
1297e5c31af7Sopenharmony_ci		for (size_t geometryNdx = 0; geometryNdx < m_data.geometriesGroupCount; ++geometryNdx)
1298e5c31af7Sopenharmony_ci		{
1299e5c31af7Sopenharmony_ci			std::vector<tcu::Vec3>	geometryData;
1300e5c31af7Sopenharmony_ci
1301e5c31af7Sopenharmony_ci			geometryData.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1302e5c31af7Sopenharmony_ci
1303e5c31af7Sopenharmony_ci			for (size_t squareNdx = 0; squareNdx < m_data.squaresGroupCount; ++squareNdx)
1304e5c31af7Sopenharmony_ci			{
1305e5c31af7Sopenharmony_ci				const deUint32	n	= m_data.width * startPos.y() + startPos.x();
1306e5c31af7Sopenharmony_ci				const float		x0	= float(startPos.x() + 0) / float(m_data.width);
1307e5c31af7Sopenharmony_ci				const float		y0	= float(startPos.y() + 0) / float(m_data.height);
1308e5c31af7Sopenharmony_ci				const float		x1	= float(startPos.x() + 1) / float(m_data.width);
1309e5c31af7Sopenharmony_ci				const float		y1	= float(startPos.y() + 1) / float(m_data.height);
1310e5c31af7Sopenharmony_ci				const deUint32	m	= n + 1;
1311e5c31af7Sopenharmony_ci
1312e5c31af7Sopenharmony_ci				if (triangles)
1313e5c31af7Sopenharmony_ci				{
1314e5c31af7Sopenharmony_ci					const float	xm	= (x0 + x1) / 2.0f;
1315e5c31af7Sopenharmony_ci					const float	ym	= (y0 + y1) / 2.0f;
1316e5c31af7Sopenharmony_ci
1317e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(x0, y0, z));
1318e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(xm, y1, z));
1319e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(x1, ym, z));
1320e5c31af7Sopenharmony_ci				}
1321e5c31af7Sopenharmony_ci				else
1322e5c31af7Sopenharmony_ci				{
1323e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(x0, y0, z));
1324e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
1325e5c31af7Sopenharmony_ci				}
1326e5c31af7Sopenharmony_ci
1327e5c31af7Sopenharmony_ci				startPos.y() = m / m_data.width;
1328e5c31af7Sopenharmony_ci				startPos.x() = m % m_data.width;
1329e5c31af7Sopenharmony_ci			}
1330e5c31af7Sopenharmony_ci
1331e5c31af7Sopenharmony_ci			result->addGeometry(geometryData, triangles);
1332e5c31af7Sopenharmony_ci		}
1333e5c31af7Sopenharmony_ci	}
1334e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_HIT_KIND_EXT)
1335e5c31af7Sopenharmony_ci	{
1336e5c31af7Sopenharmony_ci		const bool	triangles	= (m_data.geomType == GEOM_TYPE_TRIANGLES);
1337e5c31af7Sopenharmony_ci		const bool	missShader	= (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1338e5c31af7Sopenharmony_ci		const float	z			= !missShader ? -1.0f : -100.0f;
1339e5c31af7Sopenharmony_ci
1340e5c31af7Sopenharmony_ci		DE_ASSERT(m_data.squaresGroupCount != 1);
1341e5c31af7Sopenharmony_ci		DE_ASSERT(m_data.geometriesGroupCount == 4);
1342e5c31af7Sopenharmony_ci
1343e5c31af7Sopenharmony_ci		std::vector<tcu::Vec3>	geometryDataOpaque;
1344e5c31af7Sopenharmony_ci		std::vector<tcu::Vec3>	geometryDataNonOpaque;
1345e5c31af7Sopenharmony_ci
1346e5c31af7Sopenharmony_ci		geometryDataOpaque.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1347e5c31af7Sopenharmony_ci		geometryDataNonOpaque.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1348e5c31af7Sopenharmony_ci
1349e5c31af7Sopenharmony_ci		for (size_t geometryNdx = 0; geometryNdx < m_data.geometriesGroupCount; ++geometryNdx)
1350e5c31af7Sopenharmony_ci		{
1351e5c31af7Sopenharmony_ci			const bool				cw				= ((geometryNdx & 1) == 0) ? true : false;
1352e5c31af7Sopenharmony_ci			std::vector<tcu::Vec3>&	geometryData	= ((geometryNdx & 2) == 0) ? geometryDataOpaque : geometryDataNonOpaque;
1353e5c31af7Sopenharmony_ci
1354e5c31af7Sopenharmony_ci			for (size_t squareNdx = 0; squareNdx < m_data.squaresGroupCount; ++squareNdx)
1355e5c31af7Sopenharmony_ci			{
1356e5c31af7Sopenharmony_ci				const deUint32	n	= m_data.width * startPos.y() + startPos.x();
1357e5c31af7Sopenharmony_ci				const deUint32	m	= n + 1;
1358e5c31af7Sopenharmony_ci				const float		x0	= float(startPos.x() + 0) / float(m_data.width);
1359e5c31af7Sopenharmony_ci				const float		y0	= float(startPos.y() + 0) / float(m_data.height);
1360e5c31af7Sopenharmony_ci				const float		x1	= float(startPos.x() + 1) / float(m_data.width);
1361e5c31af7Sopenharmony_ci				const float		y1	= float(startPos.y() + 1) / float(m_data.height);
1362e5c31af7Sopenharmony_ci
1363e5c31af7Sopenharmony_ci				if (triangles)
1364e5c31af7Sopenharmony_ci				{
1365e5c31af7Sopenharmony_ci					const float	xm	= (x0 + x1) / 2.0f;
1366e5c31af7Sopenharmony_ci					const float	ym	= (y0 + y1) / 2.0f;
1367e5c31af7Sopenharmony_ci
1368e5c31af7Sopenharmony_ci					if (cw)
1369e5c31af7Sopenharmony_ci					{
1370e5c31af7Sopenharmony_ci						geometryData.push_back(tcu::Vec3(x0, y0, z));
1371e5c31af7Sopenharmony_ci						geometryData.push_back(tcu::Vec3(x1, ym, z));
1372e5c31af7Sopenharmony_ci						geometryData.push_back(tcu::Vec3(xm, y1, z));
1373e5c31af7Sopenharmony_ci					}
1374e5c31af7Sopenharmony_ci					else
1375e5c31af7Sopenharmony_ci					{
1376e5c31af7Sopenharmony_ci						geometryData.push_back(tcu::Vec3(x0, y0, z));
1377e5c31af7Sopenharmony_ci						geometryData.push_back(tcu::Vec3(xm, y1, z));
1378e5c31af7Sopenharmony_ci						geometryData.push_back(tcu::Vec3(x1, ym, z));
1379e5c31af7Sopenharmony_ci					}
1380e5c31af7Sopenharmony_ci				}
1381e5c31af7Sopenharmony_ci				else
1382e5c31af7Sopenharmony_ci				{
1383e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(x0, y0, z));
1384e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
1385e5c31af7Sopenharmony_ci				}
1386e5c31af7Sopenharmony_ci
1387e5c31af7Sopenharmony_ci				startPos.y() = m / m_data.width;
1388e5c31af7Sopenharmony_ci				startPos.x() = m % m_data.width;
1389e5c31af7Sopenharmony_ci			}
1390e5c31af7Sopenharmony_ci		}
1391e5c31af7Sopenharmony_ci
1392e5c31af7Sopenharmony_ci		DE_ASSERT(startPos.y() == m_data.height && startPos.x() == 0);
1393e5c31af7Sopenharmony_ci
1394e5c31af7Sopenharmony_ci		result->addGeometry(geometryDataOpaque, triangles, (VkGeometryFlagsKHR)VK_GEOMETRY_OPAQUE_BIT_KHR);
1395e5c31af7Sopenharmony_ci		result->addGeometry(geometryDataNonOpaque, triangles, (VkGeometryFlagsKHR)0);
1396e5c31af7Sopenharmony_ci	}
1397e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_EXT)
1398e5c31af7Sopenharmony_ci	{
1399e5c31af7Sopenharmony_ci		const bool					triangles		= (m_data.geomType == GEOM_TYPE_TRIANGLES);
1400e5c31af7Sopenharmony_ci		const bool					missShader		= (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1401e5c31af7Sopenharmony_ci		const float					z				= !missShader ? -1.0f : -100.0f;
1402e5c31af7Sopenharmony_ci		const VkGeometryFlagsKHR	geometryFlags	= m_data.opaque ? static_cast<VkGeometryFlagsKHR>(VK_GEOMETRY_OPAQUE_BIT_KHR) : static_cast<VkGeometryFlagsKHR>(0);
1403e5c31af7Sopenharmony_ci		const bool					cw				= m_data.frontFace;
1404e5c31af7Sopenharmony_ci		std::vector<tcu::Vec3>		geometryData;
1405e5c31af7Sopenharmony_ci
1406e5c31af7Sopenharmony_ci		DE_ASSERT(m_data.geometriesGroupCount == 1);
1407e5c31af7Sopenharmony_ci		DE_ASSERT(m_data.squaresGroupCount != 1);
1408e5c31af7Sopenharmony_ci
1409e5c31af7Sopenharmony_ci		geometryData.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1410e5c31af7Sopenharmony_ci
1411e5c31af7Sopenharmony_ci		for (size_t squareNdx = 0; squareNdx < m_data.squaresGroupCount; ++squareNdx)
1412e5c31af7Sopenharmony_ci		{
1413e5c31af7Sopenharmony_ci			const deUint32	n	= m_data.width * startPos.y() + startPos.x();
1414e5c31af7Sopenharmony_ci			const deUint32	m	= n + 1;
1415e5c31af7Sopenharmony_ci			const float		x0	= float(startPos.x() + 0) / float(m_data.width);
1416e5c31af7Sopenharmony_ci			const float		y0	= float(startPos.y() + 0) / float(m_data.height);
1417e5c31af7Sopenharmony_ci			const float		x1	= float(startPos.x() + 1) / float(m_data.width);
1418e5c31af7Sopenharmony_ci			const float		y1	= float(startPos.y() + 1) / float(m_data.height);
1419e5c31af7Sopenharmony_ci
1420e5c31af7Sopenharmony_ci			if (triangles)
1421e5c31af7Sopenharmony_ci			{
1422e5c31af7Sopenharmony_ci				const float	xm	= (x0 + x1) / 2.0f;
1423e5c31af7Sopenharmony_ci				const float	ym	= (y0 + y1) / 2.0f;
1424e5c31af7Sopenharmony_ci
1425e5c31af7Sopenharmony_ci				if (cw)
1426e5c31af7Sopenharmony_ci				{
1427e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(x0, y0, z));
1428e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(x1, ym, z));
1429e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(xm, y1, z));
1430e5c31af7Sopenharmony_ci				}
1431e5c31af7Sopenharmony_ci				else
1432e5c31af7Sopenharmony_ci				{
1433e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(x0, y0, z));
1434e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(xm, y1, z));
1435e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(x1, ym, z));
1436e5c31af7Sopenharmony_ci				}
1437e5c31af7Sopenharmony_ci			}
1438e5c31af7Sopenharmony_ci			else
1439e5c31af7Sopenharmony_ci			{
1440e5c31af7Sopenharmony_ci				geometryData.push_back(tcu::Vec3(x0, y0, z));
1441e5c31af7Sopenharmony_ci				geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
1442e5c31af7Sopenharmony_ci			}
1443e5c31af7Sopenharmony_ci
1444e5c31af7Sopenharmony_ci			startPos.y() = m / m_data.width;
1445e5c31af7Sopenharmony_ci			startPos.x() = m % m_data.width;
1446e5c31af7Sopenharmony_ci		}
1447e5c31af7Sopenharmony_ci
1448e5c31af7Sopenharmony_ci		DE_ASSERT(startPos.y() == m_data.height && startPos.x() == 0);
1449e5c31af7Sopenharmony_ci
1450e5c31af7Sopenharmony_ci		result->addGeometry(geometryData, triangles, geometryFlags);
1451e5c31af7Sopenharmony_ci	}
1452e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_HIT_T_EXT		||
1453e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_RAY_T_MIN_EXT	||
1454e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_RAY_T_MAX_EXT	)
1455e5c31af7Sopenharmony_ci	{
1456e5c31af7Sopenharmony_ci		const bool	triangles	= (m_data.geomType == GEOM_TYPE_TRIANGLES);
1457e5c31af7Sopenharmony_ci		const bool	missShader	= (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1458e5c31af7Sopenharmony_ci		const bool	sectShader	= (m_data.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR);
1459e5c31af7Sopenharmony_ci		const bool	maxTTest	= (m_data.id == TEST_ID_RAY_T_MAX_EXT);
1460e5c31af7Sopenharmony_ci
1461e5c31af7Sopenharmony_ci		DE_ASSERT(m_data.squaresGroupCount != 1);
1462e5c31af7Sopenharmony_ci
1463e5c31af7Sopenharmony_ci		for (size_t geometryNdx = 0; geometryNdx < m_data.geometriesGroupCount; ++geometryNdx)
1464e5c31af7Sopenharmony_ci		{
1465e5c31af7Sopenharmony_ci			std::vector<tcu::Vec3>	geometryData;
1466e5c31af7Sopenharmony_ci
1467e5c31af7Sopenharmony_ci			geometryData.reserve(m_data.squaresGroupCount * (triangles ? 3u : 2u));
1468e5c31af7Sopenharmony_ci
1469e5c31af7Sopenharmony_ci			for (size_t squareNdx = 0; squareNdx < m_data.squaresGroupCount; ++squareNdx)
1470e5c31af7Sopenharmony_ci			{
1471e5c31af7Sopenharmony_ci				const deUint32	n			= m_data.width * startPos.y() + startPos.x();
1472e5c31af7Sopenharmony_ci				const deUint32	m			= n + 1;
1473e5c31af7Sopenharmony_ci				const bool		shiftRight	= sectShader && maxTTest && (0 == (startPos.y() & 1)) && (0 == (startPos.x() & 1));
1474e5c31af7Sopenharmony_ci				const deUint32	xo			= shiftRight ? 1 : 0;
1475e5c31af7Sopenharmony_ci				const float		x0			= float(startPos.x() + 0 + xo) / float(m_data.width);
1476e5c31af7Sopenharmony_ci				const float		y0			= float(startPos.y() + 0) / float(m_data.height);
1477e5c31af7Sopenharmony_ci				const float		x1			= float(startPos.x() + 1 + xo) / float(m_data.width);
1478e5c31af7Sopenharmony_ci				const float		y1			= float(startPos.y() + 1) / float(m_data.height);
1479e5c31af7Sopenharmony_ci				const float		a			= x0;
1480e5c31af7Sopenharmony_ci				const float		b			= 1.0f + y0;
1481e5c31af7Sopenharmony_ci				const float		c			= 0.03125f + 0.25f * a / b;
1482e5c31af7Sopenharmony_ci				const float		z			= !missShader ? -c : -100.0f;
1483e5c31af7Sopenharmony_ci
1484e5c31af7Sopenharmony_ci				if (triangles)
1485e5c31af7Sopenharmony_ci				{
1486e5c31af7Sopenharmony_ci					const float	xm	= (x0 + x1) / 2.0f;
1487e5c31af7Sopenharmony_ci					const float	ym	= (y0 + y1) / 2.0f;
1488e5c31af7Sopenharmony_ci
1489e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(x0, y0, z));
1490e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(xm, y1, z));
1491e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(x1, ym, z));
1492e5c31af7Sopenharmony_ci				}
1493e5c31af7Sopenharmony_ci				else
1494e5c31af7Sopenharmony_ci				{
1495e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(x0, y0, z));
1496e5c31af7Sopenharmony_ci					geometryData.push_back(tcu::Vec3(x1, y1, z * 0.9f));
1497e5c31af7Sopenharmony_ci				}
1498e5c31af7Sopenharmony_ci
1499e5c31af7Sopenharmony_ci				startPos.y() = m / m_data.width;
1500e5c31af7Sopenharmony_ci				startPos.x() = m % m_data.width;
1501e5c31af7Sopenharmony_ci			}
1502e5c31af7Sopenharmony_ci
1503e5c31af7Sopenharmony_ci			result->addGeometry(geometryData, triangles);
1504e5c31af7Sopenharmony_ci		}
1505e5c31af7Sopenharmony_ci	}
1506e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_WORLD_RAY_ORIGIN_EXT		||
1507e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_WORLD_RAY_DIRECTION_EXT	||
1508e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_OBJECT_RAY_ORIGIN_EXT		||
1509e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_OBJECT_RAY_DIRECTION_EXT	||
1510e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT		||
1511e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT		||
1512e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT	||
1513e5c31af7Sopenharmony_ci			 m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT	)
1514e5c31af7Sopenharmony_ci	{
1515e5c31af7Sopenharmony_ci		const bool				triangles		= m_data.geomType == GEOM_TYPE_TRIANGLES;
1516e5c31af7Sopenharmony_ci		const float				y0				= float(startPos.y() + 0) / float(m_data.height);
1517e5c31af7Sopenharmony_ci		const float				y1				= float(startPos.y() + 1) / float(m_data.height);
1518e5c31af7Sopenharmony_ci		const bool				missShader		= (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR);
1519e5c31af7Sopenharmony_ci		const float				z				= !missShader ? -1.0f : -100.0f;
1520e5c31af7Sopenharmony_ci		std::vector<tcu::Vec3>	geometryData;
1521e5c31af7Sopenharmony_ci
1522e5c31af7Sopenharmony_ci		if (triangles)
1523e5c31af7Sopenharmony_ci		{
1524e5c31af7Sopenharmony_ci			geometryData.push_back(tcu::Vec3(-1.0f, y1, z));
1525e5c31af7Sopenharmony_ci			geometryData.push_back(tcu::Vec3(-1.0f, y0, z));
1526e5c31af7Sopenharmony_ci			geometryData.push_back(tcu::Vec3(+1.0f, y0, z));
1527e5c31af7Sopenharmony_ci			geometryData.push_back(tcu::Vec3(-1.0f, y1, z));
1528e5c31af7Sopenharmony_ci			geometryData.push_back(tcu::Vec3(+1.0f, y0, z));
1529e5c31af7Sopenharmony_ci			geometryData.push_back(tcu::Vec3(+1.0f, y1, z));
1530e5c31af7Sopenharmony_ci		}
1531e5c31af7Sopenharmony_ci		else
1532e5c31af7Sopenharmony_ci		{
1533e5c31af7Sopenharmony_ci			geometryData.reserve(2);
1534e5c31af7Sopenharmony_ci
1535e5c31af7Sopenharmony_ci			geometryData.push_back(tcu::Vec3(-1.0f, y0, z));
1536e5c31af7Sopenharmony_ci			geometryData.push_back(tcu::Vec3(+1.0f, y1, z));
1537e5c31af7Sopenharmony_ci		}
1538e5c31af7Sopenharmony_ci
1539e5c31af7Sopenharmony_ci		DE_ASSERT(startPos.y() < m_data.height);
1540e5c31af7Sopenharmony_ci
1541e5c31af7Sopenharmony_ci		startPos.y()++;
1542e5c31af7Sopenharmony_ci
1543e5c31af7Sopenharmony_ci		result->addGeometry(geometryData, triangles);
1544e5c31af7Sopenharmony_ci	}
1545e5c31af7Sopenharmony_ci	else
1546e5c31af7Sopenharmony_ci	{
1547e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "Not implemented");
1548e5c31af7Sopenharmony_ci	}
1549e5c31af7Sopenharmony_ci
1550e5c31af7Sopenharmony_ci	result->createAndBuild(vkd, device, cmdBuffer, allocator);
1551e5c31af7Sopenharmony_ci
1552e5c31af7Sopenharmony_ci	return result;
1553e5c31af7Sopenharmony_ci}
1554e5c31af7Sopenharmony_ci
1555e5c31af7Sopenharmony_civector<de::SharedPtr<BottomLevelAccelerationStructure> > RayTracingBuiltinLaunchTestInstance::initBottomAccelerationStructures (VkCommandBuffer	cmdBuffer)
1556e5c31af7Sopenharmony_ci{
1557e5c31af7Sopenharmony_ci	tcu::UVec2													startPos;
1558e5c31af7Sopenharmony_ci	vector<de::SharedPtr<BottomLevelAccelerationStructure> >	result;
1559e5c31af7Sopenharmony_ci
1560e5c31af7Sopenharmony_ci	for (size_t instanceNdx = 0; instanceNdx < m_data.instancesGroupCount; ++instanceNdx)
1561e5c31af7Sopenharmony_ci	{
1562e5c31af7Sopenharmony_ci		de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure	= initBottomAccelerationStructure(cmdBuffer, startPos);
1563e5c31af7Sopenharmony_ci
1564e5c31af7Sopenharmony_ci		result.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release()));
1565e5c31af7Sopenharmony_ci	}
1566e5c31af7Sopenharmony_ci
1567e5c31af7Sopenharmony_ci	return result;
1568e5c31af7Sopenharmony_ci}
1569e5c31af7Sopenharmony_ci
1570e5c31af7Sopenharmony_ciMove<VkPipeline> RayTracingBuiltinLaunchTestInstance::makePipeline (de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
1571e5c31af7Sopenharmony_ci																	VkPipelineLayout					pipelineLayout,
1572e5c31af7Sopenharmony_ci																	const VkSpecializationInfo*			specializationInfo)
1573e5c31af7Sopenharmony_ci{
1574e5c31af7Sopenharmony_ci	const DeviceInterface&	vkd			= m_context.getDeviceInterface();
1575e5c31af7Sopenharmony_ci	const VkDevice			device		= m_context.getDevice();
1576e5c31af7Sopenharmony_ci	vk::BinaryCollection&	collection	= m_context.getBinaryCollection();
1577e5c31af7Sopenharmony_ci
1578e5c31af7Sopenharmony_ci	if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))			rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR		, createShaderModule(vkd, device, collection.get("rgen"), 0), m_raygenShaderGroup, specializationInfo);
1579e5c31af7Sopenharmony_ci	if (0 != (m_shaders & VK_SHADER_STAGE_ANY_HIT_BIT_KHR))			rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR		, createShaderModule(vkd, device, collection.get("ahit"), 0), m_hitShaderGroup, specializationInfo);
1580e5c31af7Sopenharmony_ci	if (0 != (m_shaders & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR))		rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR	, createShaderModule(vkd, device, collection.get("chit"), 0), m_hitShaderGroup, specializationInfo);
1581e5c31af7Sopenharmony_ci	if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))			rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR			, createShaderModule(vkd, device, collection.get("miss"), 0), m_missShaderGroup, specializationInfo);
1582e5c31af7Sopenharmony_ci	if (0 != (m_shaders & VK_SHADER_STAGE_INTERSECTION_BIT_KHR))	rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR	, createShaderModule(vkd, device, collection.get("sect"), 0), m_hitShaderGroup, specializationInfo);
1583e5c31af7Sopenharmony_ci	if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))		rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR		, createShaderModule(vkd, device, collection.get("call"), 0), m_callableShaderGroup, specializationInfo);
1584e5c31af7Sopenharmony_ci
1585e5c31af7Sopenharmony_ci	if (m_data.pipelineCreateFlags != 0)
1586e5c31af7Sopenharmony_ci	{
1587e5c31af7Sopenharmony_ci		rayTracingPipeline->setCreateFlags(m_data.pipelineCreateFlags);
1588e5c31af7Sopenharmony_ci		if (m_data.useMaintenance5)
1589e5c31af7Sopenharmony_ci			rayTracingPipeline->setCreateFlags2(translateCreateFlag(m_data.pipelineCreateFlags));
1590e5c31af7Sopenharmony_ci	}
1591e5c31af7Sopenharmony_ci
1592e5c31af7Sopenharmony_ci	Move<VkPipeline> pipeline = rayTracingPipeline->createPipeline(vkd, device, pipelineLayout);
1593e5c31af7Sopenharmony_ci
1594e5c31af7Sopenharmony_ci	return pipeline;
1595e5c31af7Sopenharmony_ci}
1596e5c31af7Sopenharmony_ci
1597e5c31af7Sopenharmony_cide::MovePtr<BufferWithMemory> RayTracingBuiltinLaunchTestInstance::createShaderBindingTable (const InstanceInterface&			vki,
1598e5c31af7Sopenharmony_ci																							 const DeviceInterface&				vkd,
1599e5c31af7Sopenharmony_ci																							 const VkDevice						device,
1600e5c31af7Sopenharmony_ci																							 const VkPhysicalDevice				physicalDevice,
1601e5c31af7Sopenharmony_ci																							 const VkPipeline					pipeline,
1602e5c31af7Sopenharmony_ci																							 Allocator&							allocator,
1603e5c31af7Sopenharmony_ci																							 de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
1604e5c31af7Sopenharmony_ci																							 const deUint32						group)
1605e5c31af7Sopenharmony_ci{
1606e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	shaderBindingTable;
1607e5c31af7Sopenharmony_ci
1608e5c31af7Sopenharmony_ci	if (group < m_shaderGroupCount)
1609e5c31af7Sopenharmony_ci	{
1610e5c31af7Sopenharmony_ci		const deUint32	shaderGroupHandleSize		= getShaderGroupSize(vki, physicalDevice);
1611e5c31af7Sopenharmony_ci		const deUint32	shaderGroupBaseAlignment	= getShaderGroupBaseAlignment(vki, physicalDevice);
1612e5c31af7Sopenharmony_ci
1613e5c31af7Sopenharmony_ci		shaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, group, 1u);
1614e5c31af7Sopenharmony_ci	}
1615e5c31af7Sopenharmony_ci
1616e5c31af7Sopenharmony_ci	return shaderBindingTable;
1617e5c31af7Sopenharmony_ci}
1618e5c31af7Sopenharmony_ci
1619e5c31af7Sopenharmony_ci// Provides two spec constants, one integer and one float, both with value 256.
1620e5c31af7Sopenharmony_ciclass SpecConstantsHelper
1621e5c31af7Sopenharmony_ci{
1622e5c31af7Sopenharmony_cipublic:
1623e5c31af7Sopenharmony_ci								SpecConstantsHelper		();
1624e5c31af7Sopenharmony_ci	const VkSpecializationInfo&	getSpecializationInfo	(void) const;
1625e5c31af7Sopenharmony_ciprivate:
1626e5c31af7Sopenharmony_ci	std::vector<deUint8>					m_data;
1627e5c31af7Sopenharmony_ci	std::vector<VkSpecializationMapEntry>	m_mapEntries;
1628e5c31af7Sopenharmony_ci	VkSpecializationInfo					m_specInfo;
1629e5c31af7Sopenharmony_ci};
1630e5c31af7Sopenharmony_ci
1631e5c31af7Sopenharmony_ciSpecConstantsHelper::SpecConstantsHelper ()
1632e5c31af7Sopenharmony_ci	: m_data		()
1633e5c31af7Sopenharmony_ci	, m_mapEntries	()
1634e5c31af7Sopenharmony_ci{
1635e5c31af7Sopenharmony_ci	// To make things interesting, make both data unaligned and add some padding.
1636e5c31af7Sopenharmony_ci	const deInt32	value1	= 256;
1637e5c31af7Sopenharmony_ci	const float		value2	= 256.0f;
1638e5c31af7Sopenharmony_ci
1639e5c31af7Sopenharmony_ci	const size_t	offset1	= 1u;							// Offset of 1 byte.
1640e5c31af7Sopenharmony_ci	const size_t	offset2	= 1u + sizeof(value1) + 2u;		// Offset of 3 bytes plus the size of value1.
1641e5c31af7Sopenharmony_ci
1642e5c31af7Sopenharmony_ci	m_data.resize(sizeof(value1) + sizeof(value2) + 5u);	// Some extra padding at the end too.
1643e5c31af7Sopenharmony_ci	deMemcpy(&m_data[offset1], &value1, sizeof(value1));
1644e5c31af7Sopenharmony_ci	deMemcpy(&m_data[offset2], &value2, sizeof(value2));
1645e5c31af7Sopenharmony_ci
1646e5c31af7Sopenharmony_ci	// Map entries.
1647e5c31af7Sopenharmony_ci	m_mapEntries.reserve(2u);
1648e5c31af7Sopenharmony_ci	m_mapEntries.push_back({ 0u, static_cast<deUint32>(offset1), static_cast<deUintptr>(sizeof(value1)) });
1649e5c31af7Sopenharmony_ci	m_mapEntries.push_back({ 1u, static_cast<deUint32>(offset2), static_cast<deUintptr>(sizeof(value2))	});
1650e5c31af7Sopenharmony_ci
1651e5c31af7Sopenharmony_ci	// Specialization info.
1652e5c31af7Sopenharmony_ci	m_specInfo.mapEntryCount	= static_cast<deUint32>(m_mapEntries.size());
1653e5c31af7Sopenharmony_ci	m_specInfo.pMapEntries		= m_mapEntries.data();
1654e5c31af7Sopenharmony_ci	m_specInfo.dataSize			= static_cast<deUintptr>(m_data.size());
1655e5c31af7Sopenharmony_ci	m_specInfo.pData			= m_data.data();
1656e5c31af7Sopenharmony_ci}
1657e5c31af7Sopenharmony_ci
1658e5c31af7Sopenharmony_ciconst VkSpecializationInfo& SpecConstantsHelper::getSpecializationInfo (void) const
1659e5c31af7Sopenharmony_ci{
1660e5c31af7Sopenharmony_ci	return m_specInfo;
1661e5c31af7Sopenharmony_ci}
1662e5c31af7Sopenharmony_ci
1663e5c31af7Sopenharmony_cide::MovePtr<BufferWithMemory> RayTracingBuiltinLaunchTestInstance::runTest (void)
1664e5c31af7Sopenharmony_ci{
1665e5c31af7Sopenharmony_ci	const InstanceInterface&			vki									= m_context.getInstanceInterface();
1666e5c31af7Sopenharmony_ci	const DeviceInterface&				vkd									= m_context.getDeviceInterface();
1667e5c31af7Sopenharmony_ci	const VkDevice						device								= m_context.getDevice();
1668e5c31af7Sopenharmony_ci	const VkPhysicalDevice				physicalDevice						= m_context.getPhysicalDevice();
1669e5c31af7Sopenharmony_ci	const deUint32						queueFamilyIndex					= m_context.getUniversalQueueFamilyIndex();
1670e5c31af7Sopenharmony_ci	const VkQueue						queue								= m_context.getUniversalQueue();
1671e5c31af7Sopenharmony_ci	Allocator&							allocator							= m_context.getDefaultAllocator();
1672e5c31af7Sopenharmony_ci	const deUint32						shaderGroupHandleSize				= getShaderGroupSize(vki, physicalDevice);
1673e5c31af7Sopenharmony_ci	const VkFormat						format								= m_data.format;
1674e5c31af7Sopenharmony_ci	const deUint32						pixelSize							= tcu::getPixelSize(mapVkFormat(format));
1675e5c31af7Sopenharmony_ci	const deUint32						pixelCount							= m_data.width * m_data.height * m_data.depth;
1676e5c31af7Sopenharmony_ci
1677e5c31af7Sopenharmony_ci	const Move<VkDescriptorSetLayout>	descriptorSetLayout					= DescriptorSetLayoutBuilder()
1678e5c31af7Sopenharmony_ci																					.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
1679e5c31af7Sopenharmony_ci																					.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
1680e5c31af7Sopenharmony_ci																					.build(vkd, device);
1681e5c31af7Sopenharmony_ci	const Move<VkDescriptorPool>		descriptorPool						= DescriptorPoolBuilder()
1682e5c31af7Sopenharmony_ci																					.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1683e5c31af7Sopenharmony_ci																					.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
1684e5c31af7Sopenharmony_ci																					.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1685e5c31af7Sopenharmony_ci	const Move<VkDescriptorSet>			descriptorSet						= makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout);
1686e5c31af7Sopenharmony_ci	const Move<VkPipelineLayout>		pipelineLayout						= makePipelineLayout(vkd, device, descriptorSetLayout.get());
1687e5c31af7Sopenharmony_ci	const Move<VkCommandPool>			cmdPool								= createCommandPool(vkd, device, 0, queueFamilyIndex);
1688e5c31af7Sopenharmony_ci	const Move<VkCommandBuffer>			cmdBuffer							= allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1689e5c31af7Sopenharmony_ci
1690e5c31af7Sopenharmony_ci	de::MovePtr<RayTracingPipeline>		rayTracingPipeline					= de::newMovePtr<RayTracingPipeline>();
1691e5c31af7Sopenharmony_ci	const SpecConstantsHelper			specConstantHelper;
1692e5c31af7Sopenharmony_ci	const VkSpecializationInfo*			specializationInfo					= (m_data.useSpecConstants ? &specConstantHelper.getSpecializationInfo() : nullptr);
1693e5c31af7Sopenharmony_ci	const Move<VkPipeline>				pipeline							= makePipeline(rayTracingPipeline, *pipelineLayout, specializationInfo);
1694e5c31af7Sopenharmony_ci	const de::MovePtr<BufferWithMemory>	raygenShaderBindingTable			= createShaderBindingTable(vki, vkd, device, physicalDevice, *pipeline, allocator, rayTracingPipeline, m_raygenShaderGroup);
1695e5c31af7Sopenharmony_ci	const de::MovePtr<BufferWithMemory>	missShaderBindingTable				= createShaderBindingTable(vki, vkd, device, physicalDevice, *pipeline, allocator, rayTracingPipeline, m_missShaderGroup);
1696e5c31af7Sopenharmony_ci	const de::MovePtr<BufferWithMemory>	hitShaderBindingTable				= createShaderBindingTable(vki, vkd, device, physicalDevice, *pipeline, allocator, rayTracingPipeline, m_hitShaderGroup);
1697e5c31af7Sopenharmony_ci	const de::MovePtr<BufferWithMemory>	callableShaderBindingTable			= createShaderBindingTable(vki, vkd, device, physicalDevice, *pipeline, allocator, rayTracingPipeline, m_callableShaderGroup);
1698e5c31af7Sopenharmony_ci
1699e5c31af7Sopenharmony_ci	const VkStridedDeviceAddressRegionKHR	raygenShaderBindingTableRegion		= raygenShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1700e5c31af7Sopenharmony_ci	const VkStridedDeviceAddressRegionKHR	missShaderBindingTableRegion		= missShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1701e5c31af7Sopenharmony_ci	const VkStridedDeviceAddressRegionKHR	hitShaderBindingTableRegion			= hitShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1702e5c31af7Sopenharmony_ci	const VkStridedDeviceAddressRegionKHR	callableShaderBindingTableRegion	= callableShaderBindingTable.get() != NULL ? makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize) : makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
1703e5c31af7Sopenharmony_ci
1704e5c31af7Sopenharmony_ci	const VkImageCreateInfo				imageCreateInfo						= makeImageCreateInfo(m_data.width, m_data.height, m_data.depth, format);
1705e5c31af7Sopenharmony_ci	const VkImageSubresourceRange		imageSubresourceRange				= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0, 1u);
1706e5c31af7Sopenharmony_ci	const de::MovePtr<ImageWithMemory>	image								= de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
1707e5c31af7Sopenharmony_ci	const Move<VkImageView>				imageView							= makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, format, imageSubresourceRange);
1708e5c31af7Sopenharmony_ci
1709e5c31af7Sopenharmony_ci	const VkBufferCreateInfo			bufferCreateInfo					= makeBufferCreateInfo(pixelCount * pixelSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
1710e5c31af7Sopenharmony_ci	const VkImageSubresourceLayers		bufferImageSubresourceLayers		= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1711e5c31af7Sopenharmony_ci	const VkBufferImageCopy				bufferImageRegion					= makeBufferImageCopy(makeExtent3D(m_data.width, m_data.height, m_data.depth), bufferImageSubresourceLayers);
1712e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>		buffer								= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible));
1713e5c31af7Sopenharmony_ci
1714e5c31af7Sopenharmony_ci	const VkDescriptorImageInfo			descriptorImageInfo					= makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);
1715e5c31af7Sopenharmony_ci
1716e5c31af7Sopenharmony_ci	const VkImageMemoryBarrier			preImageBarrier						= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT,
1717e5c31af7Sopenharmony_ci																				VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1718e5c31af7Sopenharmony_ci																				**image, imageSubresourceRange);
1719e5c31af7Sopenharmony_ci	const VkImageMemoryBarrier			postImageBarrier					= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
1720e5c31af7Sopenharmony_ci																				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1721e5c31af7Sopenharmony_ci																				**image, imageSubresourceRange);
1722e5c31af7Sopenharmony_ci	const VkMemoryBarrier				postTraceMemoryBarrier				= makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
1723e5c31af7Sopenharmony_ci	const VkMemoryBarrier				postCopyMemoryBarrier				= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
1724e5c31af7Sopenharmony_ci	const VkClearValue					clearValue							= makeClearValueColorU32(DEFAULT_UINT_CLEAR_VALUE, DEFAULT_UINT_CLEAR_VALUE, DEFAULT_UINT_CLEAR_VALUE, 255u);
1725e5c31af7Sopenharmony_ci
1726e5c31af7Sopenharmony_ci	vector<de::SharedPtr<BottomLevelAccelerationStructure> >	bottomLevelAccelerationStructures;
1727e5c31af7Sopenharmony_ci	de::MovePtr<TopLevelAccelerationStructure>					topLevelAccelerationStructure;
1728e5c31af7Sopenharmony_ci
1729e5c31af7Sopenharmony_ci	beginCommandBuffer(vkd, *cmdBuffer, 0u);
1730e5c31af7Sopenharmony_ci	{
1731e5c31af7Sopenharmony_ci		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
1732e5c31af7Sopenharmony_ci		vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
1733e5c31af7Sopenharmony_ci		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);
1734e5c31af7Sopenharmony_ci
1735e5c31af7Sopenharmony_ci		bottomLevelAccelerationStructures	= initBottomAccelerationStructures(*cmdBuffer);
1736e5c31af7Sopenharmony_ci		topLevelAccelerationStructure		= initTopAccelerationStructure(*cmdBuffer, bottomLevelAccelerationStructures);
1737e5c31af7Sopenharmony_ci
1738e5c31af7Sopenharmony_ci		const TopLevelAccelerationStructure*			topLevelAccelerationStructurePtr		= topLevelAccelerationStructure.get();
1739e5c31af7Sopenharmony_ci		VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet	=
1740e5c31af7Sopenharmony_ci		{
1741e5c31af7Sopenharmony_ci			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
1742e5c31af7Sopenharmony_ci			DE_NULL,															//  const void*							pNext;
1743e5c31af7Sopenharmony_ci			1u,																	//  deUint32							accelerationStructureCount;
1744e5c31af7Sopenharmony_ci			topLevelAccelerationStructurePtr->getPtr(),							//  const VkAccelerationStructureKHR*	pAccelerationStructures;
1745e5c31af7Sopenharmony_ci		};
1746e5c31af7Sopenharmony_ci
1747e5c31af7Sopenharmony_ci		DescriptorSetUpdateBuilder()
1748e5c31af7Sopenharmony_ci			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
1749e5c31af7Sopenharmony_ci			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
1750e5c31af7Sopenharmony_ci			.update(vkd, device);
1751e5c31af7Sopenharmony_ci
1752e5c31af7Sopenharmony_ci		vkd.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet.get(), 0, DE_NULL);
1753e5c31af7Sopenharmony_ci
1754e5c31af7Sopenharmony_ci		vkd.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipeline);
1755e5c31af7Sopenharmony_ci
1756e5c31af7Sopenharmony_ci		cmdTraceRays(vkd,
1757e5c31af7Sopenharmony_ci			*cmdBuffer,
1758e5c31af7Sopenharmony_ci			&raygenShaderBindingTableRegion,
1759e5c31af7Sopenharmony_ci			&missShaderBindingTableRegion,
1760e5c31af7Sopenharmony_ci			&hitShaderBindingTableRegion,
1761e5c31af7Sopenharmony_ci			&callableShaderBindingTableRegion,
1762e5c31af7Sopenharmony_ci			m_data.width, m_data.height, m_data.raysDepth);
1763e5c31af7Sopenharmony_ci
1764e5c31af7Sopenharmony_ci		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTraceMemoryBarrier);
1765e5c31af7Sopenharmony_ci
1766e5c31af7Sopenharmony_ci		vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **buffer, 1u, &bufferImageRegion);
1767e5c31af7Sopenharmony_ci
1768e5c31af7Sopenharmony_ci		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
1769e5c31af7Sopenharmony_ci	}
1770e5c31af7Sopenharmony_ci	endCommandBuffer(vkd, *cmdBuffer);
1771e5c31af7Sopenharmony_ci
1772e5c31af7Sopenharmony_ci	submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());
1773e5c31af7Sopenharmony_ci
1774e5c31af7Sopenharmony_ci	invalidateMappedMemoryRange(vkd, device, buffer->getAllocation().getMemory(), buffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
1775e5c31af7Sopenharmony_ci
1776e5c31af7Sopenharmony_ci	return buffer;
1777e5c31af7Sopenharmony_ci}
1778e5c31af7Sopenharmony_ci
1779e5c31af7Sopenharmony_civoid checkFormatSupported(Context& context, VkFormat format, VkImageUsageFlags usage, const VkExtent3D& extent)
1780e5c31af7Sopenharmony_ci{
1781e5c31af7Sopenharmony_ci	VkResult					result;
1782e5c31af7Sopenharmony_ci	VkImageFormatProperties		properties;
1783e5c31af7Sopenharmony_ci
1784e5c31af7Sopenharmony_ci	result = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(), format, VK_IMAGE_TYPE_3D, VK_IMAGE_TILING_OPTIMAL, usage, 0, &properties);
1785e5c31af7Sopenharmony_ci
1786e5c31af7Sopenharmony_ci	if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
1787e5c31af7Sopenharmony_ci	{
1788e5c31af7Sopenharmony_ci		std::ostringstream msg;
1789e5c31af7Sopenharmony_ci
1790e5c31af7Sopenharmony_ci		msg << "Format " << format << " not supported for usage flags 0x" << std::hex << usage;
1791e5c31af7Sopenharmony_ci
1792e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, msg.str());
1793e5c31af7Sopenharmony_ci	}
1794e5c31af7Sopenharmony_ci
1795e5c31af7Sopenharmony_ci	if (properties.maxExtent.width < extent.width || properties.maxExtent.height < extent.height || properties.maxExtent.depth < extent.depth)
1796e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Image size is too large for this format");
1797e5c31af7Sopenharmony_ci
1798e5c31af7Sopenharmony_ci	VK_CHECK(result);
1799e5c31af7Sopenharmony_ci}
1800e5c31af7Sopenharmony_ci
1801e5c31af7Sopenharmony_civoid RayTracingBuiltinLaunchTestInstance::checkSupportInInstance (void) const
1802e5c31af7Sopenharmony_ci{
1803e5c31af7Sopenharmony_ci	const InstanceInterface&				vki						= m_context.getInstanceInterface();
1804e5c31af7Sopenharmony_ci	const VkPhysicalDevice					physicalDevice			= m_context.getPhysicalDevice();
1805e5c31af7Sopenharmony_ci	const vk::VkPhysicalDeviceProperties&	properties				= m_context.getDeviceProperties();
1806e5c31af7Sopenharmony_ci	const deUint32							requiredAllocations		= 8u
1807e5c31af7Sopenharmony_ci																	+ TopLevelAccelerationStructure::getRequiredAllocationCount()
1808e5c31af7Sopenharmony_ci																	+ m_data.instancesGroupCount * BottomLevelAccelerationStructure::getRequiredAllocationCount();
1809e5c31af7Sopenharmony_ci	const de::MovePtr<RayTracingProperties>	rayTracingProperties	= makeRayTracingProperties(vki, physicalDevice);
1810e5c31af7Sopenharmony_ci	const VkExtent3D						extent					= makeExtent3D(m_data.width, m_data.height, m_data.depth);
1811e5c31af7Sopenharmony_ci
1812e5c31af7Sopenharmony_ci	checkFormatSupported(m_context, m_data.format, VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, extent);
1813e5c31af7Sopenharmony_ci
1814e5c31af7Sopenharmony_ci	if (rayTracingProperties->getMaxPrimitiveCount() < 2 * m_data.squaresGroupCount)
1815e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Triangles required more than supported");
1816e5c31af7Sopenharmony_ci
1817e5c31af7Sopenharmony_ci	if (rayTracingProperties->getMaxGeometryCount() < m_data.geometriesGroupCount)
1818e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Geometries required more than supported");
1819e5c31af7Sopenharmony_ci
1820e5c31af7Sopenharmony_ci	if (rayTracingProperties->getMaxInstanceCount() < m_data.instancesGroupCount)
1821e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Instances required more than supported");
1822e5c31af7Sopenharmony_ci
1823e5c31af7Sopenharmony_ci	if (properties.limits.maxMemoryAllocationCount < requiredAllocations)
1824e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Test requires more allocations allowed");
1825e5c31af7Sopenharmony_ci}
1826e5c31af7Sopenharmony_ci
1827e5c31af7Sopenharmony_cistd::vector<deInt32> RayTracingBuiltinLaunchTestInstance::expectedIntValuesBuffer (void)
1828e5c31af7Sopenharmony_ci{
1829e5c31af7Sopenharmony_ci	deUint32				pos		= 0;
1830e5c31af7Sopenharmony_ci	std::vector<deInt32>	result;
1831e5c31af7Sopenharmony_ci
1832e5c31af7Sopenharmony_ci	result.reserve(m_data.depth * m_data.height * m_data.width);
1833e5c31af7Sopenharmony_ci
1834e5c31af7Sopenharmony_ci	if (m_data.id == TEST_ID_LAUNCH_ID_EXT)
1835e5c31af7Sopenharmony_ci	{
1836e5c31af7Sopenharmony_ci		for (deUint32 z = 0; z < m_data.depth; ++z)
1837e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
1838e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
1839e5c31af7Sopenharmony_ci			result.push_back(deInt32(x + 256 * (y + 256 * z)) + 1);
1840e5c31af7Sopenharmony_ci	}
1841e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_LAUNCH_SIZE_EXT)
1842e5c31af7Sopenharmony_ci	{
1843e5c31af7Sopenharmony_ci		const deUint32				expectedValue	= m_data.width + 256 * (m_data.height + 256 * m_data.depth);
1844e5c31af7Sopenharmony_ci		const std::vector<deInt32>	result2			(m_data.depth * m_data.height * m_data.width, deInt32(expectedValue) + 1);
1845e5c31af7Sopenharmony_ci
1846e5c31af7Sopenharmony_ci		result = result2;
1847e5c31af7Sopenharmony_ci	}
1848e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_GEOMETRY_INDEX_EXT)
1849e5c31af7Sopenharmony_ci	{
1850e5c31af7Sopenharmony_ci		for (deUint32 z = 0; z < m_data.depth; ++z)
1851e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
1852e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
1853e5c31af7Sopenharmony_ci			result.push_back(deInt32((pos++ / m_data.squaresGroupCount) % m_data.geometriesGroupCount));
1854e5c31af7Sopenharmony_ci	}
1855e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_PRIMITIVE_ID)
1856e5c31af7Sopenharmony_ci	{
1857e5c31af7Sopenharmony_ci		for (deUint32 z = 0; z < m_data.depth; ++z)
1858e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
1859e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
1860e5c31af7Sopenharmony_ci			result.push_back(deInt32(pos++ % m_data.squaresGroupCount));
1861e5c31af7Sopenharmony_ci	}
1862e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_INSTANCE_ID)
1863e5c31af7Sopenharmony_ci	{
1864e5c31af7Sopenharmony_ci		for (deUint32 z = 0; z < m_data.depth; ++z)
1865e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
1866e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
1867e5c31af7Sopenharmony_ci			result.push_back(deInt32(pos++ / (m_data.squaresGroupCount * m_data.geometriesGroupCount)));
1868e5c31af7Sopenharmony_ci	}
1869e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_INSTANCE_CUSTOM_INDEX_EXT)
1870e5c31af7Sopenharmony_ci	{
1871e5c31af7Sopenharmony_ci		for (deUint32 z = 0; z < m_data.depth; ++z)
1872e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
1873e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
1874e5c31af7Sopenharmony_ci			result.push_back(deInt32(2 * (pos++ / (m_data.squaresGroupCount * m_data.geometriesGroupCount))));
1875e5c31af7Sopenharmony_ci	}
1876e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_EXT)
1877e5c31af7Sopenharmony_ci	{
1878e5c31af7Sopenharmony_ci		DE_ASSERT(m_data.squaresGroupCount == (1<<RAY_FLAG_BIT_LAST_PER_TEST));
1879e5c31af7Sopenharmony_ci		DE_ASSERT(DEFAULT_UINT_CLEAR_VALUE != (1<<RAY_FLAG_BIT_LAST_PER_TEST));
1880e5c31af7Sopenharmony_ci
1881e5c31af7Sopenharmony_ci		for (deUint32 z = 0; z < m_data.depth; ++z)
1882e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
1883e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
1884e5c31af7Sopenharmony_ci		{
1885e5c31af7Sopenharmony_ci			const deUint32	n						= x + m_data.width * (y + m_data.height * z);
1886e5c31af7Sopenharmony_ci			const bool		rayOpaque				= (0 != (n & (1<<RAY_FLAG_BIT_OPAQUE_EXT                     )));
1887e5c31af7Sopenharmony_ci			const bool		rayNoOpaque				= (0 != (n & (1<<RAY_FLAG_BIT_NO_OPAQUE_EXT                  ))) && !rayOpaque;
1888e5c31af7Sopenharmony_ci			const bool		rayTerminateOnFirstHit	= (0 != (n & (1<<RAY_FLAG_BIT_TERMINATE_ON_FIRST_HIT_EXT     )));
1889e5c31af7Sopenharmony_ci			const bool		raySkipClosestHitShader	= (0 != (n & (1<<RAY_FLAG_BIT_SKIP_CLOSEST_HIT_SHADER_EXT    )));
1890e5c31af7Sopenharmony_ci			const bool		rayCullBack				= (0 != (n & (1<<RAY_FLAG_BIT_CULL_BACK_FACING_TRIANGLES_EXT )));
1891e5c31af7Sopenharmony_ci			const bool		rayCullFront			= (0 != (n & (1<<RAY_FLAG_BIT_CULL_FRONT_FACING_TRIANGLES_EXT))) && !rayCullBack;
1892e5c31af7Sopenharmony_ci			const bool		rayCullOpaque			= (0 != (n & (1<<RAY_FLAG_BIT_CULL_OPAQUE_EXT                ))) && !rayOpaque && !rayNoOpaque;
1893e5c31af7Sopenharmony_ci			const bool		rayCullNoOpaque			= (0 != (n & (1<<RAY_FLAG_BIT_CULL_NO_OPAQUE_EXT             ))) && !rayOpaque && !rayNoOpaque && !rayCullOpaque;
1894e5c31af7Sopenharmony_ci			const bool		raySkipTriangles		= m_data.rayFlagSkipTriangles;
1895e5c31af7Sopenharmony_ci			const bool		raySkipAABBs			= m_data.rayFlagSkipAABSs;
1896e5c31af7Sopenharmony_ci			const bool		pipelineSkipTriangles	= (m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR) != 0;
1897e5c31af7Sopenharmony_ci			const bool		pipelineSkipAABBs		= (m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR) != 0;
1898e5c31af7Sopenharmony_ci			const bool		cullingTest				= m_data.rayFlagSkipTriangles || m_data.rayFlagSkipAABSs || pipelineSkipTriangles || pipelineSkipAABBs;
1899e5c31af7Sopenharmony_ci			const bool		geometryFrontFace		= m_data.frontFace;
1900e5c31af7Sopenharmony_ci			const bool		geometryOpaque			= m_data.opaque;
1901e5c31af7Sopenharmony_ci			const bool		geometryTriangles		= (m_data.geomType == GEOM_TYPE_TRIANGLES) ? true : false;
1902e5c31af7Sopenharmony_ci			const bool		geometryAABBs			= (m_data.geomType == GEOM_TYPE_AABBS) ? true : false;
1903e5c31af7Sopenharmony_ci			deUint32		v						= 0
1904e5c31af7Sopenharmony_ci													| (rayOpaque                ? (1<<RAY_FLAG_BIT_OPAQUE_EXT                     ) : 0)
1905e5c31af7Sopenharmony_ci													| (rayNoOpaque              ? (1<<RAY_FLAG_BIT_NO_OPAQUE_EXT                  ) : 0)
1906e5c31af7Sopenharmony_ci													| (rayTerminateOnFirstHit   ? (1<<RAY_FLAG_BIT_TERMINATE_ON_FIRST_HIT_EXT     ) : 0)
1907e5c31af7Sopenharmony_ci													| (raySkipClosestHitShader  ? (1<<RAY_FLAG_BIT_SKIP_CLOSEST_HIT_SHADER_EXT    ) : 0)
1908e5c31af7Sopenharmony_ci													| (rayCullBack              ? (1<<RAY_FLAG_BIT_CULL_BACK_FACING_TRIANGLES_EXT ) : 0)
1909e5c31af7Sopenharmony_ci													| (rayCullFront             ? (1<<RAY_FLAG_BIT_CULL_FRONT_FACING_TRIANGLES_EXT) : 0)
1910e5c31af7Sopenharmony_ci													| (rayCullOpaque            ? (1<<RAY_FLAG_BIT_CULL_OPAQUE_EXT                ) : 0)
1911e5c31af7Sopenharmony_ci													| (rayCullNoOpaque          ? (1<<RAY_FLAG_BIT_CULL_NO_OPAQUE_EXT             ) : 0)
1912e5c31af7Sopenharmony_ci													| (raySkipTriangles         ? (1<<RAY_FLAG_BIT_SKIP_TRIANGLES_EXT             ) : 0)
1913e5c31af7Sopenharmony_ci													| (raySkipAABBs             ? (1<<RAY_FLAG_BIT_SKIP_AABB_EXT                  ) : 0);
1914e5c31af7Sopenharmony_ci
1915e5c31af7Sopenharmony_ci			if (m_data.stage == VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR && raySkipClosestHitShader)
1916e5c31af7Sopenharmony_ci				v = DEFAULT_UINT_CLEAR_VALUE;
1917e5c31af7Sopenharmony_ci
1918e5c31af7Sopenharmony_ci			if (m_data.stage == VK_SHADER_STAGE_ANY_HIT_BIT_KHR && (rayOpaque || (geometryOpaque && !rayOpaque && !rayNoOpaque)))
1919e5c31af7Sopenharmony_ci				v = DEFAULT_UINT_CLEAR_VALUE;
1920e5c31af7Sopenharmony_ci
1921e5c31af7Sopenharmony_ci			if (geometryOpaque)
1922e5c31af7Sopenharmony_ci			{
1923e5c31af7Sopenharmony_ci				if (rayCullOpaque)
1924e5c31af7Sopenharmony_ci					if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1925e5c31af7Sopenharmony_ci						v = DEFAULT_UINT_CLEAR_VALUE;
1926e5c31af7Sopenharmony_ci			}
1927e5c31af7Sopenharmony_ci			else
1928e5c31af7Sopenharmony_ci			{
1929e5c31af7Sopenharmony_ci				if (rayCullNoOpaque)
1930e5c31af7Sopenharmony_ci					if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1931e5c31af7Sopenharmony_ci						v = DEFAULT_UINT_CLEAR_VALUE;
1932e5c31af7Sopenharmony_ci			}
1933e5c31af7Sopenharmony_ci
1934e5c31af7Sopenharmony_ci			if (geometryTriangles)
1935e5c31af7Sopenharmony_ci			{
1936e5c31af7Sopenharmony_ci				if (geometryFrontFace)
1937e5c31af7Sopenharmony_ci				{
1938e5c31af7Sopenharmony_ci					if (rayCullFront)
1939e5c31af7Sopenharmony_ci						if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1940e5c31af7Sopenharmony_ci							v = DEFAULT_UINT_CLEAR_VALUE;
1941e5c31af7Sopenharmony_ci				}
1942e5c31af7Sopenharmony_ci				else
1943e5c31af7Sopenharmony_ci				{
1944e5c31af7Sopenharmony_ci					if (rayCullBack)
1945e5c31af7Sopenharmony_ci						if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1946e5c31af7Sopenharmony_ci							v = DEFAULT_UINT_CLEAR_VALUE;
1947e5c31af7Sopenharmony_ci				}
1948e5c31af7Sopenharmony_ci			}
1949e5c31af7Sopenharmony_ci
1950e5c31af7Sopenharmony_ci			if (cullingTest)
1951e5c31af7Sopenharmony_ci			{
1952e5c31af7Sopenharmony_ci				if (m_data.stage != VK_SHADER_STAGE_MISS_BIT_KHR)
1953e5c31af7Sopenharmony_ci				{
1954e5c31af7Sopenharmony_ci					if (geometryTriangles)
1955e5c31af7Sopenharmony_ci					{
1956e5c31af7Sopenharmony_ci						if (raySkipTriangles || pipelineSkipTriangles)
1957e5c31af7Sopenharmony_ci							v = DEFAULT_UINT_CLEAR_VALUE;
1958e5c31af7Sopenharmony_ci					}
1959e5c31af7Sopenharmony_ci
1960e5c31af7Sopenharmony_ci					if (geometryAABBs)
1961e5c31af7Sopenharmony_ci					{
1962e5c31af7Sopenharmony_ci						if (raySkipAABBs || pipelineSkipAABBs)
1963e5c31af7Sopenharmony_ci							v = DEFAULT_UINT_CLEAR_VALUE;
1964e5c31af7Sopenharmony_ci					}
1965e5c31af7Sopenharmony_ci				}
1966e5c31af7Sopenharmony_ci			}
1967e5c31af7Sopenharmony_ci
1968e5c31af7Sopenharmony_ci			result.push_back(deInt32(v));
1969e5c31af7Sopenharmony_ci		}
1970e5c31af7Sopenharmony_ci	}
1971e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_HIT_KIND_EXT)
1972e5c31af7Sopenharmony_ci	{
1973e5c31af7Sopenharmony_ci		for (deUint32 z = 0; z < m_data.depth; ++z)
1974e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
1975e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
1976e5c31af7Sopenharmony_ci		{
1977e5c31af7Sopenharmony_ci			const deUint32	n				= x + m_data.width * (y + m_data.height * z);
1978e5c31af7Sopenharmony_ci			const deUint32	geometryNdx		= n / m_data.squaresGroupCount;
1979e5c31af7Sopenharmony_ci			const deUint32	hitKind			= ((geometryNdx & 1) == 0) ? 0xFEu : 0xFFu;
1980e5c31af7Sopenharmony_ci			const bool		geometryOpaque	= ((geometryNdx & 2) == 0) ? true : false;
1981e5c31af7Sopenharmony_ci			deUint32		v				= (m_data.geomType == GEOM_TYPE_TRIANGLES) ? hitKind : 0x7Eu;
1982e5c31af7Sopenharmony_ci
1983e5c31af7Sopenharmony_ci			if (m_data.stage == VK_SHADER_STAGE_ANY_HIT_BIT_KHR && geometryOpaque)
1984e5c31af7Sopenharmony_ci				v = DEFAULT_UINT_CLEAR_VALUE;
1985e5c31af7Sopenharmony_ci
1986e5c31af7Sopenharmony_ci			result.push_back(deInt32(v));
1987e5c31af7Sopenharmony_ci		}
1988e5c31af7Sopenharmony_ci	}
1989e5c31af7Sopenharmony_ci	else
1990e5c31af7Sopenharmony_ci	{
1991e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "Not implemented");
1992e5c31af7Sopenharmony_ci	}
1993e5c31af7Sopenharmony_ci
1994e5c31af7Sopenharmony_ci	return result;
1995e5c31af7Sopenharmony_ci}
1996e5c31af7Sopenharmony_ci
1997e5c31af7Sopenharmony_cistd::vector<float> RayTracingBuiltinLaunchTestInstance::expectedFloatValuesBuffer (void)
1998e5c31af7Sopenharmony_ci{
1999e5c31af7Sopenharmony_ci	std::vector<float>	result;
2000e5c31af7Sopenharmony_ci
2001e5c31af7Sopenharmony_ci	result.reserve(m_data.depth * m_data.height * m_data.width);
2002e5c31af7Sopenharmony_ci
2003e5c31af7Sopenharmony_ci	if (m_data.id == TEST_ID_HIT_T_EXT)
2004e5c31af7Sopenharmony_ci	{
2005e5c31af7Sopenharmony_ci		for (deUint32 z = 0; z < m_data.depth; ++z)
2006e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2007e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2008e5c31af7Sopenharmony_ci		{
2009e5c31af7Sopenharmony_ci			const float	a	= float(x) / float(m_data.width);
2010e5c31af7Sopenharmony_ci			const float	b	= 1.0f + float(y) / float(m_data.height);
2011e5c31af7Sopenharmony_ci			const float	f	= 0.03125f + 0.25f * a / b;
2012e5c31af7Sopenharmony_ci
2013e5c31af7Sopenharmony_ci			result.push_back(f);
2014e5c31af7Sopenharmony_ci		}
2015e5c31af7Sopenharmony_ci	}
2016e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_RAY_T_MIN_EXT)
2017e5c31af7Sopenharmony_ci	{
2018e5c31af7Sopenharmony_ci		for (deUint32 z = 0; z < m_data.depth; ++z)
2019e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2020e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2021e5c31af7Sopenharmony_ci		{
2022e5c31af7Sopenharmony_ci			const float	a	= float(x) / float(m_data.width);
2023e5c31af7Sopenharmony_ci			const float	b	= 1.0f + float(y) / float(m_data.height);
2024e5c31af7Sopenharmony_ci			const float	f	= 0.25f * a / b;
2025e5c31af7Sopenharmony_ci
2026e5c31af7Sopenharmony_ci			result.push_back(f);
2027e5c31af7Sopenharmony_ci		}
2028e5c31af7Sopenharmony_ci	}
2029e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_RAY_T_MAX_EXT)
2030e5c31af7Sopenharmony_ci	{
2031e5c31af7Sopenharmony_ci		for (deUint32 z = 0; z < m_data.depth; ++z)
2032e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2033e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2034e5c31af7Sopenharmony_ci		{
2035e5c31af7Sopenharmony_ci			const float	a				= float(x) / float(m_data.width);
2036e5c31af7Sopenharmony_ci			const float	b				= 1.0f + float(y) / float(m_data.height);
2037e5c31af7Sopenharmony_ci			const float	c				= 0.25f * a / b;
2038e5c31af7Sopenharmony_ci			// In a miss shader, the value is identical to the parameter passed into traceRayEXT().
2039e5c31af7Sopenharmony_ci			const float	m				= 0.75f + c;
2040e5c31af7Sopenharmony_ci			// In the closest-hit shader, the value reflects the closest distance to the intersected primitive.
2041e5c31af7Sopenharmony_ci			// In the any-hit shader, it reflects the distance to the primitive currently being intersected.
2042e5c31af7Sopenharmony_ci			// In the intersection shader, it reflects the distance to the closest primitive intersected so far.
2043e5c31af7Sopenharmony_ci			const float	n				= 0.03125f + c;
2044e5c31af7Sopenharmony_ci			const bool	normalRow		= (y & 1) != 0;
2045e5c31af7Sopenharmony_ci			const bool	doublePrimitive	= (x & 1) != 0;
2046e5c31af7Sopenharmony_ci			const float	s				= normalRow ? m
2047e5c31af7Sopenharmony_ci										: doublePrimitive ? 0.4375f + c
2048e5c31af7Sopenharmony_ci										: float(DEFAULT_UINT_CLEAR_VALUE) / float(FIXED_POINT_DIVISOR);
2049e5c31af7Sopenharmony_ci			const float	f				= (m_data.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR) ? s
2050e5c31af7Sopenharmony_ci										: (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR) ? m
2051e5c31af7Sopenharmony_ci										: n;
2052e5c31af7Sopenharmony_ci
2053e5c31af7Sopenharmony_ci			result.push_back(f);
2054e5c31af7Sopenharmony_ci		}
2055e5c31af7Sopenharmony_ci	}
2056e5c31af7Sopenharmony_ci	else
2057e5c31af7Sopenharmony_ci	{
2058e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "Not implemented");
2059e5c31af7Sopenharmony_ci	}
2060e5c31af7Sopenharmony_ci
2061e5c31af7Sopenharmony_ci	return result;
2062e5c31af7Sopenharmony_ci}
2063e5c31af7Sopenharmony_ci
2064e5c31af7Sopenharmony_cistd::vector<float> RayTracingBuiltinLaunchTestInstance::expectedVectorValuesBuffer (void)
2065e5c31af7Sopenharmony_ci{
2066e5c31af7Sopenharmony_ci	const deUint32		imageDepth		= 4;
2067e5c31af7Sopenharmony_ci	const deUint32		expectedFloats	= imageDepth * m_data.height * m_data.width;
2068e5c31af7Sopenharmony_ci	std::vector<float>	result			(expectedFloats, float(DEFAULT_UINT_CLEAR_VALUE) / float(FIXED_POINT_DIVISOR));
2069e5c31af7Sopenharmony_ci
2070e5c31af7Sopenharmony_ci	if (m_data.id == TEST_ID_WORLD_RAY_ORIGIN_EXT)
2071e5c31af7Sopenharmony_ci	{
2072e5c31af7Sopenharmony_ci		deUint32	pos	= 0;
2073e5c31af7Sopenharmony_ci
2074e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2075e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2076e5c31af7Sopenharmony_ci			result[pos++] = (0.5f + float(x)) / float(m_data.width);
2077e5c31af7Sopenharmony_ci
2078e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2079e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2080e5c31af7Sopenharmony_ci			result[pos++] = (0.5f + float(y)) / float(m_data.height);
2081e5c31af7Sopenharmony_ci
2082e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2083e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2084e5c31af7Sopenharmony_ci			result[pos++] = 0.0f;
2085e5c31af7Sopenharmony_ci	}
2086e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_WORLD_RAY_DIRECTION_EXT)
2087e5c31af7Sopenharmony_ci	{
2088e5c31af7Sopenharmony_ci		deUint32	pos	= 0;
2089e5c31af7Sopenharmony_ci
2090e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2091e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2092e5c31af7Sopenharmony_ci			result[pos++] = 0.0f;
2093e5c31af7Sopenharmony_ci
2094e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2095e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2096e5c31af7Sopenharmony_ci			result[pos++] = 0.0f;
2097e5c31af7Sopenharmony_ci
2098e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2099e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2100e5c31af7Sopenharmony_ci			result[pos++] = -1.0f;
2101e5c31af7Sopenharmony_ci	}
2102e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_OBJECT_RAY_ORIGIN_EXT)
2103e5c31af7Sopenharmony_ci	{
2104e5c31af7Sopenharmony_ci		deUint32	pos	= 0;
2105e5c31af7Sopenharmony_ci
2106e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2107e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2108e5c31af7Sopenharmony_ci		{
2109e5c31af7Sopenharmony_ci			const deUint32	instanceId	= y / (m_data.height / m_data.instancesGroupCount);
2110e5c31af7Sopenharmony_ci			const float		offset		= (instanceId & 1) ? 1.0f / 8.0f : 0.0f;
2111e5c31af7Sopenharmony_ci
2112e5c31af7Sopenharmony_ci			result[pos++] = (0.5f + float(x) - offset) / float(m_data.width);
2113e5c31af7Sopenharmony_ci		}
2114e5c31af7Sopenharmony_ci
2115e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2116e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2117e5c31af7Sopenharmony_ci		{
2118e5c31af7Sopenharmony_ci			const deUint32	instanceId	= y / (m_data.height / m_data.instancesGroupCount);
2119e5c31af7Sopenharmony_ci			const float		offset		= (instanceId & 2) ? 1.0f / 16.0f : 0.0f;
2120e5c31af7Sopenharmony_ci
2121e5c31af7Sopenharmony_ci			result[pos++] = (0.5f + float(y) - offset) / float(m_data.height);
2122e5c31af7Sopenharmony_ci		}
2123e5c31af7Sopenharmony_ci
2124e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2125e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2126e5c31af7Sopenharmony_ci			result[pos++] = 0.0f;
2127e5c31af7Sopenharmony_ci	}
2128e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_OBJECT_RAY_DIRECTION_EXT)
2129e5c31af7Sopenharmony_ci	{
2130e5c31af7Sopenharmony_ci		deUint32	pos	= 0;
2131e5c31af7Sopenharmony_ci
2132e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2133e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2134e5c31af7Sopenharmony_ci			result[pos++] = 0.0f;
2135e5c31af7Sopenharmony_ci
2136e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2137e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2138e5c31af7Sopenharmony_ci			result[pos++] = 0.0f;
2139e5c31af7Sopenharmony_ci
2140e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2141e5c31af7Sopenharmony_ci		for (deUint32 x = 0; x < m_data.width; ++x)
2142e5c31af7Sopenharmony_ci			result[pos++] = -1.0f;
2143e5c31af7Sopenharmony_ci	}
2144e5c31af7Sopenharmony_ci	else
2145e5c31af7Sopenharmony_ci	{
2146e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "Not implemented");
2147e5c31af7Sopenharmony_ci	}
2148e5c31af7Sopenharmony_ci
2149e5c31af7Sopenharmony_ci	return result;
2150e5c31af7Sopenharmony_ci}
2151e5c31af7Sopenharmony_ci
2152e5c31af7Sopenharmony_cistd::vector<float> RayTracingBuiltinLaunchTestInstance::expectedMatrixValuesBuffer (void)
2153e5c31af7Sopenharmony_ci{
2154e5c31af7Sopenharmony_ci	const deUint32		colCount		= 4;
2155e5c31af7Sopenharmony_ci	const deUint32		rowCount		= 3;
2156e5c31af7Sopenharmony_ci	const deUint32		imageDepth		= 4 * 4;
2157e5c31af7Sopenharmony_ci	const deUint32		zStride			= m_data.height * m_data.width;
2158e5c31af7Sopenharmony_ci	const deUint32		expectedFloats	= imageDepth * m_data.height * m_data.width;
2159e5c31af7Sopenharmony_ci	std::vector<float>	result			(expectedFloats, float(DEFAULT_UINT_CLEAR_VALUE) / float(FIXED_POINT_DIVISOR));
2160e5c31af7Sopenharmony_ci
2161e5c31af7Sopenharmony_ci	if (m_data.id == TEST_ID_OBJECT_TO_WORLD_EXT ||
2162e5c31af7Sopenharmony_ci		m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT ||
2163e5c31af7Sopenharmony_ci		m_data.id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT ||
2164e5c31af7Sopenharmony_ci		m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT)
2165e5c31af7Sopenharmony_ci	{
2166e5c31af7Sopenharmony_ci		const int	translateColumnNumber	= 3;
2167e5c31af7Sopenharmony_ci		const float translateSign			= (m_data.id == TEST_ID_WORLD_TO_OBJECT_EXT || m_data.id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT) ? -1.0f : +1.0f;
2168e5c31af7Sopenharmony_ci		const float translateX				= translateSign * (1.0f / 8.0f) / float(m_data.width);
2169e5c31af7Sopenharmony_ci		const float translateY				= translateSign * (1.0f / 16.0f) / float(m_data.height);
2170e5c31af7Sopenharmony_ci
2171e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2172e5c31af7Sopenharmony_ci		{
2173e5c31af7Sopenharmony_ci			const deUint32	instanceId	= y / (m_data.height / m_data.instancesGroupCount);
2174e5c31af7Sopenharmony_ci
2175e5c31af7Sopenharmony_ci			for (deUint32 x = 0; x < m_data.width; ++x)
2176e5c31af7Sopenharmony_ci			{
2177e5c31af7Sopenharmony_ci				tcu::Matrix<float, rowCount, colCount>	m;
2178e5c31af7Sopenharmony_ci				const deUint32							elem0Pos	= x + m_data.width * y;
2179e5c31af7Sopenharmony_ci
2180e5c31af7Sopenharmony_ci				if (instanceId & 1)
2181e5c31af7Sopenharmony_ci					m[translateColumnNumber][0] = translateX;
2182e5c31af7Sopenharmony_ci
2183e5c31af7Sopenharmony_ci				if (instanceId & 2)
2184e5c31af7Sopenharmony_ci					m[translateColumnNumber][1] = translateY;
2185e5c31af7Sopenharmony_ci
2186e5c31af7Sopenharmony_ci				for (deUint32 rowNdx = 0; rowNdx < rowCount; ++rowNdx)
2187e5c31af7Sopenharmony_ci				for (deUint32 colNdx = 0; colNdx < colCount; ++colNdx)
2188e5c31af7Sopenharmony_ci				{
2189e5c31af7Sopenharmony_ci					const deUint32	z	= rowNdx * colCount + colNdx;
2190e5c31af7Sopenharmony_ci					const deUint32	pos	= elem0Pos + zStride * z;
2191e5c31af7Sopenharmony_ci
2192e5c31af7Sopenharmony_ci					result[pos] = m[colNdx][rowNdx];
2193e5c31af7Sopenharmony_ci				}
2194e5c31af7Sopenharmony_ci			}
2195e5c31af7Sopenharmony_ci		}
2196e5c31af7Sopenharmony_ci	}
2197e5c31af7Sopenharmony_ci	else
2198e5c31af7Sopenharmony_ci	{
2199e5c31af7Sopenharmony_ci		TCU_THROW(InternalError, "Not implemented");
2200e5c31af7Sopenharmony_ci	}
2201e5c31af7Sopenharmony_ci
2202e5c31af7Sopenharmony_ci	return result;
2203e5c31af7Sopenharmony_ci}
2204e5c31af7Sopenharmony_ci
2205e5c31af7Sopenharmony_cibool RayTracingBuiltinLaunchTestInstance::validateIntBuffer (de::MovePtr<BufferWithMemory> buffer)
2206e5c31af7Sopenharmony_ci{
2207e5c31af7Sopenharmony_ci	const deInt32*			bufferPtr		= (deInt32*)buffer->getAllocation().getHostPtr();
2208e5c31af7Sopenharmony_ci	const vector<deInt32>	expectedValues	= expectedIntValuesBuffer();
2209e5c31af7Sopenharmony_ci	tcu::TestLog&			log				= m_context.getTestContext().getLog();
2210e5c31af7Sopenharmony_ci	deUint32				failures		= 0;
2211e5c31af7Sopenharmony_ci	deUint32				pos				= 0;
2212e5c31af7Sopenharmony_ci
2213e5c31af7Sopenharmony_ci	for (deUint32 z = 0; z < m_data.depth; ++z)
2214e5c31af7Sopenharmony_ci	for (deUint32 y = 0; y < m_data.height; ++y)
2215e5c31af7Sopenharmony_ci	for (deUint32 x = 0; x < m_data.width; ++x)
2216e5c31af7Sopenharmony_ci	{
2217e5c31af7Sopenharmony_ci		if (bufferPtr[pos] != expectedValues[pos])
2218e5c31af7Sopenharmony_ci			failures++;
2219e5c31af7Sopenharmony_ci
2220e5c31af7Sopenharmony_ci		++pos;
2221e5c31af7Sopenharmony_ci	}
2222e5c31af7Sopenharmony_ci
2223e5c31af7Sopenharmony_ci	if (failures != 0)
2224e5c31af7Sopenharmony_ci	{
2225e5c31af7Sopenharmony_ci		const char * names[] = { "Retrieved:", "Expected:" };
2226e5c31af7Sopenharmony_ci		for (deUint32 n = 0; n < 2; ++n)
2227e5c31af7Sopenharmony_ci		{
2228e5c31af7Sopenharmony_ci			const deInt32*		loggedData = (n == 0) ? bufferPtr : expectedValues.data();
2229e5c31af7Sopenharmony_ci			std::stringstream	css;
2230e5c31af7Sopenharmony_ci
2231e5c31af7Sopenharmony_ci			pos = 0;
2232e5c31af7Sopenharmony_ci
2233e5c31af7Sopenharmony_ci			for (deUint32 z = 0; z < m_data.depth; ++z)
2234e5c31af7Sopenharmony_ci			for (deUint32 y = 0; y < m_data.height; ++y)
2235e5c31af7Sopenharmony_ci			{
2236e5c31af7Sopenharmony_ci				for (deUint32 x = 0; x < m_data.width; ++x)
2237e5c31af7Sopenharmony_ci				{
2238e5c31af7Sopenharmony_ci					if (bufferPtr[pos] == expectedValues[pos])
2239e5c31af7Sopenharmony_ci						css << "____,";
2240e5c31af7Sopenharmony_ci					else
2241e5c31af7Sopenharmony_ci						css << std::hex << std::setw(4) << loggedData[pos] << ",";
2242e5c31af7Sopenharmony_ci
2243e5c31af7Sopenharmony_ci					pos++;
2244e5c31af7Sopenharmony_ci				}
2245e5c31af7Sopenharmony_ci
2246e5c31af7Sopenharmony_ci				css << std::endl;
2247e5c31af7Sopenharmony_ci			}
2248e5c31af7Sopenharmony_ci
2249e5c31af7Sopenharmony_ci			log << tcu::TestLog::Message << names[n] << tcu::TestLog::EndMessage;
2250e5c31af7Sopenharmony_ci			log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
2251e5c31af7Sopenharmony_ci		}
2252e5c31af7Sopenharmony_ci	}
2253e5c31af7Sopenharmony_ci
2254e5c31af7Sopenharmony_ci	return failures == 0;
2255e5c31af7Sopenharmony_ci}
2256e5c31af7Sopenharmony_ci
2257e5c31af7Sopenharmony_cibool RayTracingBuiltinLaunchTestInstance::validateFloatBuffer (de::MovePtr<BufferWithMemory> buffer)
2258e5c31af7Sopenharmony_ci{
2259e5c31af7Sopenharmony_ci	const float			eps				= float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
2260e5c31af7Sopenharmony_ci	const deInt32*		bufferPtr		= (deInt32*)buffer->getAllocation().getHostPtr();
2261e5c31af7Sopenharmony_ci	const vector<float>	expectedValues	= expectedFloatValuesBuffer();
2262e5c31af7Sopenharmony_ci	tcu::TestLog&		log				= m_context.getTestContext().getLog();
2263e5c31af7Sopenharmony_ci	deUint32			failures		= 0;
2264e5c31af7Sopenharmony_ci	deUint32			pos				= 0;
2265e5c31af7Sopenharmony_ci
2266e5c31af7Sopenharmony_ci	for (deUint32 z = 0; z < m_data.depth; ++z)
2267e5c31af7Sopenharmony_ci	for (deUint32 y = 0; y < m_data.height; ++y)
2268e5c31af7Sopenharmony_ci	for (deUint32 x = 0; x < m_data.width; ++x)
2269e5c31af7Sopenharmony_ci	{
2270e5c31af7Sopenharmony_ci		const float retrievedValue	= float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2271e5c31af7Sopenharmony_ci
2272e5c31af7Sopenharmony_ci		if (deFloatAbs(retrievedValue - expectedValues[pos]) > eps)
2273e5c31af7Sopenharmony_ci			failures++;
2274e5c31af7Sopenharmony_ci
2275e5c31af7Sopenharmony_ci		++pos;
2276e5c31af7Sopenharmony_ci	}
2277e5c31af7Sopenharmony_ci
2278e5c31af7Sopenharmony_ci	if (failures != 0)
2279e5c31af7Sopenharmony_ci	{
2280e5c31af7Sopenharmony_ci		const char * names[] = { "Retrieved:", "Expected:" };
2281e5c31af7Sopenharmony_ci
2282e5c31af7Sopenharmony_ci		for (deUint32 n = 0; n < 2; ++n)
2283e5c31af7Sopenharmony_ci		{
2284e5c31af7Sopenharmony_ci			std::stringstream	css;
2285e5c31af7Sopenharmony_ci
2286e5c31af7Sopenharmony_ci			pos = 0;
2287e5c31af7Sopenharmony_ci
2288e5c31af7Sopenharmony_ci			for (deUint32 z = 0; z < m_data.depth; ++z)
2289e5c31af7Sopenharmony_ci			for (deUint32 y = 0; y < m_data.height; ++y)
2290e5c31af7Sopenharmony_ci			{
2291e5c31af7Sopenharmony_ci				for (deUint32 x = 0; x < m_data.width; ++x)
2292e5c31af7Sopenharmony_ci				{
2293e5c31af7Sopenharmony_ci					const float	retrievedValue	= float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2294e5c31af7Sopenharmony_ci					const float	expectedValue	= expectedValues[pos];
2295e5c31af7Sopenharmony_ci
2296e5c31af7Sopenharmony_ci					if (deFloatAbs(retrievedValue - expectedValue) > eps)
2297e5c31af7Sopenharmony_ci						css << std::setprecision(8) << std::setw(12) << (n == 0 ? retrievedValue : expectedValue) << ",";
2298e5c31af7Sopenharmony_ci					else
2299e5c31af7Sopenharmony_ci						css << "____________,";
2300e5c31af7Sopenharmony_ci
2301e5c31af7Sopenharmony_ci					pos++;
2302e5c31af7Sopenharmony_ci				}
2303e5c31af7Sopenharmony_ci
2304e5c31af7Sopenharmony_ci				css << std::endl;
2305e5c31af7Sopenharmony_ci			}
2306e5c31af7Sopenharmony_ci
2307e5c31af7Sopenharmony_ci			log << tcu::TestLog::Message << names[n] << tcu::TestLog::EndMessage;
2308e5c31af7Sopenharmony_ci			log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
2309e5c31af7Sopenharmony_ci		}
2310e5c31af7Sopenharmony_ci	}
2311e5c31af7Sopenharmony_ci
2312e5c31af7Sopenharmony_ci	return failures == 0;
2313e5c31af7Sopenharmony_ci}
2314e5c31af7Sopenharmony_ci
2315e5c31af7Sopenharmony_cibool RayTracingBuiltinLaunchTestInstance::validateVectorBuffer (de::MovePtr<BufferWithMemory> buffer)
2316e5c31af7Sopenharmony_ci{
2317e5c31af7Sopenharmony_ci	const float			eps				= float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
2318e5c31af7Sopenharmony_ci	const deInt32*		bufferPtr		= (deInt32*)buffer->getAllocation().getHostPtr();
2319e5c31af7Sopenharmony_ci	const vector<float>	expectedValues	= expectedVectorValuesBuffer();
2320e5c31af7Sopenharmony_ci	const deUint32		depth			= 3u; // vec3
2321e5c31af7Sopenharmony_ci	tcu::TestLog&		log				= m_context.getTestContext().getLog();
2322e5c31af7Sopenharmony_ci	deUint32			failures		= 0;
2323e5c31af7Sopenharmony_ci	deUint32			pos				= 0;
2324e5c31af7Sopenharmony_ci
2325e5c31af7Sopenharmony_ci	DE_ASSERT(depth <= m_data.depth);
2326e5c31af7Sopenharmony_ci
2327e5c31af7Sopenharmony_ci	for (deUint32 z = 0; z < depth; ++z)
2328e5c31af7Sopenharmony_ci	for (deUint32 y = 0; y < m_data.height; ++y)
2329e5c31af7Sopenharmony_ci	for (deUint32 x = 0; x < m_data.width; ++x)
2330e5c31af7Sopenharmony_ci	{
2331e5c31af7Sopenharmony_ci		const float retrievedValue	= float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2332e5c31af7Sopenharmony_ci
2333e5c31af7Sopenharmony_ci		if (deFloatAbs(retrievedValue - expectedValues[pos]) > eps)
2334e5c31af7Sopenharmony_ci			failures++;
2335e5c31af7Sopenharmony_ci
2336e5c31af7Sopenharmony_ci		++pos;
2337e5c31af7Sopenharmony_ci	}
2338e5c31af7Sopenharmony_ci
2339e5c31af7Sopenharmony_ci	if (failures != 0)
2340e5c31af7Sopenharmony_ci	{
2341e5c31af7Sopenharmony_ci		const char*			names[] = { "Retrieved", "Expected " };
2342e5c31af7Sopenharmony_ci		std::stringstream	css;
2343e5c31af7Sopenharmony_ci
2344e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2345e5c31af7Sopenharmony_ci		{
2346e5c31af7Sopenharmony_ci			for (deUint32 x = 0; x < m_data.width; ++x)
2347e5c31af7Sopenharmony_ci			{
2348e5c31af7Sopenharmony_ci				for (deUint32 n = 0; n < 2; ++n)
2349e5c31af7Sopenharmony_ci				{
2350e5c31af7Sopenharmony_ci					css << names[n] << " at (" << x << "," << y << ") {";
2351e5c31af7Sopenharmony_ci
2352e5c31af7Sopenharmony_ci					for (deUint32 z = 0; z < depth; ++z)
2353e5c31af7Sopenharmony_ci					{
2354e5c31af7Sopenharmony_ci						pos = x + m_data.width * (y + m_data.height * z);
2355e5c31af7Sopenharmony_ci
2356e5c31af7Sopenharmony_ci						const float	retrievedValue	= float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2357e5c31af7Sopenharmony_ci						const float	expectedValue	= expectedValues[pos];
2358e5c31af7Sopenharmony_ci
2359e5c31af7Sopenharmony_ci						if (deFloatAbs(retrievedValue - expectedValue) > eps)
2360e5c31af7Sopenharmony_ci							css << std::setprecision(8) << std::setw(12) << (n == 0 ? retrievedValue : expectedValue) << ",";
2361e5c31af7Sopenharmony_ci						else
2362e5c31af7Sopenharmony_ci							css << "____________,";
2363e5c31af7Sopenharmony_ci					}
2364e5c31af7Sopenharmony_ci
2365e5c31af7Sopenharmony_ci					css << "}" << std::endl;
2366e5c31af7Sopenharmony_ci				}
2367e5c31af7Sopenharmony_ci			}
2368e5c31af7Sopenharmony_ci		}
2369e5c31af7Sopenharmony_ci
2370e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
2371e5c31af7Sopenharmony_ci	}
2372e5c31af7Sopenharmony_ci
2373e5c31af7Sopenharmony_ci	return failures == 0;
2374e5c31af7Sopenharmony_ci}
2375e5c31af7Sopenharmony_ci
2376e5c31af7Sopenharmony_cibool RayTracingBuiltinLaunchTestInstance::validateMatrixBuffer (de::MovePtr<BufferWithMemory> buffer)
2377e5c31af7Sopenharmony_ci{
2378e5c31af7Sopenharmony_ci	const float			eps				= float(FIXED_POINT_ALLOWED_ERROR) / float(FIXED_POINT_DIVISOR);
2379e5c31af7Sopenharmony_ci	const deInt32*		bufferPtr		= (deInt32*)buffer->getAllocation().getHostPtr();
2380e5c31af7Sopenharmony_ci	const vector<float>	expectedValues	= expectedMatrixValuesBuffer();
2381e5c31af7Sopenharmony_ci	const deUint32		depth			= 12u; // mat3x4 or mat4x3
2382e5c31af7Sopenharmony_ci	tcu::TestLog&		log				= m_context.getTestContext().getLog();
2383e5c31af7Sopenharmony_ci	deUint32			failures		= 0;
2384e5c31af7Sopenharmony_ci	deUint32			pos				= 0;
2385e5c31af7Sopenharmony_ci
2386e5c31af7Sopenharmony_ci	DE_ASSERT(depth <= m_data.depth);
2387e5c31af7Sopenharmony_ci
2388e5c31af7Sopenharmony_ci	for (deUint32 z = 0; z < depth; ++z)
2389e5c31af7Sopenharmony_ci	for (deUint32 y = 0; y < m_data.height; ++y)
2390e5c31af7Sopenharmony_ci	for (deUint32 x = 0; x < m_data.width; ++x)
2391e5c31af7Sopenharmony_ci	{
2392e5c31af7Sopenharmony_ci		const float retrievedValue	= float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2393e5c31af7Sopenharmony_ci
2394e5c31af7Sopenharmony_ci		if (deFloatAbs(retrievedValue - expectedValues[pos]) > eps)
2395e5c31af7Sopenharmony_ci			failures++;
2396e5c31af7Sopenharmony_ci
2397e5c31af7Sopenharmony_ci		++pos;
2398e5c31af7Sopenharmony_ci	}
2399e5c31af7Sopenharmony_ci
2400e5c31af7Sopenharmony_ci	if (failures != 0)
2401e5c31af7Sopenharmony_ci	{
2402e5c31af7Sopenharmony_ci		const char*			names[] = { "Retrieved", "Expected" };
2403e5c31af7Sopenharmony_ci		std::stringstream	css;
2404e5c31af7Sopenharmony_ci
2405e5c31af7Sopenharmony_ci		for (deUint32 y = 0; y < m_data.height; ++y)
2406e5c31af7Sopenharmony_ci		{
2407e5c31af7Sopenharmony_ci			for (deUint32 x = 0; x < m_data.width; ++x)
2408e5c31af7Sopenharmony_ci			{
2409e5c31af7Sopenharmony_ci				css << "At (" << x << "," << y << ")" << std::endl;
2410e5c31af7Sopenharmony_ci				for (deUint32 n = 0; n < 2; ++n)
2411e5c31af7Sopenharmony_ci				{
2412e5c31af7Sopenharmony_ci					css << names[n] << std::endl << "{" << std::endl;
2413e5c31af7Sopenharmony_ci
2414e5c31af7Sopenharmony_ci					for (deUint32 z = 0; z < depth; ++z)
2415e5c31af7Sopenharmony_ci					{
2416e5c31af7Sopenharmony_ci						pos = x + m_data.width * (y + m_data.height * z);
2417e5c31af7Sopenharmony_ci
2418e5c31af7Sopenharmony_ci						const float	retrievedValue	= float(bufferPtr[pos]) / float(FIXED_POINT_DIVISOR);
2419e5c31af7Sopenharmony_ci						const float	expectedValue	= expectedValues[pos];
2420e5c31af7Sopenharmony_ci
2421e5c31af7Sopenharmony_ci						if (z % 4 == 0)
2422e5c31af7Sopenharmony_ci							css << "    {";
2423e5c31af7Sopenharmony_ci
2424e5c31af7Sopenharmony_ci						if (deFloatAbs(retrievedValue - expectedValue) > eps)
2425e5c31af7Sopenharmony_ci							css << std::setprecision(5) << std::setw(9) << (n == 0 ? retrievedValue : expectedValue) << ",";
2426e5c31af7Sopenharmony_ci						else
2427e5c31af7Sopenharmony_ci							css << "_________,";
2428e5c31af7Sopenharmony_ci
2429e5c31af7Sopenharmony_ci						if (z % 4 == 3)
2430e5c31af7Sopenharmony_ci							css << "}" << std::endl;
2431e5c31af7Sopenharmony_ci					}
2432e5c31af7Sopenharmony_ci
2433e5c31af7Sopenharmony_ci					css << "}" << std::endl;
2434e5c31af7Sopenharmony_ci				}
2435e5c31af7Sopenharmony_ci			}
2436e5c31af7Sopenharmony_ci		}
2437e5c31af7Sopenharmony_ci
2438e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
2439e5c31af7Sopenharmony_ci	}
2440e5c31af7Sopenharmony_ci
2441e5c31af7Sopenharmony_ci	return failures == 0;
2442e5c31af7Sopenharmony_ci}
2443e5c31af7Sopenharmony_ci
2444e5c31af7Sopenharmony_citcu::TestStatus RayTracingBuiltinLaunchTestInstance::iterate (void)
2445e5c31af7Sopenharmony_ci{
2446e5c31af7Sopenharmony_ci	checkSupportInInstance();
2447e5c31af7Sopenharmony_ci
2448e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>	buffer	= runTest();
2449e5c31af7Sopenharmony_ci	const bool						ok		= m_data.fixedPointMatrixOutput ? validateMatrixBuffer(buffer)
2450e5c31af7Sopenharmony_ci											: m_data.fixedPointVectorOutput ? validateVectorBuffer(buffer)
2451e5c31af7Sopenharmony_ci											: m_data.fixedPointScalarOutput ? validateFloatBuffer(buffer)
2452e5c31af7Sopenharmony_ci											: validateIntBuffer(buffer);
2453e5c31af7Sopenharmony_ci
2454e5c31af7Sopenharmony_ci	if (ok)
2455e5c31af7Sopenharmony_ci		return tcu::TestStatus::pass("pass");
2456e5c31af7Sopenharmony_ci	else
2457e5c31af7Sopenharmony_ci		return tcu::TestStatus::fail("fail");
2458e5c31af7Sopenharmony_ci}
2459e5c31af7Sopenharmony_ci
2460e5c31af7Sopenharmony_cienum ShaderSourceFlag
2461e5c31af7Sopenharmony_ci{
2462e5c31af7Sopenharmony_ci	DEFINE_RAY = 0x1,
2463e5c31af7Sopenharmony_ci	DEFINE_RESULT_BUFFER = 0x2,
2464e5c31af7Sopenharmony_ci	DEFINE_SCENE = 0x4,
2465e5c31af7Sopenharmony_ci	DEFINE_RAY_BUFFER = 0x8,
2466e5c31af7Sopenharmony_ci	DEFINE_SIMPLE_BINDINGS = DEFINE_RESULT_BUFFER | DEFINE_SCENE | DEFINE_RAY_BUFFER
2467e5c31af7Sopenharmony_ci};
2468e5c31af7Sopenharmony_ci
2469e5c31af7Sopenharmony_cistd::string generateShaderSource(const char* body, const char* resultType = "", deUint32 flags = 0, const char* prefix = "")
2470e5c31af7Sopenharmony_ci{
2471e5c31af7Sopenharmony_ci	std::ostringstream src;
2472e5c31af7Sopenharmony_ci	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n";
2473e5c31af7Sopenharmony_ci
2474e5c31af7Sopenharmony_ci	src << "#extension GL_EXT_ray_tracing : enable\n";
2475e5c31af7Sopenharmony_ci
2476e5c31af7Sopenharmony_ci	src << prefix << "\n";
2477e5c31af7Sopenharmony_ci
2478e5c31af7Sopenharmony_ci	if (flags & DEFINE_SIMPLE_BINDINGS)
2479e5c31af7Sopenharmony_ci		flags |= DEFINE_RAY_BUFFER;
2480e5c31af7Sopenharmony_ci
2481e5c31af7Sopenharmony_ci	if (flags & DEFINE_RAY_BUFFER)
2482e5c31af7Sopenharmony_ci		flags |= DEFINE_RAY;
2483e5c31af7Sopenharmony_ci
2484e5c31af7Sopenharmony_ci	if (flags & DEFINE_RAY)
2485e5c31af7Sopenharmony_ci	{
2486e5c31af7Sopenharmony_ci		src << "struct Ray { vec3 pos; float tmin; vec3 dir; float tmax; };\n";
2487e5c31af7Sopenharmony_ci	}
2488e5c31af7Sopenharmony_ci
2489e5c31af7Sopenharmony_ci	if (flags & DEFINE_RESULT_BUFFER)
2490e5c31af7Sopenharmony_ci		src << "layout(std430, set = 0, binding = " << 0 << ") buffer Results { " << resultType << " results[]; };\n";
2491e5c31af7Sopenharmony_ci
2492e5c31af7Sopenharmony_ci	if (flags & DEFINE_SCENE)
2493e5c31af7Sopenharmony_ci	{
2494e5c31af7Sopenharmony_ci		src << "layout(set = 0, binding = " << 1 << ") uniform accelerationStructureEXT scene;\n";
2495e5c31af7Sopenharmony_ci	}
2496e5c31af7Sopenharmony_ci
2497e5c31af7Sopenharmony_ci	if (flags & DEFINE_RAY_BUFFER)
2498e5c31af7Sopenharmony_ci		src << "layout(std430, set = 0, binding = " << 2 << ") buffer Rays { Ray rays[]; };\n";
2499e5c31af7Sopenharmony_ci
2500e5c31af7Sopenharmony_ci	src << "uint launchIndex() { return gl_LaunchIDEXT.z*gl_LaunchSizeEXT.x*gl_LaunchSizeEXT.y + gl_LaunchIDEXT.y*gl_LaunchSizeEXT.x + gl_LaunchIDEXT.x; }\n";
2501e5c31af7Sopenharmony_ci
2502e5c31af7Sopenharmony_ci	src << body;
2503e5c31af7Sopenharmony_ci
2504e5c31af7Sopenharmony_ci	return src.str();
2505e5c31af7Sopenharmony_ci}
2506e5c31af7Sopenharmony_ci
2507e5c31af7Sopenharmony_cistd::string getShaderIdentifier(const CaseDef& params, VkShaderStageFlagBits stage)
2508e5c31af7Sopenharmony_ci{
2509e5c31af7Sopenharmony_ci	std::string testStage;
2510e5c31af7Sopenharmony_ci
2511e5c31af7Sopenharmony_ci	switch (params.stage)
2512e5c31af7Sopenharmony_ci	{
2513e5c31af7Sopenharmony_ci	case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2514e5c31af7Sopenharmony_ci		testStage = "raygen";
2515e5c31af7Sopenharmony_ci		break;
2516e5c31af7Sopenharmony_ci	case VK_SHADER_STAGE_MISS_BIT_KHR:
2517e5c31af7Sopenharmony_ci		testStage = "-miss";
2518e5c31af7Sopenharmony_ci		break;
2519e5c31af7Sopenharmony_ci	case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2520e5c31af7Sopenharmony_ci		testStage = "-closest-hit";
2521e5c31af7Sopenharmony_ci		break;
2522e5c31af7Sopenharmony_ci	case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2523e5c31af7Sopenharmony_ci		testStage = "-any_hit";
2524e5c31af7Sopenharmony_ci		break;
2525e5c31af7Sopenharmony_ci	case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2526e5c31af7Sopenharmony_ci		testStage = "-closest_hit";
2527e5c31af7Sopenharmony_ci		break;
2528e5c31af7Sopenharmony_ci	case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2529e5c31af7Sopenharmony_ci		testStage = "-callable";
2530e5c31af7Sopenharmony_ci		break;
2531e5c31af7Sopenharmony_ci	default:
2532e5c31af7Sopenharmony_ci		DE_ASSERT(false);
2533e5c31af7Sopenharmony_ci		return std::string();
2534e5c31af7Sopenharmony_ci	}
2535e5c31af7Sopenharmony_ci
2536e5c31af7Sopenharmony_ci	switch (stage)
2537e5c31af7Sopenharmony_ci	{
2538e5c31af7Sopenharmony_ci	case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
2539e5c31af7Sopenharmony_ci		return testStage + "-rgen";
2540e5c31af7Sopenharmony_ci	case VK_SHADER_STAGE_MISS_BIT_KHR:
2541e5c31af7Sopenharmony_ci		return testStage + "-miss";
2542e5c31af7Sopenharmony_ci	case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
2543e5c31af7Sopenharmony_ci		return testStage + "-closest_hit";
2544e5c31af7Sopenharmony_ci	case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
2545e5c31af7Sopenharmony_ci		return testStage + "-any_hit";
2546e5c31af7Sopenharmony_ci	case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
2547e5c31af7Sopenharmony_ci		return testStage + "-isect";
2548e5c31af7Sopenharmony_ci	case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
2549e5c31af7Sopenharmony_ci		return testStage + "-callable";
2550e5c31af7Sopenharmony_ci	default:
2551e5c31af7Sopenharmony_ci		DE_ASSERT(false);
2552e5c31af7Sopenharmony_ci		return std::string();
2553e5c31af7Sopenharmony_ci	}
2554e5c31af7Sopenharmony_ci}
2555e5c31af7Sopenharmony_ci
2556e5c31af7Sopenharmony_cistd::string replaceString(std::string text, const std::string& search, const std::string& replace)
2557e5c31af7Sopenharmony_ci{
2558e5c31af7Sopenharmony_ci	size_t found;
2559e5c31af7Sopenharmony_ci
2560e5c31af7Sopenharmony_ci	while ((found = text.find(search)) != std::string::npos)
2561e5c31af7Sopenharmony_ci	{
2562e5c31af7Sopenharmony_ci		text = text.replace(found, search.length(), replace);
2563e5c31af7Sopenharmony_ci	}
2564e5c31af7Sopenharmony_ci
2565e5c31af7Sopenharmony_ci	return text;
2566e5c31af7Sopenharmony_ci}
2567e5c31af7Sopenharmony_ci
2568e5c31af7Sopenharmony_citemplate<typename T> inline void addBuiltInShaderSource(SourceCollections& programCollection,
2569e5c31af7Sopenharmony_ci														VkShaderStageFlagBits stage,
2570e5c31af7Sopenharmony_ci														const std::string& body,
2571e5c31af7Sopenharmony_ci														const CaseDef& params,
2572e5c31af7Sopenharmony_ci														std::string builtInType)
2573e5c31af7Sopenharmony_ci{
2574e5c31af7Sopenharmony_ci	std::string identifier = getShaderIdentifier(params, stage);
2575e5c31af7Sopenharmony_ci
2576e5c31af7Sopenharmony_ci	deUint32 flags = 0;
2577e5c31af7Sopenharmony_ci
2578e5c31af7Sopenharmony_ci	if (stage == VK_SHADER_STAGE_RAYGEN_BIT_KHR)
2579e5c31af7Sopenharmony_ci		flags |= DEFINE_RAY | DEFINE_SIMPLE_BINDINGS;
2580e5c31af7Sopenharmony_ci
2581e5c31af7Sopenharmony_ci	std::string text = generateShaderSource(body.c_str(), builtInType.c_str(), flags, "");
2582e5c31af7Sopenharmony_ci
2583e5c31af7Sopenharmony_ci	text = replaceString(text, "$builtInType$", builtInType);
2584e5c31af7Sopenharmony_ci
2585e5c31af7Sopenharmony_ci	const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0, true);
2586e5c31af7Sopenharmony_ci	programCollection.glslSources.add(identifier) << T(text) << buildOptions;
2587e5c31af7Sopenharmony_ci}
2588e5c31af7Sopenharmony_ci
2589e5c31af7Sopenharmony_ciclass RayTracingIndirectTestInstance : public TestInstance
2590e5c31af7Sopenharmony_ci{
2591e5c31af7Sopenharmony_cipublic:
2592e5c31af7Sopenharmony_ci																RayTracingIndirectTestInstance			(Context& context, const CaseDef& data);
2593e5c31af7Sopenharmony_ci																~RayTracingIndirectTestInstance			(void);
2594e5c31af7Sopenharmony_ci	tcu::TestStatus												iterate									(void);
2595e5c31af7Sopenharmony_ci
2596e5c31af7Sopenharmony_ciprivate:
2597e5c31af7Sopenharmony_ci	void														checkSupportInInstance					(void) const;
2598e5c31af7Sopenharmony_ci	Move<VkPipeline>											createPipelineAndShaderBindingTables	(de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
2599e5c31af7Sopenharmony_ci																										 bool aabb,
2600e5c31af7Sopenharmony_ci																										VkPipelineLayout pipelineLayout);
2601e5c31af7Sopenharmony_ci
2602e5c31af7Sopenharmony_ci	void														createPipelineLayoutAndSet				(deUint32 setCount,
2603e5c31af7Sopenharmony_ci																										vk::Move<VkDescriptorPool>& descriptorPool,
2604e5c31af7Sopenharmony_ci																										vk::Move<VkDescriptorSetLayout>& descriptorSetLayout,
2605e5c31af7Sopenharmony_ci																										std::vector<vk::Move<VkDescriptorSet>>& descriptorSets,
2606e5c31af7Sopenharmony_ci																										vk::Move<VkPipelineLayout>& pipelineLayout);
2607e5c31af7Sopenharmony_ci
2608e5c31af7Sopenharmony_ci	de::SharedPtr<TopLevelAccelerationStructure>				initTopAccelerationStructure			(std::vector<de::SharedPtr<BottomLevelAccelerationStructure> >&	bottomLevelAccelerationStructures);
2609e5c31af7Sopenharmony_ci	vector<de::SharedPtr<BottomLevelAccelerationStructure>>		initBottomAccelerationStructures		(void);
2610e5c31af7Sopenharmony_ci	void														initializeParameters					(void);
2611e5c31af7Sopenharmony_ci	bool														verifyResults							(void);
2612e5c31af7Sopenharmony_ci
2613e5c31af7Sopenharmony_ciprivate:
2614e5c31af7Sopenharmony_ci	CaseDef														m_data;
2615e5c31af7Sopenharmony_ci	std::vector<std::vector<tcu::Vec3>>							m_geomData;
2616e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>								m_resultBuffer;
2617e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>								m_rayBuffer;
2618e5c31af7Sopenharmony_ci	deUint32													m_numGeoms;
2619e5c31af7Sopenharmony_ci	deUint32													m_primsPerGeometry;
2620e5c31af7Sopenharmony_ci	deUint32													m_geomsPerInstance;
2621e5c31af7Sopenharmony_ci
2622e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>								m_raygenShaderBindingTable;
2623e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>								m_missShaderBindingTable;
2624e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory>								m_hitShaderBindingTable;
2625e5c31af7Sopenharmony_ci
2626e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR								m_raygenShaderBindingTableRegion;
2627e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR								m_missShaderBindingTableRegion;
2628e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR								m_hitShaderBindingTableRegion;
2629e5c31af7Sopenharmony_ci	VkStridedDeviceAddressRegionKHR								m_callableShaderBindingTableRegion;
2630e5c31af7Sopenharmony_ci};
2631e5c31af7Sopenharmony_ci
2632e5c31af7Sopenharmony_ciRayTracingIndirectTestInstance::RayTracingIndirectTestInstance (Context& context, const CaseDef& data)
2633e5c31af7Sopenharmony_ci	: vkt::TestInstance		(context)
2634e5c31af7Sopenharmony_ci	, m_data				(data)
2635e5c31af7Sopenharmony_ci	, m_numGeoms			(0)
2636e5c31af7Sopenharmony_ci	, m_primsPerGeometry	(0)
2637e5c31af7Sopenharmony_ci	, m_geomsPerInstance	(0)
2638e5c31af7Sopenharmony_ci{
2639e5c31af7Sopenharmony_ci}
2640e5c31af7Sopenharmony_ci
2641e5c31af7Sopenharmony_ciRayTracingIndirectTestInstance::~RayTracingIndirectTestInstance(void)
2642e5c31af7Sopenharmony_ci{
2643e5c31af7Sopenharmony_ci}
2644e5c31af7Sopenharmony_ci
2645e5c31af7Sopenharmony_ciclass RayTracingIndirectTestCase : public TestCase
2646e5c31af7Sopenharmony_ci{
2647e5c31af7Sopenharmony_ci	public:
2648e5c31af7Sopenharmony_ci										RayTracingIndirectTestCase			(tcu::TestContext& context, const char* name, const CaseDef data);
2649e5c31af7Sopenharmony_ci										~RayTracingIndirectTestCase			(void);
2650e5c31af7Sopenharmony_ci
2651e5c31af7Sopenharmony_ci	virtual	void						initPrograms				(SourceCollections& programCollection) const;
2652e5c31af7Sopenharmony_ci	virtual TestInstance*				createInstance				(Context& context) const;
2653e5c31af7Sopenharmony_ci	virtual void						checkSupport				(Context& context) const;
2654e5c31af7Sopenharmony_ci
2655e5c31af7Sopenharmony_ciprivate:
2656e5c31af7Sopenharmony_ci	static inline const std::string		getIntersectionPassthrough	(void);
2657e5c31af7Sopenharmony_ci	static inline const std::string		getMissPassthrough			(void);
2658e5c31af7Sopenharmony_ci	static inline const std::string		getHitPassthrough			(void);
2659e5c31af7Sopenharmony_ci
2660e5c31af7Sopenharmony_ci	CaseDef								m_data;
2661e5c31af7Sopenharmony_ci};
2662e5c31af7Sopenharmony_ci
2663e5c31af7Sopenharmony_ciRayTracingIndirectTestCase::RayTracingIndirectTestCase (tcu::TestContext& context, const char* name, const CaseDef data)
2664e5c31af7Sopenharmony_ci	: vkt::TestCase	(context, name)
2665e5c31af7Sopenharmony_ci	, m_data		(data)
2666e5c31af7Sopenharmony_ci{
2667e5c31af7Sopenharmony_ci}
2668e5c31af7Sopenharmony_ci
2669e5c31af7Sopenharmony_ciRayTracingIndirectTestCase::~RayTracingIndirectTestCase	(void)
2670e5c31af7Sopenharmony_ci{
2671e5c31af7Sopenharmony_ci}
2672e5c31af7Sopenharmony_ci
2673e5c31af7Sopenharmony_civoid RayTracingIndirectTestCase::checkSupport(Context& context) const
2674e5c31af7Sopenharmony_ci{
2675e5c31af7Sopenharmony_ci	const bool	pipelineFlagSkipTriangles	= ((m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR) != 0);
2676e5c31af7Sopenharmony_ci	const bool	pipelineFlagSkipAABSs		= ((m_data.pipelineCreateFlags & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR) != 0);
2677e5c31af7Sopenharmony_ci	const bool	cullingFlags				=  m_data.rayFlagSkipTriangles
2678e5c31af7Sopenharmony_ci											|| m_data.rayFlagSkipAABSs
2679e5c31af7Sopenharmony_ci											|| pipelineFlagSkipTriangles
2680e5c31af7Sopenharmony_ci											|| pipelineFlagSkipAABSs;
2681e5c31af7Sopenharmony_ci
2682e5c31af7Sopenharmony_ci	context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
2683e5c31af7Sopenharmony_ci	context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
2684e5c31af7Sopenharmony_ci
2685e5c31af7Sopenharmony_ci	const VkPhysicalDeviceRayTracingPipelineFeaturesKHR&	rayTracingPipelineFeaturesKHR		= context.getRayTracingPipelineFeatures();
2686e5c31af7Sopenharmony_ci	if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE )
2687e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
2688e5c31af7Sopenharmony_ci
2689e5c31af7Sopenharmony_ci	const VkPhysicalDeviceAccelerationStructureFeaturesKHR&	accelerationStructureFeaturesKHR	= context.getAccelerationStructureFeatures();
2690e5c31af7Sopenharmony_ci	if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
2691e5c31af7Sopenharmony_ci		TCU_THROW(TestError, "VK_KHR_ray_tracing_pipeline requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");
2692e5c31af7Sopenharmony_ci
2693e5c31af7Sopenharmony_ci	if (cullingFlags && rayTracingPipelineFeaturesKHR.rayTraversalPrimitiveCulling == DE_FALSE)
2694e5c31af7Sopenharmony_ci		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTraversalPrimitiveCulling");
2695e5c31af7Sopenharmony_ci}
2696e5c31af7Sopenharmony_ci
2697e5c31af7Sopenharmony_civoid RayTracingIndirectTestCase::initPrograms (SourceCollections& programCollection) const
2698e5c31af7Sopenharmony_ci{
2699e5c31af7Sopenharmony_ci	if (m_data.id == TEST_ID_INDICES_INDIRECT)
2700e5c31af7Sopenharmony_ci	{
2701e5c31af7Sopenharmony_ci		std::ostringstream raygenSrc;
2702e5c31af7Sopenharmony_ci		raygenSrc
2703e5c31af7Sopenharmony_ci			<< "struct Payload { uvec4 data; };\n"
2704e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadEXT Payload payload;\n"
2705e5c31af7Sopenharmony_ci			<< "void main() {\n"
2706e5c31af7Sopenharmony_ci			<< "	uint index = launchIndex();\n"
2707e5c31af7Sopenharmony_ci			<< "	payload.data = uvec4(0, 0, 0, 0);\n"
2708e5c31af7Sopenharmony_ci			<< "	Ray ray = rays[index];\n"
2709e5c31af7Sopenharmony_ci			<< "	traceRayEXT(scene, 0, 0xff, 0, 0, 0, ray.pos, ray.tmin, ray.dir, ray.tmax, 0);\n"
2710e5c31af7Sopenharmony_ci			<< "	results[index] = payload.data;\n"
2711e5c31af7Sopenharmony_ci			<< "}";
2712e5c31af7Sopenharmony_ci		const std::string raygen = raygenSrc.str();
2713e5c31af7Sopenharmony_ci		addBuiltInShaderSource<glu::RaygenSource>(programCollection, VK_SHADER_STAGE_RAYGEN_BIT_KHR, raygen, m_data, "uvec4");
2714e5c31af7Sopenharmony_ci
2715e5c31af7Sopenharmony_ci		std::ostringstream missSrc;
2716e5c31af7Sopenharmony_ci		missSrc
2717e5c31af7Sopenharmony_ci			<< "struct Payload { uvec4 data; };\n"
2718e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2719e5c31af7Sopenharmony_ci			<< "void main() {\n"
2720e5c31af7Sopenharmony_ci			<< "	payload.data = uvec4(111, 222, 333, 444);\n"
2721e5c31af7Sopenharmony_ci			<< "}";
2722e5c31af7Sopenharmony_ci		const std::string miss = missSrc.str();
2723e5c31af7Sopenharmony_ci		addBuiltInShaderSource<glu::MissSource>(programCollection, VK_SHADER_STAGE_MISS_BIT_KHR, miss, m_data, "uvec4");
2724e5c31af7Sopenharmony_ci
2725e5c31af7Sopenharmony_ci		std::ostringstream closestHitSrc;
2726e5c31af7Sopenharmony_ci		closestHitSrc
2727e5c31af7Sopenharmony_ci			<< "struct Payload { uvec4 data; };\n"
2728e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2729e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 attribs;\n"
2730e5c31af7Sopenharmony_ci			<< "void main() {\n"
2731e5c31af7Sopenharmony_ci			<< "	payload.data = uvec4(gl_PrimitiveID, 0, gl_InstanceID, gl_InstanceCustomIndexEXT);\n"
2732e5c31af7Sopenharmony_ci			<< "}";
2733e5c31af7Sopenharmony_ci		const std::string closestHit = closestHitSrc.str();
2734e5c31af7Sopenharmony_ci		addBuiltInShaderSource<glu::ClosestHitSource>(programCollection, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, closestHit, m_data, "uvec4");
2735e5c31af7Sopenharmony_ci
2736e5c31af7Sopenharmony_ci		std::ostringstream anyHitSrc;
2737e5c31af7Sopenharmony_ci		anyHitSrc
2738e5c31af7Sopenharmony_ci			<< "struct Payload { uvec4 data; };\n"
2739e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2740e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 attribs;\n"
2741e5c31af7Sopenharmony_ci			<< "void main() {\n"
2742e5c31af7Sopenharmony_ci			<< "	payload.data = uvec4(gl_PrimitiveID, 0, gl_InstanceID, gl_InstanceCustomIndexEXT);\n"
2743e5c31af7Sopenharmony_ci			<< "}";
2744e5c31af7Sopenharmony_ci		const std::string anyHit = anyHitSrc.str();
2745e5c31af7Sopenharmony_ci		addBuiltInShaderSource<glu::AnyHitSource>(programCollection, VK_SHADER_STAGE_ANY_HIT_BIT_KHR, anyHit, m_data, "uvec4");
2746e5c31af7Sopenharmony_ci
2747e5c31af7Sopenharmony_ci		std::ostringstream isectSrc;
2748e5c31af7Sopenharmony_ci		isectSrc
2749e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 dummy;\n"
2750e5c31af7Sopenharmony_ci			<< "void main() {\n"
2751e5c31af7Sopenharmony_ci			<< "	reportIntersectionEXT(0.0, 0u);\n"
2752e5c31af7Sopenharmony_ci			<< "}";
2753e5c31af7Sopenharmony_ci		const std::string isect = isectSrc.str();
2754e5c31af7Sopenharmony_ci		addBuiltInShaderSource<glu::IntersectionSource>(programCollection, VK_SHADER_STAGE_INTERSECTION_BIT_KHR, isect, m_data, "uvec4");
2755e5c31af7Sopenharmony_ci	}
2756e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_TRANSFORMS_INDIRECT)
2757e5c31af7Sopenharmony_ci	{
2758e5c31af7Sopenharmony_ci		const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0, true);
2759e5c31af7Sopenharmony_ci
2760e5c31af7Sopenharmony_ci		std::ostringstream preambleSrc;
2761e5c31af7Sopenharmony_ci		preambleSrc
2762e5c31af7Sopenharmony_ci			<< "struct ResultData { Ray ray; vec4 worldRayOrig; vec4 worldRayDir; vec4 objectRayOrig; vec4 objectRayDir;\n"
2763e5c31af7Sopenharmony_ci			<< "vec4 objectToWorld[4]; vec4 worldToObject[4];\n"
2764e5c31af7Sopenharmony_ci			<< "uint missResult; uint closestHitResult; uint anyHitResult; uint isectResult; };\n"
2765e5c31af7Sopenharmony_ci			<< "layout(std430, set = 0, binding = 0) buffer Results { ResultData results; };\n"
2766e5c31af7Sopenharmony_ci			<< "\n"
2767e5c31af7Sopenharmony_ci			<< "#ifdef CHECKS\n"
2768e5c31af7Sopenharmony_ci			<< "bool fuzzy_check(vec3 a, vec3 b) {\n"
2769e5c31af7Sopenharmony_ci			<< "	float eps = 0.00001;\n"
2770e5c31af7Sopenharmony_ci			<< "	return abs(a.x - b.x) <= eps && abs(a.y - b.y) <= eps && abs(a.z - b.z) <= eps;\n"
2771e5c31af7Sopenharmony_ci			<< "}\n"
2772e5c31af7Sopenharmony_ci			<< "bool check_all() {\n"
2773e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.worldRayOrig.xyz, gl_WorldRayOriginEXT) == false)\n"
2774e5c31af7Sopenharmony_ci			<< "		return false;\n"
2775e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.worldRayDir.xyz, gl_WorldRayDirectionEXT) == false)\n"
2776e5c31af7Sopenharmony_ci			<< "		return false;\n"
2777e5c31af7Sopenharmony_ci			<< "#ifndef MISS_SHADER\n"
2778e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.objectRayOrig.xyz, gl_ObjectRayOriginEXT) == false)\n"
2779e5c31af7Sopenharmony_ci			<< "		return false;\n"
2780e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.objectRayDir.xyz, gl_WorldRayDirectionEXT) == false)\n"
2781e5c31af7Sopenharmony_ci			<< "		return false;\n"
2782e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.objectToWorld[0].xyz, gl_ObjectToWorldEXT[0]) == false)\n"
2783e5c31af7Sopenharmony_ci			<< "		return false;\n"
2784e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.objectToWorld[1].xyz, gl_ObjectToWorldEXT[1]) == false)\n"
2785e5c31af7Sopenharmony_ci			<< "		return false;\n"
2786e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.objectToWorld[2].xyz, gl_ObjectToWorldEXT[2]) == false)\n"
2787e5c31af7Sopenharmony_ci			<< "		return false;\n"
2788e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.objectToWorld[3].xyz, gl_ObjectToWorldEXT[3]) == false)\n"
2789e5c31af7Sopenharmony_ci			<< "		return false;\n"
2790e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.worldToObject[0].xyz, gl_WorldToObjectEXT[0]) == false)\n"
2791e5c31af7Sopenharmony_ci			<< "		return false;\n"
2792e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.worldToObject[1].xyz, gl_WorldToObjectEXT[1]) == false)\n"
2793e5c31af7Sopenharmony_ci			<< "		return false;\n"
2794e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.worldToObject[2].xyz, gl_WorldToObjectEXT[2]) == false)\n"
2795e5c31af7Sopenharmony_ci			<< "		return false;\n"
2796e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.worldToObject[3].xyz, gl_WorldToObjectEXT[3]) == false)\n"
2797e5c31af7Sopenharmony_ci			<< "		return false;\n"
2798e5c31af7Sopenharmony_ci			<< "#endif\n"
2799e5c31af7Sopenharmony_ci			<< "	return true;\n"
2800e5c31af7Sopenharmony_ci			<< "};\n"
2801e5c31af7Sopenharmony_ci			<< "#endif\n";
2802e5c31af7Sopenharmony_ci		const std::string preamble = preambleSrc.str();
2803e5c31af7Sopenharmony_ci
2804e5c31af7Sopenharmony_ci		std::ostringstream raygenSrc;
2805e5c31af7Sopenharmony_ci		raygenSrc
2806e5c31af7Sopenharmony_ci			<< "$preamble$\n"
2807e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
2808e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadEXT Payload payload;\n"
2809e5c31af7Sopenharmony_ci			<< "void main() {\n"
2810e5c31af7Sopenharmony_ci			<< "	payload.x = 0;\n"
2811e5c31af7Sopenharmony_ci			<< "	results.missResult = 0;\n"
2812e5c31af7Sopenharmony_ci			<< "	results.closestHitResult = 0;\n"
2813e5c31af7Sopenharmony_ci			<< "	results.anyHitResult = 0;\n"
2814e5c31af7Sopenharmony_ci			<< "	results.isectResult = 0;\n"
2815e5c31af7Sopenharmony_ci			<< "	Ray ray = results.ray;\n"
2816e5c31af7Sopenharmony_ci			<< "	traceRayEXT(scene, 0, 0xff, 0, 0, 0, ray.pos, ray.tmin, ray.dir, ray.tmax, 0);\n"
2817e5c31af7Sopenharmony_ci			<< "}";
2818e5c31af7Sopenharmony_ci		std::string raygen = raygenSrc.str();
2819e5c31af7Sopenharmony_ci		raygen = generateShaderSource(raygen.c_str(), "", DEFINE_RAY | DEFINE_SCENE);
2820e5c31af7Sopenharmony_ci		raygen = replaceString(raygen, "$preamble$", preamble);
2821e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_RAYGEN_BIT_KHR)) << glu::RaygenSource(raygen) << buildOptions;
2822e5c31af7Sopenharmony_ci
2823e5c31af7Sopenharmony_ci		std::ostringstream missSrc;
2824e5c31af7Sopenharmony_ci		missSrc
2825e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
2826e5c31af7Sopenharmony_ci			<< "#define MISS_SHADER\n"
2827e5c31af7Sopenharmony_ci			<< "$preamble$\n"
2828e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
2829e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2830e5c31af7Sopenharmony_ci			<< "void main() {\n"
2831e5c31af7Sopenharmony_ci			<< "	if (check_all())\n"
2832e5c31af7Sopenharmony_ci			<< "		results.missResult = 1;\n"
2833e5c31af7Sopenharmony_ci			<< "}";
2834e5c31af7Sopenharmony_ci		std::string miss = missSrc.str();
2835e5c31af7Sopenharmony_ci		miss = generateShaderSource(miss.c_str(), "", DEFINE_RAY);
2836e5c31af7Sopenharmony_ci		miss = replaceString(miss, "$preamble$", preamble);
2837e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_MISS_BIT_KHR)) << glu::MissSource(miss) << buildOptions;
2838e5c31af7Sopenharmony_ci
2839e5c31af7Sopenharmony_ci		std::ostringstream closestHitSrc;
2840e5c31af7Sopenharmony_ci		closestHitSrc
2841e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
2842e5c31af7Sopenharmony_ci			<< "$preamble$\n"
2843e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
2844e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2845e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 attribs; "
2846e5c31af7Sopenharmony_ci			<< "void main() {\n"
2847e5c31af7Sopenharmony_ci			<< "	if (check_all())\n"
2848e5c31af7Sopenharmony_ci			<< "		results.closestHitResult = 1;\n"
2849e5c31af7Sopenharmony_ci			<< "}";
2850e5c31af7Sopenharmony_ci		std::string closestHit = closestHitSrc.str();
2851e5c31af7Sopenharmony_ci		closestHit = generateShaderSource(closestHit.c_str(), "", DEFINE_RAY);
2852e5c31af7Sopenharmony_ci		closestHit = replaceString(closestHit, "$preamble$", preamble);
2853e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)) << glu::ClosestHitSource(closestHit) << buildOptions;
2854e5c31af7Sopenharmony_ci
2855e5c31af7Sopenharmony_ci		std::ostringstream anyHitSrc;
2856e5c31af7Sopenharmony_ci		anyHitSrc
2857e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
2858e5c31af7Sopenharmony_ci			<< "$preamble$\n"
2859e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
2860e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2861e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 attribs; "
2862e5c31af7Sopenharmony_ci			<< "void main() {\n"
2863e5c31af7Sopenharmony_ci			<< "	if (check_all())\n"
2864e5c31af7Sopenharmony_ci			<< "		results.anyHitResult = 1;\n"
2865e5c31af7Sopenharmony_ci			<< "}";
2866e5c31af7Sopenharmony_ci		std::string anyHit = anyHitSrc.str();
2867e5c31af7Sopenharmony_ci		anyHit = generateShaderSource(anyHit.c_str(), "", DEFINE_RAY);
2868e5c31af7Sopenharmony_ci		anyHit = replaceString(anyHit, "$preamble$", preamble);
2869e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_ANY_HIT_BIT_KHR)) << glu::AnyHitSource(anyHit) << buildOptions;
2870e5c31af7Sopenharmony_ci
2871e5c31af7Sopenharmony_ci		std::ostringstream isectSrc;
2872e5c31af7Sopenharmony_ci		isectSrc
2873e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
2874e5c31af7Sopenharmony_ci			<< "$preamble$\n"
2875e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 dummy;\n"
2876e5c31af7Sopenharmony_ci			<< "void main() {\n"
2877e5c31af7Sopenharmony_ci			<< "	if (check_all())\n"
2878e5c31af7Sopenharmony_ci			<< "		results.isectResult = 1;\n"
2879e5c31af7Sopenharmony_ci			<< "	reportIntersectionEXT(0.0, 0u);\n"
2880e5c31af7Sopenharmony_ci			<< "}";
2881e5c31af7Sopenharmony_ci		std::string isect = isectSrc.str();
2882e5c31af7Sopenharmony_ci		isect = generateShaderSource(isect.c_str(), "", DEFINE_RAY);
2883e5c31af7Sopenharmony_ci		isect = replaceString(isect, "$preamble$", preamble);
2884e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_INTERSECTION_BIT_KHR)) << glu::IntersectionSource(isect) << buildOptions;
2885e5c31af7Sopenharmony_ci	}
2886e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_TMINMAX_INDIRECT)
2887e5c31af7Sopenharmony_ci	{
2888e5c31af7Sopenharmony_ci		const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
2889e5c31af7Sopenharmony_ci
2890e5c31af7Sopenharmony_ci		std::ostringstream preambleSrc;
2891e5c31af7Sopenharmony_ci		preambleSrc
2892e5c31af7Sopenharmony_ci			<< "struct ResultData { Ray ray; float miss_maxt; float chit_maxt; float ahit_maxt; float isect_maxt;\n"
2893e5c31af7Sopenharmony_ci			<< "uint missResult; uint closestHitResult; uint anyHitResult; uint isectResult; float debug; };\n"
2894e5c31af7Sopenharmony_ci			<< "layout(std430, set = 0, binding = 0) buffer Results { ResultData results; };\n"
2895e5c31af7Sopenharmony_ci			<< "\n"
2896e5c31af7Sopenharmony_ci			<< "#ifdef CHECKS\n"
2897e5c31af7Sopenharmony_ci			<< "bool fuzzy_check(float a, float b) {\n"
2898e5c31af7Sopenharmony_ci			<< "	float eps = 0.0001;\n"
2899e5c31af7Sopenharmony_ci			<< "	return abs(a - b) <= eps;\n"
2900e5c31af7Sopenharmony_ci			<< "}\n"
2901e5c31af7Sopenharmony_ci			<< "bool check_all() {\n"
2902e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.ray.tmin, gl_RayTminEXT) == false)\n"
2903e5c31af7Sopenharmony_ci			<< "		return false;\n"
2904e5c31af7Sopenharmony_ci			<< "#ifdef MISS_SHADER\n"
2905e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.miss_maxt, gl_RayTmaxEXT) == false)\n"
2906e5c31af7Sopenharmony_ci			<< "		return false;\n"
2907e5c31af7Sopenharmony_ci			<< "#endif\n"
2908e5c31af7Sopenharmony_ci			<< "#ifdef CHIT_SHADER\n"
2909e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.chit_maxt, gl_RayTmaxEXT) == false)\n"
2910e5c31af7Sopenharmony_ci			<< "		return false;\n"
2911e5c31af7Sopenharmony_ci			<< "#endif\n"
2912e5c31af7Sopenharmony_ci			<< "#ifdef AHIT_SHADER\n"
2913e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.ahit_maxt, gl_RayTmaxEXT) == false)\n"
2914e5c31af7Sopenharmony_ci			<< "		return false;\n"
2915e5c31af7Sopenharmony_ci			<< "#endif\n"
2916e5c31af7Sopenharmony_ci			<< "#ifdef ISECT_SHADER\n"
2917e5c31af7Sopenharmony_ci			<< "	if (fuzzy_check(results.isect_maxt, gl_RayTmaxEXT) == false)\n"
2918e5c31af7Sopenharmony_ci			<< "		return false;\n"
2919e5c31af7Sopenharmony_ci			<< "#endif\n"
2920e5c31af7Sopenharmony_ci			<< "	return true;\n"
2921e5c31af7Sopenharmony_ci			<< "};\n"
2922e5c31af7Sopenharmony_ci			<< "#endif\n";
2923e5c31af7Sopenharmony_ci		const std::string preamble = preambleSrc.str();
2924e5c31af7Sopenharmony_ci
2925e5c31af7Sopenharmony_ci		std::ostringstream raygenSrc;
2926e5c31af7Sopenharmony_ci		raygenSrc
2927e5c31af7Sopenharmony_ci			<< "$preamble$\n"
2928e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
2929e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadEXT Payload payload;\n"
2930e5c31af7Sopenharmony_ci			<< "void main() {\n"
2931e5c31af7Sopenharmony_ci			<< "	payload.x = 0;\n"
2932e5c31af7Sopenharmony_ci			<< "	results.missResult = 0;\n"
2933e5c31af7Sopenharmony_ci			<< "	results.closestHitResult = 0;\n"
2934e5c31af7Sopenharmony_ci			<< "	results.anyHitResult = 0;\n"
2935e5c31af7Sopenharmony_ci			<< "	results.isectResult = 0;\n"
2936e5c31af7Sopenharmony_ci			<< "	Ray ray = results.ray;\n"
2937e5c31af7Sopenharmony_ci			<< "	traceRayEXT(scene, 0, 0xff, 0, 0, 0, ray.pos, ray.tmin, ray.dir, ray.tmax, 0);\n"
2938e5c31af7Sopenharmony_ci			<< "}";
2939e5c31af7Sopenharmony_ci		std::string raygen = raygenSrc.str();
2940e5c31af7Sopenharmony_ci		raygen = generateShaderSource(raygen.c_str(), "", DEFINE_RAY | DEFINE_SCENE);
2941e5c31af7Sopenharmony_ci		raygen = replaceString(raygen, "$preamble$", preamble);
2942e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_RAYGEN_BIT_KHR)) << glu::RaygenSource(raygen) << buildOptions;
2943e5c31af7Sopenharmony_ci
2944e5c31af7Sopenharmony_ci		std::ostringstream missSrc;
2945e5c31af7Sopenharmony_ci		missSrc
2946e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
2947e5c31af7Sopenharmony_ci			<< "#define MISS_SHADER\n"
2948e5c31af7Sopenharmony_ci			<< "$preamble$\n"
2949e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
2950e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2951e5c31af7Sopenharmony_ci			<< "void main() {\n"
2952e5c31af7Sopenharmony_ci			<< "	if (check_all())\n"
2953e5c31af7Sopenharmony_ci			<< "		results.missResult = 1;\n"
2954e5c31af7Sopenharmony_ci			<< "}";
2955e5c31af7Sopenharmony_ci		std::string miss = missSrc.str();
2956e5c31af7Sopenharmony_ci		miss = generateShaderSource(miss.c_str(), "", DEFINE_RAY);
2957e5c31af7Sopenharmony_ci		miss = replaceString(miss, "$preamble$", preamble);
2958e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_MISS_BIT_KHR)) << glu::MissSource(miss) << buildOptions;
2959e5c31af7Sopenharmony_ci
2960e5c31af7Sopenharmony_ci		std::ostringstream cloesetHitSrc;
2961e5c31af7Sopenharmony_ci		cloesetHitSrc
2962e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
2963e5c31af7Sopenharmony_ci			<< "#define CHIT_SHADER\n"
2964e5c31af7Sopenharmony_ci			<< "$preamble$\n"
2965e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
2966e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2967e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 attribs; "
2968e5c31af7Sopenharmony_ci			<< "void main() {\n"
2969e5c31af7Sopenharmony_ci			<< "	if (check_all())\n"
2970e5c31af7Sopenharmony_ci			<< "		results.closestHitResult = 1;\n"
2971e5c31af7Sopenharmony_ci			<< "}";
2972e5c31af7Sopenharmony_ci		std::string closestHit = cloesetHitSrc.str();
2973e5c31af7Sopenharmony_ci		closestHit = generateShaderSource(closestHit.c_str(), "", DEFINE_RAY);
2974e5c31af7Sopenharmony_ci		closestHit = replaceString(closestHit, "$preamble$", preamble);
2975e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)) << glu::ClosestHitSource(closestHit) << buildOptions;
2976e5c31af7Sopenharmony_ci
2977e5c31af7Sopenharmony_ci		std::ostringstream anyHitSrc;
2978e5c31af7Sopenharmony_ci		anyHitSrc
2979e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
2980e5c31af7Sopenharmony_ci			<< "#define AHIT_SHADER\n"
2981e5c31af7Sopenharmony_ci			<< "$preamble$\n"
2982e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
2983e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
2984e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 attribs; "
2985e5c31af7Sopenharmony_ci			<< "void main() {\n"
2986e5c31af7Sopenharmony_ci			<< "	if (check_all())\n"
2987e5c31af7Sopenharmony_ci			<< "		results.anyHitResult = 1;\n"
2988e5c31af7Sopenharmony_ci			<< "}";
2989e5c31af7Sopenharmony_ci		std::string anyHit = anyHitSrc.str();
2990e5c31af7Sopenharmony_ci		anyHit = generateShaderSource(anyHit.c_str(), "", DEFINE_RAY);
2991e5c31af7Sopenharmony_ci		anyHit = replaceString(anyHit, "$preamble$", preamble);
2992e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_ANY_HIT_BIT_KHR)) << glu::AnyHitSource(anyHit) << buildOptions;
2993e5c31af7Sopenharmony_ci
2994e5c31af7Sopenharmony_ci		std::ostringstream isectSrc;
2995e5c31af7Sopenharmony_ci		isectSrc
2996e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
2997e5c31af7Sopenharmony_ci			<< "#define ISECT_SHADER\n"
2998e5c31af7Sopenharmony_ci			<< "$preamble$\n"
2999e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 dummy;\n"
3000e5c31af7Sopenharmony_ci			<< "void main() {\n"
3001e5c31af7Sopenharmony_ci			<< "	results.debug = gl_RayTmaxEXT;\n"
3002e5c31af7Sopenharmony_ci			<< "	if (check_all())\n"
3003e5c31af7Sopenharmony_ci			<< "		results.isectResult = 1;\n"
3004e5c31af7Sopenharmony_ci			<< "	reportIntersectionEXT(results.chit_maxt, 0u);\n"
3005e5c31af7Sopenharmony_ci			<< "}";
3006e5c31af7Sopenharmony_ci		std::string isect = isectSrc.str();
3007e5c31af7Sopenharmony_ci		isect = generateShaderSource(isect.c_str(), "", DEFINE_RAY);
3008e5c31af7Sopenharmony_ci		isect = replaceString(isect, "$preamble$", preamble);
3009e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_INTERSECTION_BIT_KHR)) << glu::IntersectionSource(isect) << buildOptions;
3010e5c31af7Sopenharmony_ci	}
3011e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_INDIRECT)
3012e5c31af7Sopenharmony_ci	{
3013e5c31af7Sopenharmony_ci		const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0, true);
3014e5c31af7Sopenharmony_ci
3015e5c31af7Sopenharmony_ci		std::ostringstream preambleSrc;
3016e5c31af7Sopenharmony_ci		preambleSrc
3017e5c31af7Sopenharmony_ci			<< "struct ResultData { Ray ray[2]; uint flags; uint miss[2]; uint chit[2]; uint ahit[2]; uint isect[2]; };\n"
3018e5c31af7Sopenharmony_ci			<< "layout(std430, set = 0, binding = 0) buffer Results { ResultData results; };\n"
3019e5c31af7Sopenharmony_ci			<< "\n"
3020e5c31af7Sopenharmony_ci			<< "#ifdef CHECKS\n"
3021e5c31af7Sopenharmony_ci			<< "bool check_all() {\n"
3022e5c31af7Sopenharmony_ci			<< "	if (gl_IncomingRayFlagsEXT != results.flags)\n"
3023e5c31af7Sopenharmony_ci			<< "		return false;\n"
3024e5c31af7Sopenharmony_ci			<< "	return true;\n"
3025e5c31af7Sopenharmony_ci			<< "}\n"
3026e5c31af7Sopenharmony_ci			<< "#endif\n";
3027e5c31af7Sopenharmony_ci		const std::string preamble = preambleSrc.str();
3028e5c31af7Sopenharmony_ci
3029e5c31af7Sopenharmony_ci		std::ostringstream raygenSrc;
3030e5c31af7Sopenharmony_ci		raygenSrc
3031e5c31af7Sopenharmony_ci			<< "$preamble$\n"
3032e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
3033e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadEXT Payload payload;\n"
3034e5c31af7Sopenharmony_ci			<< "void main() {\n"
3035e5c31af7Sopenharmony_ci			<< "	payload.x = 0;\n"
3036e5c31af7Sopenharmony_ci			<< "	results.miss[gl_LaunchIDEXT.x] = 0;\n"
3037e5c31af7Sopenharmony_ci			<< "	results.chit[gl_LaunchIDEXT.x] = 0;\n"
3038e5c31af7Sopenharmony_ci			<< "	results.ahit[gl_LaunchIDEXT.x] = 0;\n"
3039e5c31af7Sopenharmony_ci			<< "	results.isect[gl_LaunchIDEXT.x] = 0;\n"
3040e5c31af7Sopenharmony_ci			<< "	Ray ray = results.ray[gl_LaunchIDEXT.x];\n"
3041e5c31af7Sopenharmony_ci			<< "	traceRayEXT(scene, results.flags, 0xff, 0, 0, 0, ray.pos, ray.tmin, ray.dir, ray.tmax, 0);\n"
3042e5c31af7Sopenharmony_ci			<< "}";
3043e5c31af7Sopenharmony_ci		std::string raygen = raygenSrc.str();
3044e5c31af7Sopenharmony_ci		raygen = generateShaderSource(raygen.c_str(), "", DEFINE_RAY | DEFINE_SCENE);
3045e5c31af7Sopenharmony_ci		raygen = replaceString(raygen, "$preamble$", preamble);
3046e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_RAYGEN_BIT_KHR)) << glu::RaygenSource(raygen) << buildOptions;
3047e5c31af7Sopenharmony_ci
3048e5c31af7Sopenharmony_ci		std::ostringstream missSrc;
3049e5c31af7Sopenharmony_ci		missSrc
3050e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
3051e5c31af7Sopenharmony_ci			<< "#define MISS_SHADER\n"
3052e5c31af7Sopenharmony_ci			<< "$preamble$\n"
3053e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
3054e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
3055e5c31af7Sopenharmony_ci			<< "void main() {\n"
3056e5c31af7Sopenharmony_ci			<< "	if (check_all())\n"
3057e5c31af7Sopenharmony_ci			<< "		results.miss[gl_LaunchIDEXT.x]++;\n"
3058e5c31af7Sopenharmony_ci			<< "}";
3059e5c31af7Sopenharmony_ci		std::string miss = missSrc.str();
3060e5c31af7Sopenharmony_ci		miss = generateShaderSource(miss.c_str(), "", DEFINE_RAY);
3061e5c31af7Sopenharmony_ci		miss = replaceString(miss, "$preamble$", preamble);
3062e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_MISS_BIT_KHR)) << glu::MissSource(miss) << buildOptions;
3063e5c31af7Sopenharmony_ci
3064e5c31af7Sopenharmony_ci		std::ostringstream closestHitSrc;
3065e5c31af7Sopenharmony_ci		closestHitSrc
3066e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
3067e5c31af7Sopenharmony_ci			<< "#define CHIT_SHADER\n"
3068e5c31af7Sopenharmony_ci			<< "$preamble$\n"
3069e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
3070e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
3071e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 attribs; "
3072e5c31af7Sopenharmony_ci			<< "void main() {\n"
3073e5c31af7Sopenharmony_ci			<< "	if (check_all())\n"
3074e5c31af7Sopenharmony_ci			<< "		results.chit[gl_LaunchIDEXT.x]++;\n"
3075e5c31af7Sopenharmony_ci			<< "}";
3076e5c31af7Sopenharmony_ci		std::string closestHit = closestHitSrc.str();
3077e5c31af7Sopenharmony_ci		closestHit = generateShaderSource(closestHit.c_str(), "", DEFINE_RAY);
3078e5c31af7Sopenharmony_ci		closestHit = replaceString(closestHit, "$preamble$", preamble);
3079e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)) << glu::ClosestHitSource(closestHit) << buildOptions;
3080e5c31af7Sopenharmony_ci
3081e5c31af7Sopenharmony_ci		std::ostringstream anyHitSrc;
3082e5c31af7Sopenharmony_ci		anyHitSrc
3083e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
3084e5c31af7Sopenharmony_ci			<< "#define AHIT_SHADER\n"
3085e5c31af7Sopenharmony_ci			<< "$preamble$\n"
3086e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
3087e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
3088e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 attribs; "
3089e5c31af7Sopenharmony_ci			<< "void main() {\n"
3090e5c31af7Sopenharmony_ci			<< "	if (check_all())\n"
3091e5c31af7Sopenharmony_ci			<< "		results.ahit[gl_LaunchIDEXT.x]++;\n"
3092e5c31af7Sopenharmony_ci			<< "}";
3093e5c31af7Sopenharmony_ci		std::string anyHit = anyHitSrc.str();
3094e5c31af7Sopenharmony_ci		anyHit = generateShaderSource(anyHit.c_str(), "", DEFINE_RAY);
3095e5c31af7Sopenharmony_ci		anyHit = replaceString(anyHit, "$preamble$", preamble);
3096e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_ANY_HIT_BIT_KHR)) << glu::AnyHitSource(anyHit) << buildOptions;
3097e5c31af7Sopenharmony_ci
3098e5c31af7Sopenharmony_ci		std::ostringstream isectSrc;
3099e5c31af7Sopenharmony_ci		isectSrc
3100e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
3101e5c31af7Sopenharmony_ci			<< "#define ISECT_SHADER\n"
3102e5c31af7Sopenharmony_ci			<< "$preamble$\n"
3103e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 dummy;\n"
3104e5c31af7Sopenharmony_ci			<< "void main() {\n"
3105e5c31af7Sopenharmony_ci			<< "	if (check_all())\n"
3106e5c31af7Sopenharmony_ci			<< "		results.isect[gl_LaunchIDEXT.x]++;\n"
3107e5c31af7Sopenharmony_ci			<< "	reportIntersectionEXT(gl_RayTminEXT, 0u);\n"
3108e5c31af7Sopenharmony_ci			<< "}";
3109e5c31af7Sopenharmony_ci		std::string isect = isectSrc.str();
3110e5c31af7Sopenharmony_ci		isect = generateShaderSource(isect.c_str(), "", DEFINE_RAY);
3111e5c31af7Sopenharmony_ci		isect = replaceString(isect, "$preamble$", preamble);
3112e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_INTERSECTION_BIT_KHR)) << glu::IntersectionSource(isect) << buildOptions;
3113e5c31af7Sopenharmony_ci	}
3114e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_HIT_KIND_INDIRECT)
3115e5c31af7Sopenharmony_ci	{
3116e5c31af7Sopenharmony_ci		const vk::ShaderBuildOptions buildOptions(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0, true);
3117e5c31af7Sopenharmony_ci
3118e5c31af7Sopenharmony_ci		std::ostringstream preambleSrc;
3119e5c31af7Sopenharmony_ci		preambleSrc
3120e5c31af7Sopenharmony_ci			<< "struct ResultData { Ray ray[2]; uint kind[2]; uint chit[2]; uint ahit[2]; uint debug[2]; };\n"
3121e5c31af7Sopenharmony_ci			<< "layout(std430, set = 0, binding = 0) buffer Results { ResultData results; };\n"
3122e5c31af7Sopenharmony_ci			<< "\n"
3123e5c31af7Sopenharmony_ci			<< "#ifdef CHECKS\n"
3124e5c31af7Sopenharmony_ci			<< "bool check_all() {\n"
3125e5c31af7Sopenharmony_ci			<< "#if defined(CHIT_SHADER) || defined(AHIT_SHADER)\n"
3126e5c31af7Sopenharmony_ci			<< "	if (gl_HitKindEXT != results.kind[gl_LaunchIDEXT.x])\n"
3127e5c31af7Sopenharmony_ci			<< "		return false;\n"
3128e5c31af7Sopenharmony_ci			<< "#endif\n"
3129e5c31af7Sopenharmony_ci			<< "	return true;\n"
3130e5c31af7Sopenharmony_ci			<< "}\n"
3131e5c31af7Sopenharmony_ci			<< "#endif\n";
3132e5c31af7Sopenharmony_ci		const std::string preamble = preambleSrc.str();
3133e5c31af7Sopenharmony_ci
3134e5c31af7Sopenharmony_ci		std::ostringstream raygenSrc;
3135e5c31af7Sopenharmony_ci		raygenSrc
3136e5c31af7Sopenharmony_ci			<< "$preamble$\n"
3137e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
3138e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadEXT Payload payload;\n"
3139e5c31af7Sopenharmony_ci			<< "void main() {\n"
3140e5c31af7Sopenharmony_ci			<< "	payload.x = 0;\n"
3141e5c31af7Sopenharmony_ci			<< "	uint i = gl_LaunchIDEXT.x;\n"
3142e5c31af7Sopenharmony_ci			<< "	results.chit[i] = 0;\n"
3143e5c31af7Sopenharmony_ci			<< "	results.ahit[i] = 0;\n"
3144e5c31af7Sopenharmony_ci			<< "	Ray ray = results.ray[i];\n"
3145e5c31af7Sopenharmony_ci			<< "	traceRayEXT(scene, 0, 0xff, 0, 0, 0, ray.pos, ray.tmin, ray.dir, ray.tmax, 0);\n"
3146e5c31af7Sopenharmony_ci			<< "}";
3147e5c31af7Sopenharmony_ci		std::string raygen = raygenSrc.str();
3148e5c31af7Sopenharmony_ci		raygen = generateShaderSource(raygen.c_str(), "", DEFINE_RAY | DEFINE_SCENE);
3149e5c31af7Sopenharmony_ci		raygen = replaceString(raygen, "$preamble$", preamble);
3150e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_RAYGEN_BIT_KHR)) << glu::RaygenSource(raygen) << buildOptions;
3151e5c31af7Sopenharmony_ci
3152e5c31af7Sopenharmony_ci		std::ostringstream missSrc;
3153e5c31af7Sopenharmony_ci		missSrc
3154e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
3155e5c31af7Sopenharmony_ci			<< "#define MISS_SHADER\n"
3156e5c31af7Sopenharmony_ci			<< "$preamble$\n"
3157e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
3158e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
3159e5c31af7Sopenharmony_ci			<< "void main() {\n"
3160e5c31af7Sopenharmony_ci			<< "}";
3161e5c31af7Sopenharmony_ci		std::string miss = missSrc.str();
3162e5c31af7Sopenharmony_ci		miss = generateShaderSource(miss.c_str(), "", DEFINE_RAY);
3163e5c31af7Sopenharmony_ci		miss = replaceString(miss, "$preamble$", preamble);
3164e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_MISS_BIT_KHR)) << glu::MissSource(miss) << buildOptions;
3165e5c31af7Sopenharmony_ci
3166e5c31af7Sopenharmony_ci		std::ostringstream closestHitSrc;
3167e5c31af7Sopenharmony_ci		closestHitSrc
3168e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
3169e5c31af7Sopenharmony_ci			<< "#define CHIT_SHADER\n"
3170e5c31af7Sopenharmony_ci			<< "$preamble$\n"
3171e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
3172e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
3173e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 attribs; "
3174e5c31af7Sopenharmony_ci			<< "void main() {\n"
3175e5c31af7Sopenharmony_ci			<< "	results.debug[gl_LaunchIDEXT.x] = gl_HitKindEXT;\n"
3176e5c31af7Sopenharmony_ci			<< "	if (check_all())\n"
3177e5c31af7Sopenharmony_ci			<< "		results.chit[gl_LaunchIDEXT.x] = 1;\n"
3178e5c31af7Sopenharmony_ci			<< "}";
3179e5c31af7Sopenharmony_ci		std::string closestHit = closestHitSrc.str();
3180e5c31af7Sopenharmony_ci		closestHit = generateShaderSource(closestHit.c_str(), "", DEFINE_RAY);
3181e5c31af7Sopenharmony_ci		closestHit = replaceString(closestHit, "$preamble$", preamble);
3182e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)) << glu::ClosestHitSource(closestHit) << buildOptions;
3183e5c31af7Sopenharmony_ci
3184e5c31af7Sopenharmony_ci		std::ostringstream anyHitSrc;
3185e5c31af7Sopenharmony_ci		anyHitSrc
3186e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
3187e5c31af7Sopenharmony_ci			<< "#define AHIT_SHADER\n"
3188e5c31af7Sopenharmony_ci			<< "$preamble$\n"
3189e5c31af7Sopenharmony_ci			<< "struct Payload { uint x; };\n"
3190e5c31af7Sopenharmony_ci			<< "layout(location = 0) rayPayloadInEXT Payload payload;\n"
3191e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 attribs; "
3192e5c31af7Sopenharmony_ci			<< "void main() {\n"
3193e5c31af7Sopenharmony_ci			<< "	if (check_all())\n"
3194e5c31af7Sopenharmony_ci			<< "		results.ahit[gl_LaunchIDEXT.x] = 1;\n"
3195e5c31af7Sopenharmony_ci			<< "}";
3196e5c31af7Sopenharmony_ci		std::string anyHit = anyHitSrc.str();
3197e5c31af7Sopenharmony_ci		anyHit = generateShaderSource(anyHit.c_str(), "", DEFINE_RAY);
3198e5c31af7Sopenharmony_ci		anyHit = replaceString(anyHit, "$preamble$", preamble);
3199e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_ANY_HIT_BIT_KHR)) << glu::AnyHitSource(anyHit) << buildOptions;
3200e5c31af7Sopenharmony_ci
3201e5c31af7Sopenharmony_ci		std::ostringstream isectSrc;
3202e5c31af7Sopenharmony_ci		isectSrc
3203e5c31af7Sopenharmony_ci			<< "#define CHECKS\n"
3204e5c31af7Sopenharmony_ci			<< "#define ISECT_SHADER\n"
3205e5c31af7Sopenharmony_ci			<< "$preamble$\n"
3206e5c31af7Sopenharmony_ci			<< "hitAttributeEXT vec2 dummy;\n"
3207e5c31af7Sopenharmony_ci			<< "void main() {\n"
3208e5c31af7Sopenharmony_ci			<< "	reportIntersectionEXT(gl_RayTminEXT, results.kind[gl_LaunchIDEXT.x]);\n"
3209e5c31af7Sopenharmony_ci			<< "}";
3210e5c31af7Sopenharmony_ci		std::string isect = isectSrc.str();
3211e5c31af7Sopenharmony_ci		isect = generateShaderSource(isect.c_str(), "", DEFINE_RAY);
3212e5c31af7Sopenharmony_ci		isect = replaceString(isect, "$preamble$", preamble);
3213e5c31af7Sopenharmony_ci		programCollection.glslSources.add(getShaderIdentifier(m_data, VK_SHADER_STAGE_INTERSECTION_BIT_KHR)) << glu::IntersectionSource(isect) << buildOptions;
3214e5c31af7Sopenharmony_ci	}
3215e5c31af7Sopenharmony_ci}
3216e5c31af7Sopenharmony_ci
3217e5c31af7Sopenharmony_ciTestInstance* RayTracingIndirectTestCase::createInstance (Context& context) const
3218e5c31af7Sopenharmony_ci{
3219e5c31af7Sopenharmony_ci	return new RayTracingIndirectTestInstance(context, m_data);
3220e5c31af7Sopenharmony_ci}
3221e5c31af7Sopenharmony_ci
3222e5c31af7Sopenharmony_ciMove<VkPipeline> RayTracingIndirectTestInstance::createPipelineAndShaderBindingTables (de::MovePtr<RayTracingPipeline>& rayTracingPipeline, bool aabb, VkPipelineLayout pipelineLayout)
3223e5c31af7Sopenharmony_ci{
3224e5c31af7Sopenharmony_ci	const InstanceInterface&			vki									= m_context.getInstanceInterface();
3225e5c31af7Sopenharmony_ci	const DeviceInterface&				vk									= m_context.getDeviceInterface();
3226e5c31af7Sopenharmony_ci	const VkDevice						device								= m_context.getDevice();
3227e5c31af7Sopenharmony_ci	const VkPhysicalDevice				physicalDevice						= m_context.getPhysicalDevice();
3228e5c31af7Sopenharmony_ci	Allocator&							allocator							= m_context.getDefaultAllocator();
3229e5c31af7Sopenharmony_ci
3230e5c31af7Sopenharmony_ci	const deUint32	shaderGroupHandleSize		= getShaderGroupSize(vki, physicalDevice);
3231e5c31af7Sopenharmony_ci	const deUint32	shaderGroupBaseAlignment	= getShaderGroupBaseAlignment(vki, physicalDevice);
3232e5c31af7Sopenharmony_ci
3233e5c31af7Sopenharmony_ci	rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR,		createShaderModule(vk, device, m_context.getBinaryCollection().get(getShaderIdentifier(m_data, VK_SHADER_STAGE_RAYGEN_BIT_KHR)), 0), 0);
3234e5c31af7Sopenharmony_ci	rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR,			createShaderModule(vk, device, m_context.getBinaryCollection().get(getShaderIdentifier(m_data, VK_SHADER_STAGE_MISS_BIT_KHR)), 0), 1);
3235e5c31af7Sopenharmony_ci	for (deUint32 g = 0; g < m_numGeoms; ++g)
3236e5c31af7Sopenharmony_ci	{
3237e5c31af7Sopenharmony_ci		rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,	createShaderModule(vk, device, m_context.getBinaryCollection().get(getShaderIdentifier(m_data, VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR)), 0), 2 + g);
3238e5c31af7Sopenharmony_ci		rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR,		createShaderModule(vk, device, m_context.getBinaryCollection().get(getShaderIdentifier(m_data, VK_SHADER_STAGE_ANY_HIT_BIT_KHR)), 0), 2 + g);
3239e5c31af7Sopenharmony_ci
3240e5c31af7Sopenharmony_ci		if (aabb)
3241e5c31af7Sopenharmony_ci		{
3242e5c31af7Sopenharmony_ci			rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR,	createShaderModule(vk, device, m_context.getBinaryCollection().get(getShaderIdentifier(m_data, VK_SHADER_STAGE_INTERSECTION_BIT_KHR)), 0), 2 + g);
3243e5c31af7Sopenharmony_ci		}
3244e5c31af7Sopenharmony_ci	}
3245e5c31af7Sopenharmony_ci	Move<VkPipeline> pipeline = rayTracingPipeline->createPipeline(vk, device, pipelineLayout);
3246e5c31af7Sopenharmony_ci
3247e5c31af7Sopenharmony_ci	m_raygenShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
3248e5c31af7Sopenharmony_ci	m_missShaderBindingTable				= rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
3249e5c31af7Sopenharmony_ci	m_hitShaderBindingTable					= rayTracingPipeline->createShaderBindingTable(vk, device, *pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, m_numGeoms);
3250e5c31af7Sopenharmony_ci
3251e5c31af7Sopenharmony_ci	m_raygenShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, m_raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
3252e5c31af7Sopenharmony_ci	m_missShaderBindingTableRegion			= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, m_missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
3253e5c31af7Sopenharmony_ci	m_hitShaderBindingTableRegion			= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vk, device, m_hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
3254e5c31af7Sopenharmony_ci	m_callableShaderBindingTableRegion		= makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0);
3255e5c31af7Sopenharmony_ci
3256e5c31af7Sopenharmony_ci	return pipeline;
3257e5c31af7Sopenharmony_ci}
3258e5c31af7Sopenharmony_ci
3259e5c31af7Sopenharmony_civoid RayTracingIndirectTestInstance::createPipelineLayoutAndSet (deUint32 setCount,
3260e5c31af7Sopenharmony_ci																 vk::Move<VkDescriptorPool>& descriptorPool,
3261e5c31af7Sopenharmony_ci																 vk::Move<VkDescriptorSetLayout>& descriptorSetLayout,
3262e5c31af7Sopenharmony_ci																 std::vector<vk::Move<VkDescriptorSet>>& descriptorSets,
3263e5c31af7Sopenharmony_ci																 vk::Move<VkPipelineLayout>& pipelineLayout)
3264e5c31af7Sopenharmony_ci{
3265e5c31af7Sopenharmony_ci	const DeviceInterface& vk = m_context.getDeviceInterface();
3266e5c31af7Sopenharmony_ci	const VkDevice device = m_context.getDevice();
3267e5c31af7Sopenharmony_ci
3268e5c31af7Sopenharmony_ci	vk::DescriptorPoolBuilder descriptorPoolBuilder;
3269e5c31af7Sopenharmony_ci
3270e5c31af7Sopenharmony_ci	deUint32 storageBufCount = 2 * setCount;
3271e5c31af7Sopenharmony_ci
3272e5c31af7Sopenharmony_ci	const VkDescriptorType accelType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
3273e5c31af7Sopenharmony_ci
3274e5c31af7Sopenharmony_ci	descriptorPoolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, storageBufCount);
3275e5c31af7Sopenharmony_ci	descriptorPoolBuilder.addType(accelType, setCount);
3276e5c31af7Sopenharmony_ci
3277e5c31af7Sopenharmony_ci	descriptorPool = descriptorPoolBuilder.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, setCount);
3278e5c31af7Sopenharmony_ci
3279e5c31af7Sopenharmony_ci	vk::DescriptorSetLayoutBuilder setLayoutBuilder;
3280e5c31af7Sopenharmony_ci
3281e5c31af7Sopenharmony_ci	setLayoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, ALL_RAY_TRACING_STAGES);
3282e5c31af7Sopenharmony_ci	setLayoutBuilder.addSingleBinding(accelType, ALL_RAY_TRACING_STAGES);
3283e5c31af7Sopenharmony_ci	setLayoutBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, ALL_RAY_TRACING_STAGES);
3284e5c31af7Sopenharmony_ci
3285e5c31af7Sopenharmony_ci	descriptorSetLayout = setLayoutBuilder.build(vk, device);
3286e5c31af7Sopenharmony_ci
3287e5c31af7Sopenharmony_ci	const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
3288e5c31af7Sopenharmony_ci	{
3289e5c31af7Sopenharmony_ci		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType;
3290e5c31af7Sopenharmony_ci		DE_NULL,											// const void*					pNext;
3291e5c31af7Sopenharmony_ci		*descriptorPool,									// VkDescriptorPool				descriptorPool;
3292e5c31af7Sopenharmony_ci		1u,													// deUint32						setLayoutCount;
3293e5c31af7Sopenharmony_ci		&descriptorSetLayout.get()							// const VkDescriptorSetLayout*	pSetLayouts;
3294e5c31af7Sopenharmony_ci	};
3295e5c31af7Sopenharmony_ci
3296e5c31af7Sopenharmony_ci	for (uint32_t i = 0; i < setCount; ++i)
3297e5c31af7Sopenharmony_ci		descriptorSets.push_back(allocateDescriptorSet(vk, device, &descriptorSetAllocateInfo));
3298e5c31af7Sopenharmony_ci
3299e5c31af7Sopenharmony_ci	const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
3300e5c31af7Sopenharmony_ci	{
3301e5c31af7Sopenharmony_ci		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
3302e5c31af7Sopenharmony_ci		DE_NULL,											// const void*					pNext;
3303e5c31af7Sopenharmony_ci		(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
3304e5c31af7Sopenharmony_ci		1u,													// deUint32						setLayoutCount;
3305e5c31af7Sopenharmony_ci		&descriptorSetLayout.get(),							// const VkDescriptorSetLayout*	pSetLayouts;
3306e5c31af7Sopenharmony_ci		0u,													// deUint32						pushConstantRangeCount;
3307e5c31af7Sopenharmony_ci		nullptr,											// const VkPushConstantRange*	pPushConstantRanges;
3308e5c31af7Sopenharmony_ci	};
3309e5c31af7Sopenharmony_ci
3310e5c31af7Sopenharmony_ci	pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutInfo);
3311e5c31af7Sopenharmony_ci}
3312e5c31af7Sopenharmony_ci
3313e5c31af7Sopenharmony_cide::SharedPtr<TopLevelAccelerationStructure> RayTracingIndirectTestInstance::initTopAccelerationStructure (std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>& blas)
3314e5c31af7Sopenharmony_ci{
3315e5c31af7Sopenharmony_ci	de::SharedPtr<TopLevelAccelerationStructure> tlas = de::SharedPtr<TopLevelAccelerationStructure>(makeTopLevelAccelerationStructure().release());
3316e5c31af7Sopenharmony_ci
3317e5c31af7Sopenharmony_ci	VkTransformMatrixKHR transform = identityMatrix3x4;
3318e5c31af7Sopenharmony_ci	if (m_data.id == TEST_ID_TRANSFORMS_INDIRECT)
3319e5c31af7Sopenharmony_ci	{
3320e5c31af7Sopenharmony_ci		tcu::Vec3 instanceOffset = tcu::Vec3(2.0f, 4.0f, 8.0f);
3321e5c31af7Sopenharmony_ci		transform.matrix[0][3] = instanceOffset[0];
3322e5c31af7Sopenharmony_ci		transform.matrix[1][3] = instanceOffset[1];
3323e5c31af7Sopenharmony_ci		transform.matrix[2][3] = instanceOffset[2];
3324e5c31af7Sopenharmony_ci	}
3325e5c31af7Sopenharmony_ci
3326e5c31af7Sopenharmony_ci	for (size_t i = 0; i < blas.size(); ++i)
3327e5c31af7Sopenharmony_ci	{
3328e5c31af7Sopenharmony_ci		tlas->addInstance(blas[i], transform, 1000 + static_cast<deUint32>(i));
3329e5c31af7Sopenharmony_ci	}
3330e5c31af7Sopenharmony_ci
3331e5c31af7Sopenharmony_ci	return tlas;
3332e5c31af7Sopenharmony_ci}
3333e5c31af7Sopenharmony_ci
3334e5c31af7Sopenharmony_cistd::vector<de::SharedPtr<BottomLevelAccelerationStructure>> RayTracingIndirectTestInstance::initBottomAccelerationStructures()
3335e5c31af7Sopenharmony_ci{
3336e5c31af7Sopenharmony_ci	const bool aabb = (m_data.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR);
3337e5c31af7Sopenharmony_ci
3338e5c31af7Sopenharmony_ci	deUint32 numInstances = m_data.id == TEST_ID_INDICES_INDIRECT ? 5 : 1;
3339e5c31af7Sopenharmony_ci
3340e5c31af7Sopenharmony_ci	if (m_data.id == TEST_ID_INDICES_INDIRECT || m_data.id == TEST_ID_TRANSFORMS_INDIRECT || m_data.id == TEST_ID_TMINMAX_INDIRECT)
3341e5c31af7Sopenharmony_ci	{
3342e5c31af7Sopenharmony_ci		m_geomsPerInstance = m_data.id == TEST_ID_INDICES_INDIRECT ? 3 : 1;
3343e5c31af7Sopenharmony_ci		m_primsPerGeometry = m_data.id == TEST_ID_INDICES_INDIRECT ? 4 : 1;
3344e5c31af7Sopenharmony_ci
3345e5c31af7Sopenharmony_ci		m_numGeoms = numInstances * m_geomsPerInstance;
3346e5c31af7Sopenharmony_ci
3347e5c31af7Sopenharmony_ci		for (deUint32 i = 0; i < m_numGeoms; ++i)
3348e5c31af7Sopenharmony_ci		{
3349e5c31af7Sopenharmony_ci			std::vector<tcu::Vec3> geomPrims;
3350e5c31af7Sopenharmony_ci
3351e5c31af7Sopenharmony_ci			for (deUint32 j = 0; j < m_primsPerGeometry; ++j)
3352e5c31af7Sopenharmony_ci			{
3353e5c31af7Sopenharmony_ci				const deUint32 primId = (i * m_primsPerGeometry) + j;
3354e5c31af7Sopenharmony_ci				float dx = 10.0f * static_cast<float>(primId);
3355e5c31af7Sopenharmony_ci				if (aabb == false)
3356e5c31af7Sopenharmony_ci				{
3357e5c31af7Sopenharmony_ci					geomPrims.push_back(tcu::Vec3(dx + -1.0f, -1.0f, 1.0f));
3358e5c31af7Sopenharmony_ci					geomPrims.push_back(tcu::Vec3(dx + 1.0f, -1.0f, 1.0f));
3359e5c31af7Sopenharmony_ci					geomPrims.push_back(tcu::Vec3(dx + 0.0f, 1.0f, 1.0f));
3360e5c31af7Sopenharmony_ci				}
3361e5c31af7Sopenharmony_ci				else
3362e5c31af7Sopenharmony_ci				{
3363e5c31af7Sopenharmony_ci					geomPrims.push_back(tcu::Vec3(dx - 1.0f, -1.0f, 1.0f)); // min x/y/z
3364e5c31af7Sopenharmony_ci					geomPrims.push_back(tcu::Vec3(dx + 1.0f, 1.0f, 2.0f)); // max x/y/z
3365e5c31af7Sopenharmony_ci				}
3366e5c31af7Sopenharmony_ci			}
3367e5c31af7Sopenharmony_ci			m_geomData.push_back(geomPrims);
3368e5c31af7Sopenharmony_ci		}
3369e5c31af7Sopenharmony_ci	}
3370e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_INDIRECT || m_data.id == TEST_ID_HIT_KIND_INDIRECT)
3371e5c31af7Sopenharmony_ci	{
3372e5c31af7Sopenharmony_ci		m_geomsPerInstance = m_data.id == TEST_ID_INCOMING_RAY_FLAGS_INDIRECT ? 2 : 1;
3373e5c31af7Sopenharmony_ci		m_primsPerGeometry = 1;
3374e5c31af7Sopenharmony_ci
3375e5c31af7Sopenharmony_ci		m_numGeoms = numInstances * m_geomsPerInstance;
3376e5c31af7Sopenharmony_ci
3377e5c31af7Sopenharmony_ci		for (deUint32 i = 0; i < m_numGeoms; ++i)
3378e5c31af7Sopenharmony_ci		{
3379e5c31af7Sopenharmony_ci			std::vector<tcu::Vec3> geomPrims;
3380e5c31af7Sopenharmony_ci
3381e5c31af7Sopenharmony_ci			for (deUint32 j = 0; j < m_primsPerGeometry; ++j)
3382e5c31af7Sopenharmony_ci			{
3383e5c31af7Sopenharmony_ci				const deUint32 primId = (i * m_primsPerGeometry) + j;
3384e5c31af7Sopenharmony_ci				float z = 1.0f + 10.0f * static_cast<float>(primId);
3385e5c31af7Sopenharmony_ci
3386e5c31af7Sopenharmony_ci				bool ccw = (primId % 2) == 0;
3387e5c31af7Sopenharmony_ci
3388e5c31af7Sopenharmony_ci				if (aabb == false)
3389e5c31af7Sopenharmony_ci				{
3390e5c31af7Sopenharmony_ci					if (ccw)
3391e5c31af7Sopenharmony_ci					{
3392e5c31af7Sopenharmony_ci						geomPrims.push_back(tcu::Vec3(-1.0f, -1.0f, z));
3393e5c31af7Sopenharmony_ci						geomPrims.push_back(tcu::Vec3( 1.0f, -1.0f, z));
3394e5c31af7Sopenharmony_ci						geomPrims.push_back(tcu::Vec3( 0.0f,  1.0f, z));
3395e5c31af7Sopenharmony_ci					}
3396e5c31af7Sopenharmony_ci					else
3397e5c31af7Sopenharmony_ci					{
3398e5c31af7Sopenharmony_ci						geomPrims.push_back(tcu::Vec3( 1.0f, -1.0f, z));
3399e5c31af7Sopenharmony_ci						geomPrims.push_back(tcu::Vec3(-1.0f, -1.0f, z));
3400e5c31af7Sopenharmony_ci						geomPrims.push_back(tcu::Vec3( 0.0f,  1.0f, z));
3401e5c31af7Sopenharmony_ci					}
3402e5c31af7Sopenharmony_ci				}
3403e5c31af7Sopenharmony_ci				else
3404e5c31af7Sopenharmony_ci				{
3405e5c31af7Sopenharmony_ci					geomPrims.push_back(tcu::Vec3(-1.0f, -1.0f, z)); // min x/y/z
3406e5c31af7Sopenharmony_ci					geomPrims.push_back(tcu::Vec3( 1.0f,  1.0f, z + 1.0f)); // max x/y/z
3407e5c31af7Sopenharmony_ci				}
3408e5c31af7Sopenharmony_ci			}
3409e5c31af7Sopenharmony_ci			m_geomData.push_back(geomPrims);
3410e5c31af7Sopenharmony_ci		}
3411e5c31af7Sopenharmony_ci	}
3412e5c31af7Sopenharmony_ci
3413e5c31af7Sopenharmony_ci	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> blas;
3414e5c31af7Sopenharmony_ci
3415e5c31af7Sopenharmony_ci	if (!m_geomData.empty())
3416e5c31af7Sopenharmony_ci	{
3417e5c31af7Sopenharmony_ci		for (deUint32 i = 0; i < numInstances; ++i)
3418e5c31af7Sopenharmony_ci		{
3419e5c31af7Sopenharmony_ci			de::SharedPtr<BottomLevelAccelerationStructure>	accel = de::SharedPtr<BottomLevelAccelerationStructure>(makeBottomLevelAccelerationStructure().release());
3420e5c31af7Sopenharmony_ci			for (deUint32 j = 0; j < m_geomsPerInstance; ++j)
3421e5c31af7Sopenharmony_ci			{
3422e5c31af7Sopenharmony_ci				accel->addGeometry(m_geomData[(i * m_geomsPerInstance) + j], !aabb, 0U);
3423e5c31af7Sopenharmony_ci			}
3424e5c31af7Sopenharmony_ci			blas.push_back(accel);
3425e5c31af7Sopenharmony_ci		}
3426e5c31af7Sopenharmony_ci	}
3427e5c31af7Sopenharmony_ci	return blas;
3428e5c31af7Sopenharmony_ci}
3429e5c31af7Sopenharmony_ci
3430e5c31af7Sopenharmony_cistruct Ray
3431e5c31af7Sopenharmony_ci{
3432e5c31af7Sopenharmony_ci	Ray() : o(0.0f), tmin(0.0f), d(0.0f), tmax(0.0f){}
3433e5c31af7Sopenharmony_ci	Ray(const tcu::Vec3& io, float imin, const tcu::Vec3& id, float imax): o(io), tmin(imin), d(id), tmax(imax){}
3434e5c31af7Sopenharmony_ci	tcu::Vec3 o;
3435e5c31af7Sopenharmony_ci	float tmin;
3436e5c31af7Sopenharmony_ci	tcu::Vec3 d;
3437e5c31af7Sopenharmony_ci	float tmax;
3438e5c31af7Sopenharmony_ci};
3439e5c31af7Sopenharmony_ci
3440e5c31af7Sopenharmony_cistruct TransformResultData {
3441e5c31af7Sopenharmony_ci
3442e5c31af7Sopenharmony_ci	TransformResultData(): ray(), worldRayOrig(0.f), padding0(0.f), worldRayDir(0.f), padding1(0.f),
3443e5c31af7Sopenharmony_ci	objectRayOrig(0.f), padding2(0.f), objectRayDir(0.f), padding3(0.f), objectToWorld0(0.f), padding4(0.f),
3444e5c31af7Sopenharmony_ci	objectToWorld1(0.f), padding5(0.f), objectToWorld2(0.f), padding6(0.f), objectToWorld3(0.f), padding7(0.f),
3445e5c31af7Sopenharmony_ci	worldToObject0(0.f), padding8(0.f), worldToObject1(0.f), padding9(0.f), worldToObject2(0.f), padding10(0.f),
3446e5c31af7Sopenharmony_ci	worldToObject3(0.f), padding11(0.f), missResult(0), closestHitResult(0), anyHitResult(0), isectResult(0) {}
3447e5c31af7Sopenharmony_ci
3448e5c31af7Sopenharmony_ci	Ray ray;
3449e5c31af7Sopenharmony_ci	tcu::Vec3 worldRayOrig; float padding0;
3450e5c31af7Sopenharmony_ci	tcu::Vec3 worldRayDir; float padding1;
3451e5c31af7Sopenharmony_ci	tcu::Vec3 objectRayOrig; float padding2;
3452e5c31af7Sopenharmony_ci	tcu::Vec3 objectRayDir; float padding3;
3453e5c31af7Sopenharmony_ci	tcu::Vec3 objectToWorld0; float padding4;
3454e5c31af7Sopenharmony_ci	tcu::Vec3 objectToWorld1; float padding5;
3455e5c31af7Sopenharmony_ci	tcu::Vec3 objectToWorld2; float padding6;
3456e5c31af7Sopenharmony_ci	tcu::Vec3 objectToWorld3; float padding7;
3457e5c31af7Sopenharmony_ci	tcu::Vec3 worldToObject0; float padding8;
3458e5c31af7Sopenharmony_ci	tcu::Vec3 worldToObject1; float padding9;
3459e5c31af7Sopenharmony_ci	tcu::Vec3 worldToObject2; float padding10;
3460e5c31af7Sopenharmony_ci	tcu::Vec3 worldToObject3; float padding11;
3461e5c31af7Sopenharmony_ci	deUint32 missResult;
3462e5c31af7Sopenharmony_ci	deUint32 closestHitResult;
3463e5c31af7Sopenharmony_ci	deUint32 anyHitResult;
3464e5c31af7Sopenharmony_ci	deUint32 isectResult;
3465e5c31af7Sopenharmony_ci};
3466e5c31af7Sopenharmony_ci
3467e5c31af7Sopenharmony_cistruct TMinMaxResultData {
3468e5c31af7Sopenharmony_ci	Ray ray;
3469e5c31af7Sopenharmony_ci	float miss_maxt;
3470e5c31af7Sopenharmony_ci	float chit_maxt;
3471e5c31af7Sopenharmony_ci	float ahit_maxt;
3472e5c31af7Sopenharmony_ci	float isect_maxt;
3473e5c31af7Sopenharmony_ci	deUint32 missResult;
3474e5c31af7Sopenharmony_ci	deUint32 closestHitResult;
3475e5c31af7Sopenharmony_ci	deUint32 anyHitResult;
3476e5c31af7Sopenharmony_ci	deUint32 isectResult;
3477e5c31af7Sopenharmony_ci	float debug;
3478e5c31af7Sopenharmony_ci};
3479e5c31af7Sopenharmony_ci
3480e5c31af7Sopenharmony_cistruct IncomingFlagsResultData {
3481e5c31af7Sopenharmony_ci	Ray ray[2];
3482e5c31af7Sopenharmony_ci	deUint32 flags;
3483e5c31af7Sopenharmony_ci	deUint32 miss[2];
3484e5c31af7Sopenharmony_ci	deUint32 chit[2];
3485e5c31af7Sopenharmony_ci	deUint32 ahit[2];
3486e5c31af7Sopenharmony_ci	deUint32 isect[2];
3487e5c31af7Sopenharmony_ci};
3488e5c31af7Sopenharmony_ci
3489e5c31af7Sopenharmony_cistruct HitKindResultData {
3490e5c31af7Sopenharmony_ci	Ray ray[2];
3491e5c31af7Sopenharmony_ci	deUint32 kind[2];
3492e5c31af7Sopenharmony_ci	deUint32 chit[2];
3493e5c31af7Sopenharmony_ci	deUint32 ahit[2];
3494e5c31af7Sopenharmony_ci	deUint32 debug[2];
3495e5c31af7Sopenharmony_ci};
3496e5c31af7Sopenharmony_ci
3497e5c31af7Sopenharmony_civoid RayTracingIndirectTestInstance::initializeParameters()
3498e5c31af7Sopenharmony_ci{
3499e5c31af7Sopenharmony_ci	const VkDevice device = m_context.getDevice();
3500e5c31af7Sopenharmony_ci	const DeviceInterface& vk = m_context.getDeviceInterface();
3501e5c31af7Sopenharmony_ci	Allocator& allocator = m_context.getDefaultAllocator();
3502e5c31af7Sopenharmony_ci
3503e5c31af7Sopenharmony_ci	const bool aabb = (m_data.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR);
3504e5c31af7Sopenharmony_ci
3505e5c31af7Sopenharmony_ci	if (m_data.id == TEST_ID_INDICES_INDIRECT)
3506e5c31af7Sopenharmony_ci	{
3507e5c31af7Sopenharmony_ci		std::vector<Ray> rays;
3508e5c31af7Sopenharmony_ci		for (deUint32 g = 0; g < m_numGeoms; ++g)
3509e5c31af7Sopenharmony_ci		{
3510e5c31af7Sopenharmony_ci			for (deUint32 p = 0; p < m_primsPerGeometry; ++p)
3511e5c31af7Sopenharmony_ci			{
3512e5c31af7Sopenharmony_ci				tcu::Vec3 center = aabb ?
3513e5c31af7Sopenharmony_ci							(m_geomData[g][2 * p + 0] + m_geomData[g][2 * p + 1]) * 0.5f :
3514e5c31af7Sopenharmony_ci							(m_geomData[g][3 * p + 0] + m_geomData[g][3 * p + 1] + m_geomData[g][3 * p + 2]) * (1.0f / 3.0f);
3515e5c31af7Sopenharmony_ci
3516e5c31af7Sopenharmony_ci				Ray r;
3517e5c31af7Sopenharmony_ci
3518e5c31af7Sopenharmony_ci				r.o = tcu::Vec3(center[0], center[1], 0.0f);
3519e5c31af7Sopenharmony_ci				r.d = tcu::Vec3(0.0f, 0.0f, 1.0f);
3520e5c31af7Sopenharmony_ci				r.tmin = 0.0f;
3521e5c31af7Sopenharmony_ci				r.tmax = 1000.0f;
3522e5c31af7Sopenharmony_ci
3523e5c31af7Sopenharmony_ci				rays.push_back(r);
3524e5c31af7Sopenharmony_ci			}
3525e5c31af7Sopenharmony_ci		}
3526e5c31af7Sopenharmony_ci		const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(rays.size() * sizeof(deUint32) * 8, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3527e5c31af7Sopenharmony_ci		m_resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
3528e5c31af7Sopenharmony_ci
3529e5c31af7Sopenharmony_ci		const VkBufferCreateInfo rayBufferCreateInfo = makeBufferCreateInfo(rays.size() * sizeof(Ray), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3530e5c31af7Sopenharmony_ci		m_rayBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, rayBufferCreateInfo, MemoryRequirement::HostVisible));
3531e5c31af7Sopenharmony_ci
3532e5c31af7Sopenharmony_ci		memcpy(m_rayBuffer->getAllocation().getHostPtr(), &rays[0], rays.size() * sizeof(Ray));
3533e5c31af7Sopenharmony_ci		flushMappedMemoryRange(vk, device, m_rayBuffer->getAllocation().getMemory(), m_rayBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
3534e5c31af7Sopenharmony_ci	}
3535e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_TRANSFORMS_INDIRECT)
3536e5c31af7Sopenharmony_ci	{
3537e5c31af7Sopenharmony_ci		const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(sizeof(TransformResultData), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3538e5c31af7Sopenharmony_ci		m_resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
3539e5c31af7Sopenharmony_ci
3540e5c31af7Sopenharmony_ci		TransformResultData* resultData = (TransformResultData*)m_resultBuffer->getAllocation().getHostPtr();
3541e5c31af7Sopenharmony_ci		*resultData = {};
3542e5c31af7Sopenharmony_ci
3543e5c31af7Sopenharmony_ci		VkTransformMatrixKHR transform = identityMatrix3x4;
3544e5c31af7Sopenharmony_ci		tcu::Vec3 instanceOffset = tcu::Vec3(2.0f, 4.0f, 8.0f);
3545e5c31af7Sopenharmony_ci		transform.matrix[0][3] = instanceOffset[0];
3546e5c31af7Sopenharmony_ci		transform.matrix[1][3] = instanceOffset[1];
3547e5c31af7Sopenharmony_ci		transform.matrix[2][3] = instanceOffset[2];
3548e5c31af7Sopenharmony_ci
3549e5c31af7Sopenharmony_ci		{
3550e5c31af7Sopenharmony_ci			tcu::Vec3 center = aabb ?
3551e5c31af7Sopenharmony_ci				(m_geomData[0][0] + m_geomData[0][1]) * 0.5f :
3552e5c31af7Sopenharmony_ci				(m_geomData[0][0] + m_geomData[0][1] + m_geomData[0][2]) * (1.0f / 3.0f);
3553e5c31af7Sopenharmony_ci
3554e5c31af7Sopenharmony_ci			center = center + instanceOffset;
3555e5c31af7Sopenharmony_ci
3556e5c31af7Sopenharmony_ci			Ray r;
3557e5c31af7Sopenharmony_ci
3558e5c31af7Sopenharmony_ci			r.o = tcu::Vec3(center[0], center[1], 0.0f);
3559e5c31af7Sopenharmony_ci			r.d = tcu::Vec3(0.0f, 0.0f, 1.0f);
3560e5c31af7Sopenharmony_ci			r.tmin = 0.0f;
3561e5c31af7Sopenharmony_ci			r.tmax = 1000.0f;
3562e5c31af7Sopenharmony_ci
3563e5c31af7Sopenharmony_ci			if (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR)
3564e5c31af7Sopenharmony_ci			{
3565e5c31af7Sopenharmony_ci				r.d[2] = -1.0f;
3566e5c31af7Sopenharmony_ci			}
3567e5c31af7Sopenharmony_ci
3568e5c31af7Sopenharmony_ci			resultData->ray = r;
3569e5c31af7Sopenharmony_ci		}
3570e5c31af7Sopenharmony_ci
3571e5c31af7Sopenharmony_ci		resultData->worldRayOrig  = resultData->ray.o;
3572e5c31af7Sopenharmony_ci		resultData->worldRayDir   = resultData->ray.d;
3573e5c31af7Sopenharmony_ci		resultData->objectRayOrig = resultData->worldRayOrig - instanceOffset;
3574e5c31af7Sopenharmony_ci		resultData->objectRayDir  = resultData->worldRayDir;
3575e5c31af7Sopenharmony_ci
3576e5c31af7Sopenharmony_ci		resultData->objectToWorld0 = tcu::Vec3(transform.matrix[0][0], transform.matrix[1][0], transform.matrix[2][0]);
3577e5c31af7Sopenharmony_ci		resultData->objectToWorld1 = tcu::Vec3(transform.matrix[0][1], transform.matrix[1][1], transform.matrix[2][1]);
3578e5c31af7Sopenharmony_ci		resultData->objectToWorld2 = tcu::Vec3(transform.matrix[0][2], transform.matrix[1][2], transform.matrix[2][2]);
3579e5c31af7Sopenharmony_ci		resultData->objectToWorld3 = tcu::Vec3(transform.matrix[0][3], transform.matrix[1][3], transform.matrix[2][3]);
3580e5c31af7Sopenharmony_ci
3581e5c31af7Sopenharmony_ci		resultData->worldToObject0 = tcu::Vec3(transform.matrix[0][0], transform.matrix[0][1], transform.matrix[0][2]);
3582e5c31af7Sopenharmony_ci		resultData->worldToObject1 = tcu::Vec3(transform.matrix[1][0], transform.matrix[1][1], transform.matrix[1][2]);
3583e5c31af7Sopenharmony_ci		resultData->worldToObject2 = tcu::Vec3(transform.matrix[2][0], transform.matrix[2][1], transform.matrix[2][2]);
3584e5c31af7Sopenharmony_ci		resultData->worldToObject3 = tcu::Vec3(-transform.matrix[0][3], -transform.matrix[1][3], -transform.matrix[2][3]);
3585e5c31af7Sopenharmony_ci	}
3586e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_TMINMAX_INDIRECT)
3587e5c31af7Sopenharmony_ci	{
3588e5c31af7Sopenharmony_ci		const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(sizeof(TMinMaxResultData) * m_numGeoms * m_primsPerGeometry, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3589e5c31af7Sopenharmony_ci		m_resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
3590e5c31af7Sopenharmony_ci
3591e5c31af7Sopenharmony_ci		TMinMaxResultData* resultData = (TMinMaxResultData*)m_resultBuffer->getAllocation().getHostPtr();
3592e5c31af7Sopenharmony_ci		*resultData = {};
3593e5c31af7Sopenharmony_ci		{
3594e5c31af7Sopenharmony_ci			tcu::Vec3 center = aabb ?
3595e5c31af7Sopenharmony_ci				(m_geomData[0][0] + m_geomData[0][1]) * 0.5f :
3596e5c31af7Sopenharmony_ci				(m_geomData[0][0] + m_geomData[0][1] + m_geomData[0][2]) * (1.0f / 3.0f);
3597e5c31af7Sopenharmony_ci
3598e5c31af7Sopenharmony_ci			Ray r;
3599e5c31af7Sopenharmony_ci
3600e5c31af7Sopenharmony_ci			r.o = tcu::Vec3(center[0], center[1], 0.0f);
3601e5c31af7Sopenharmony_ci			r.d = tcu::Vec3(0.0f, 0.0f, 1.0f);
3602e5c31af7Sopenharmony_ci			r.tmin = 0.05f;
3603e5c31af7Sopenharmony_ci			r.tmax = 1000.0f;
3604e5c31af7Sopenharmony_ci
3605e5c31af7Sopenharmony_ci			if (m_data.stage == VK_SHADER_STAGE_MISS_BIT_KHR)
3606e5c31af7Sopenharmony_ci			{
3607e5c31af7Sopenharmony_ci				r.d[2] = -1.0f;
3608e5c31af7Sopenharmony_ci			}
3609e5c31af7Sopenharmony_ci
3610e5c31af7Sopenharmony_ci			resultData->ray = r;
3611e5c31af7Sopenharmony_ci		}
3612e5c31af7Sopenharmony_ci
3613e5c31af7Sopenharmony_ci		resultData->miss_maxt  = resultData->ray.tmax;
3614e5c31af7Sopenharmony_ci		resultData->isect_maxt = resultData->ray.tmax;
3615e5c31af7Sopenharmony_ci		resultData->chit_maxt  = aabb ? 1.5f : 1.0f;
3616e5c31af7Sopenharmony_ci		resultData->ahit_maxt  = aabb ? 1.5f : 1.0f;
3617e5c31af7Sopenharmony_ci		resultData->isect_maxt = resultData->ray.tmax;
3618e5c31af7Sopenharmony_ci		resultData->debug = -2.0f;
3619e5c31af7Sopenharmony_ci	}
3620e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_INDIRECT)
3621e5c31af7Sopenharmony_ci	{
3622e5c31af7Sopenharmony_ci		const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(sizeof(IncomingFlagsResultData), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3623e5c31af7Sopenharmony_ci		m_resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
3624e5c31af7Sopenharmony_ci
3625e5c31af7Sopenharmony_ci		IncomingFlagsResultData* resultData = (IncomingFlagsResultData*)m_resultBuffer->getAllocation().getHostPtr();
3626e5c31af7Sopenharmony_ci		*resultData = {};
3627e5c31af7Sopenharmony_ci
3628e5c31af7Sopenharmony_ci		for (deUint32 i = 0; i < 2; ++i)
3629e5c31af7Sopenharmony_ci		{
3630e5c31af7Sopenharmony_ci			tcu::Vec3 center = aabb ?
3631e5c31af7Sopenharmony_ci				(m_geomData[0][0] + m_geomData[0][1]) * 0.5f :
3632e5c31af7Sopenharmony_ci				(m_geomData[0][0] + m_geomData[0][1] + m_geomData[0][2]) * (1.0f / 3.0f);
3633e5c31af7Sopenharmony_ci
3634e5c31af7Sopenharmony_ci			Ray r;
3635e5c31af7Sopenharmony_ci
3636e5c31af7Sopenharmony_ci			r.o = tcu::Vec3(center[0], center[1], 0.0f);
3637e5c31af7Sopenharmony_ci			r.d = tcu::Vec3(0.0f, 0.0f, (i == 0) ? -1.0f : 1.0f);
3638e5c31af7Sopenharmony_ci			r.tmin = 0.05f;
3639e5c31af7Sopenharmony_ci			r.tmax = 1000.0f;
3640e5c31af7Sopenharmony_ci
3641e5c31af7Sopenharmony_ci			resultData->ray[i] = r;
3642e5c31af7Sopenharmony_ci		}
3643e5c31af7Sopenharmony_ci
3644e5c31af7Sopenharmony_ci		if (m_data.opaque)
3645e5c31af7Sopenharmony_ci			resultData->flags |= (1 << RAY_FLAG_BIT_OPAQUE_EXT);
3646e5c31af7Sopenharmony_ci		if (m_data.skipClosestHit)
3647e5c31af7Sopenharmony_ci			resultData->flags |= (1 << RAY_FLAG_BIT_SKIP_CLOSEST_HIT_SHADER_EXT);
3648e5c31af7Sopenharmony_ci	}
3649e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_HIT_KIND_INDIRECT)
3650e5c31af7Sopenharmony_ci	{
3651e5c31af7Sopenharmony_ci		const VkBufferCreateInfo resultBufferCreateInfo = makeBufferCreateInfo(sizeof(HitKindResultData), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
3652e5c31af7Sopenharmony_ci		m_resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));
3653e5c31af7Sopenharmony_ci
3654e5c31af7Sopenharmony_ci		HitKindResultData* resultData = (HitKindResultData*)m_resultBuffer->getAllocation().getHostPtr();
3655e5c31af7Sopenharmony_ci		*resultData = {};
3656e5c31af7Sopenharmony_ci
3657e5c31af7Sopenharmony_ci		for (deUint32 i = 0; i < 2; ++i)
3658e5c31af7Sopenharmony_ci		{
3659e5c31af7Sopenharmony_ci			tcu::Vec3 center = aabb ?
3660e5c31af7Sopenharmony_ci				(m_geomData[0][0] + m_geomData[0][1]) * 0.5f :
3661e5c31af7Sopenharmony_ci				(m_geomData[0][0] + m_geomData[0][1] + m_geomData[0][2]) * (1.0f / 3.0f);
3662e5c31af7Sopenharmony_ci
3663e5c31af7Sopenharmony_ci			Ray r;
3664e5c31af7Sopenharmony_ci
3665e5c31af7Sopenharmony_ci			r.o = tcu::Vec3(center[0], center[1], 0.0f);
3666e5c31af7Sopenharmony_ci			r.d = tcu::Vec3(0.0f, 0.0f, (i == 1) ? -1.0f : 1.0f);
3667e5c31af7Sopenharmony_ci
3668e5c31af7Sopenharmony_ci			if (i == 1)
3669e5c31af7Sopenharmony_ci				r.o += tcu::Vec3(0, 0, 100.0f);
3670e5c31af7Sopenharmony_ci
3671e5c31af7Sopenharmony_ci			r.tmin = 0.05f;
3672e5c31af7Sopenharmony_ci			r.tmax = 1000.0f;
3673e5c31af7Sopenharmony_ci
3674e5c31af7Sopenharmony_ci			resultData->ray[i] = r;
3675e5c31af7Sopenharmony_ci		}
3676e5c31af7Sopenharmony_ci
3677e5c31af7Sopenharmony_ci		resultData->kind[0] = 255;
3678e5c31af7Sopenharmony_ci		resultData->kind[1] = 254;
3679e5c31af7Sopenharmony_ci	}
3680e5c31af7Sopenharmony_ci}
3681e5c31af7Sopenharmony_ci
3682e5c31af7Sopenharmony_cibool RayTracingIndirectTestInstance::verifyResults()
3683e5c31af7Sopenharmony_ci{
3684e5c31af7Sopenharmony_ci	const bool aabb = (m_data.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR);
3685e5c31af7Sopenharmony_ci
3686e5c31af7Sopenharmony_ci	if (m_data.id == TEST_ID_INDICES_INDIRECT)
3687e5c31af7Sopenharmony_ci	{
3688e5c31af7Sopenharmony_ci		deUint32* resultData = (deUint32*)m_resultBuffer->getAllocation().getHostPtr();
3689e5c31af7Sopenharmony_ci		for (deUint32 r = 0; r < m_numGeoms * m_primsPerGeometry; ++r)
3690e5c31af7Sopenharmony_ci		{
3691e5c31af7Sopenharmony_ci			deUint32 primitiveId = r % m_primsPerGeometry;
3692e5c31af7Sopenharmony_ci			deUint32 instanceId = (r / m_primsPerGeometry) / m_geomsPerInstance;
3693e5c31af7Sopenharmony_ci			deUint32 instanceCustomIndex = 1000 + instanceId;
3694e5c31af7Sopenharmony_ci
3695e5c31af7Sopenharmony_ci			if (resultData[4 * r + 0] != primitiveId)
3696e5c31af7Sopenharmony_ci				return false;
3697e5c31af7Sopenharmony_ci
3698e5c31af7Sopenharmony_ci			if (resultData[4 * r + 2] != instanceId)
3699e5c31af7Sopenharmony_ci				return false;
3700e5c31af7Sopenharmony_ci
3701e5c31af7Sopenharmony_ci			if (resultData[4 * r + 3] != instanceCustomIndex)
3702e5c31af7Sopenharmony_ci				return false;
3703e5c31af7Sopenharmony_ci		}
3704e5c31af7Sopenharmony_ci	}
3705e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_TRANSFORMS_INDIRECT)
3706e5c31af7Sopenharmony_ci	{
3707e5c31af7Sopenharmony_ci		TransformResultData* resultData = (TransformResultData*)m_resultBuffer->getAllocation().getHostPtr();
3708e5c31af7Sopenharmony_ci		if (resultData->anyHitResult != 1 || resultData->closestHitResult != 1)
3709e5c31af7Sopenharmony_ci		{
3710e5c31af7Sopenharmony_ci			return false;
3711e5c31af7Sopenharmony_ci		}
3712e5c31af7Sopenharmony_ci
3713e5c31af7Sopenharmony_ci		if (aabb && resultData->isectResult != 1)
3714e5c31af7Sopenharmony_ci		{
3715e5c31af7Sopenharmony_ci			return false;
3716e5c31af7Sopenharmony_ci		}
3717e5c31af7Sopenharmony_ci	}
3718e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_TMINMAX_INDIRECT)
3719e5c31af7Sopenharmony_ci	{
3720e5c31af7Sopenharmony_ci		TMinMaxResultData* resultData = (TMinMaxResultData*)m_resultBuffer->getAllocation().getHostPtr();
3721e5c31af7Sopenharmony_ci		if (resultData->anyHitResult != 1 || resultData->closestHitResult != 1)
3722e5c31af7Sopenharmony_ci		{
3723e5c31af7Sopenharmony_ci			return false;
3724e5c31af7Sopenharmony_ci		}
3725e5c31af7Sopenharmony_ci
3726e5c31af7Sopenharmony_ci		if (aabb && resultData->isectResult != 1)
3727e5c31af7Sopenharmony_ci		{
3728e5c31af7Sopenharmony_ci			return false;
3729e5c31af7Sopenharmony_ci		}
3730e5c31af7Sopenharmony_ci	}
3731e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_INCOMING_RAY_FLAGS_INDIRECT)
3732e5c31af7Sopenharmony_ci	{
3733e5c31af7Sopenharmony_ci		IncomingFlagsResultData* resultData = (IncomingFlagsResultData*)m_resultBuffer->getAllocation().getHostPtr();
3734e5c31af7Sopenharmony_ci
3735e5c31af7Sopenharmony_ci		deUint32 miss[2] = { 1, 0 };
3736e5c31af7Sopenharmony_ci		deUint32 chitMin[2] = { 0, 1 };
3737e5c31af7Sopenharmony_ci		deUint32 chitMax[2] = { 0, 1 };
3738e5c31af7Sopenharmony_ci		deUint32 ahitMin[2] = { 0, 1 };
3739e5c31af7Sopenharmony_ci		deUint32 ahitMax[2] = { 0, 2 };
3740e5c31af7Sopenharmony_ci		deUint32 isectMin[2] = { 0, 0 };
3741e5c31af7Sopenharmony_ci		deUint32 isectMax[2] = { 0, 0 };
3742e5c31af7Sopenharmony_ci
3743e5c31af7Sopenharmony_ci		if (aabb)
3744e5c31af7Sopenharmony_ci		{
3745e5c31af7Sopenharmony_ci			isectMin[1] = 1;
3746e5c31af7Sopenharmony_ci			isectMax[1] = 2;
3747e5c31af7Sopenharmony_ci		}
3748e5c31af7Sopenharmony_ci
3749e5c31af7Sopenharmony_ci		if (m_data.opaque)
3750e5c31af7Sopenharmony_ci		{
3751e5c31af7Sopenharmony_ci			ahitMin[1] = 0;
3752e5c31af7Sopenharmony_ci			ahitMax[1] = 0;
3753e5c31af7Sopenharmony_ci		}
3754e5c31af7Sopenharmony_ci
3755e5c31af7Sopenharmony_ci		if (m_data.skipClosestHit)
3756e5c31af7Sopenharmony_ci		{
3757e5c31af7Sopenharmony_ci			chitMin[1] = 0;
3758e5c31af7Sopenharmony_ci			chitMax[1] = 0;
3759e5c31af7Sopenharmony_ci		}
3760e5c31af7Sopenharmony_ci
3761e5c31af7Sopenharmony_ci		for (deUint32 i = 0; i < 2; ++i)
3762e5c31af7Sopenharmony_ci		{
3763e5c31af7Sopenharmony_ci			if (resultData->miss[i] != miss[i])
3764e5c31af7Sopenharmony_ci				return false;
3765e5c31af7Sopenharmony_ci			if (resultData->chit[i] < chitMin[i])
3766e5c31af7Sopenharmony_ci				return false;
3767e5c31af7Sopenharmony_ci			if (resultData->chit[i] > chitMax[i])
3768e5c31af7Sopenharmony_ci				return false;
3769e5c31af7Sopenharmony_ci			if (resultData->ahit[i] < ahitMin[i])
3770e5c31af7Sopenharmony_ci				return false;
3771e5c31af7Sopenharmony_ci			if (resultData->ahit[i] > ahitMax[i])
3772e5c31af7Sopenharmony_ci				return false;
3773e5c31af7Sopenharmony_ci			if (resultData->isect[i] < isectMin[i])
3774e5c31af7Sopenharmony_ci				return false;
3775e5c31af7Sopenharmony_ci			if (resultData->isect[i] > isectMax[i])
3776e5c31af7Sopenharmony_ci				return false;
3777e5c31af7Sopenharmony_ci		}
3778e5c31af7Sopenharmony_ci	}
3779e5c31af7Sopenharmony_ci	else if (m_data.id == TEST_ID_HIT_KIND_INDIRECT)
3780e5c31af7Sopenharmony_ci	{
3781e5c31af7Sopenharmony_ci		HitKindResultData* resultData = (HitKindResultData*)m_resultBuffer->getAllocation().getHostPtr();
3782e5c31af7Sopenharmony_ci		for (deUint32 i = 0; i < 2; ++i)
3783e5c31af7Sopenharmony_ci		{
3784e5c31af7Sopenharmony_ci			if (resultData->chit[i] != 1)
3785e5c31af7Sopenharmony_ci				return false;
3786e5c31af7Sopenharmony_ci
3787e5c31af7Sopenharmony_ci			if (resultData->ahit[i]  != 1)
3788e5c31af7Sopenharmony_ci				return false;
3789e5c31af7Sopenharmony_ci		}
3790e5c31af7Sopenharmony_ci	}
3791e5c31af7Sopenharmony_ci	else
3792e5c31af7Sopenharmony_ci	{
3793e5c31af7Sopenharmony_ci		return false;
3794e5c31af7Sopenharmony_ci	}
3795e5c31af7Sopenharmony_ci	return true;
3796e5c31af7Sopenharmony_ci}
3797e5c31af7Sopenharmony_ci
3798e5c31af7Sopenharmony_citcu::TestStatus RayTracingIndirectTestInstance::iterate (void)
3799e5c31af7Sopenharmony_ci{
3800e5c31af7Sopenharmony_ci	const VkDevice device = m_context.getDevice();
3801e5c31af7Sopenharmony_ci	const DeviceInterface& vk = m_context.getDeviceInterface();
3802e5c31af7Sopenharmony_ci	const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3803e5c31af7Sopenharmony_ci	Allocator& allocator = m_context.getDefaultAllocator();
3804e5c31af7Sopenharmony_ci
3805e5c31af7Sopenharmony_ci	const bool aabb = (m_data.stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR);
3806e5c31af7Sopenharmony_ci
3807e5c31af7Sopenharmony_ci	vk::Move<VkDescriptorPool>		descriptorPool;
3808e5c31af7Sopenharmony_ci	vk::Move<VkDescriptorSetLayout> descriptorSetLayout;
3809e5c31af7Sopenharmony_ci	std::vector<vk::Move<VkDescriptorSet>>		descriptorSet;
3810e5c31af7Sopenharmony_ci	vk::Move<VkPipelineLayout>		pipelineLayout;
3811e5c31af7Sopenharmony_ci
3812e5c31af7Sopenharmony_ci	createPipelineLayoutAndSet(1u, descriptorPool, descriptorSetLayout, descriptorSet, pipelineLayout);
3813e5c31af7Sopenharmony_ci
3814e5c31af7Sopenharmony_ci	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>> blas = initBottomAccelerationStructures();
3815e5c31af7Sopenharmony_ci
3816e5c31af7Sopenharmony_ci	de::SharedPtr<TopLevelAccelerationStructure> tlas = initTopAccelerationStructure(blas);
3817e5c31af7Sopenharmony_ci
3818e5c31af7Sopenharmony_ci	de::MovePtr<RayTracingPipeline>	rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();
3819e5c31af7Sopenharmony_ci	Move<VkPipeline> pipeline = createPipelineAndShaderBindingTables(rayTracingPipeline, aabb, *pipelineLayout);
3820e5c31af7Sopenharmony_ci
3821e5c31af7Sopenharmony_ci	initializeParameters();
3822e5c31af7Sopenharmony_ci
3823e5c31af7Sopenharmony_ci	const VkDescriptorBufferInfo		resultDescriptorInfo			= makeDescriptorBufferInfo(m_resultBuffer->get(), 0, VK_WHOLE_SIZE);
3824e5c31af7Sopenharmony_ci
3825e5c31af7Sopenharmony_ci	const Move<VkCommandPool>			cmdPool							= createCommandPool(vk, device, 0, queueFamilyIndex);
3826e5c31af7Sopenharmony_ci	const Move<VkCommandBuffer>			cmdBuffer						= allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
3827e5c31af7Sopenharmony_ci
3828e5c31af7Sopenharmony_ci	beginCommandBuffer(vk, *cmdBuffer);
3829e5c31af7Sopenharmony_ci
3830e5c31af7Sopenharmony_ci	for (const auto& accel : blas)
3831e5c31af7Sopenharmony_ci	{
3832e5c31af7Sopenharmony_ci		accel->createAndBuild(vk, device, *cmdBuffer, allocator);
3833e5c31af7Sopenharmony_ci	}
3834e5c31af7Sopenharmony_ci	tlas->createAndBuild(vk, device, *cmdBuffer, allocator);
3835e5c31af7Sopenharmony_ci
3836e5c31af7Sopenharmony_ci	VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet	=
3837e5c31af7Sopenharmony_ci	{
3838e5c31af7Sopenharmony_ci		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
3839e5c31af7Sopenharmony_ci		DE_NULL,															//  const void*							pNext;
3840e5c31af7Sopenharmony_ci		1u,																	//  deUint32							accelerationStructureCount;
3841e5c31af7Sopenharmony_ci		tlas->getPtr(),														//  const VkAccelerationStructureKHR*	pAccelerationStructures;
3842e5c31af7Sopenharmony_ci	};
3843e5c31af7Sopenharmony_ci
3844e5c31af7Sopenharmony_ci	if (m_rayBuffer)
3845e5c31af7Sopenharmony_ci	{
3846e5c31af7Sopenharmony_ci		const VkDescriptorBufferInfo		rayDescriptorInfo				= makeDescriptorBufferInfo(m_rayBuffer->get(), 0, VK_WHOLE_SIZE);
3847e5c31af7Sopenharmony_ci
3848e5c31af7Sopenharmony_ci		DescriptorSetUpdateBuilder()
3849e5c31af7Sopenharmony_ci			.writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultDescriptorInfo)
3850e5c31af7Sopenharmony_ci			.writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
3851e5c31af7Sopenharmony_ci			.writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &rayDescriptorInfo)
3852e5c31af7Sopenharmony_ci			.update(vk, device);
3853e5c31af7Sopenharmony_ci	}
3854e5c31af7Sopenharmony_ci	else
3855e5c31af7Sopenharmony_ci	{
3856e5c31af7Sopenharmony_ci		DescriptorSetUpdateBuilder()
3857e5c31af7Sopenharmony_ci			.writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultDescriptorInfo)
3858e5c31af7Sopenharmony_ci			.writeSingle(*descriptorSet[0], DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
3859e5c31af7Sopenharmony_ci			.update(vk, device);
3860e5c31af7Sopenharmony_ci	}
3861e5c31af7Sopenharmony_ci
3862e5c31af7Sopenharmony_ci	vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipelineLayout, 0, 1, &descriptorSet[0].get(), 0, DE_NULL);
3863e5c31af7Sopenharmony_ci
3864e5c31af7Sopenharmony_ci	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *pipeline);
3865e5c31af7Sopenharmony_ci
3866e5c31af7Sopenharmony_ci	deUint32 rayCount = m_numGeoms * m_primsPerGeometry;
3867e5c31af7Sopenharmony_ci	if (m_data.id == TEST_ID_HIT_KIND_INDIRECT)
3868e5c31af7Sopenharmony_ci	{
3869e5c31af7Sopenharmony_ci		rayCount *= 2;
3870e5c31af7Sopenharmony_ci	}
3871e5c31af7Sopenharmony_ci
3872e5c31af7Sopenharmony_ci	VkAccelerationStructureBuildRangeInfoKHR buildRangeInfo = { rayCount, 1, 1, 0};
3873e5c31af7Sopenharmony_ci
3874e5c31af7Sopenharmony_ci	VkBufferCreateInfo indirectBufferCreateInfo		= makeBufferCreateInfo(sizeof(VkAccelerationStructureBuildRangeInfoKHR), VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT);
3875e5c31af7Sopenharmony_ci	de::MovePtr<BufferWithMemory> indirectBuffer	= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, indirectBufferCreateInfo, MemoryRequirement::HostVisible | MemoryRequirement::DeviceAddress));
3876e5c31af7Sopenharmony_ci
3877e5c31af7Sopenharmony_ci	deMemcpy(indirectBuffer->getAllocation().getHostPtr(), (void*)&buildRangeInfo, sizeof(VkAccelerationStructureBuildRangeInfoKHR));
3878e5c31af7Sopenharmony_ci	invalidateMappedMemoryRange(vk, device, indirectBuffer->getAllocation().getMemory(), indirectBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
3879e5c31af7Sopenharmony_ci
3880e5c31af7Sopenharmony_ci	cmdTraceRaysIndirect(vk, *cmdBuffer, &m_raygenShaderBindingTableRegion, &m_missShaderBindingTableRegion, &m_hitShaderBindingTableRegion, &m_callableShaderBindingTableRegion, getBufferDeviceAddress(vk, device, indirectBuffer->get(), 0));
3881e5c31af7Sopenharmony_ci
3882e5c31af7Sopenharmony_ci	endCommandBuffer(vk, *cmdBuffer);
3883e5c31af7Sopenharmony_ci
3884e5c31af7Sopenharmony_ci	submitCommandsAndWait(vk, device, m_context.getUniversalQueue(), *cmdBuffer);
3885e5c31af7Sopenharmony_ci
3886e5c31af7Sopenharmony_ci	invalidateMappedMemoryRange(vk, device, m_resultBuffer->getAllocation().getMemory(), m_resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);
3887e5c31af7Sopenharmony_ci
3888e5c31af7Sopenharmony_ci	return verifyResults() ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Invalid results");
3889e5c31af7Sopenharmony_ci}
3890e5c31af7Sopenharmony_ci
3891e5c31af7Sopenharmony_cistatic const struct Stages
3892e5c31af7Sopenharmony_ci{
3893e5c31af7Sopenharmony_ci	const char*				name;
3894e5c31af7Sopenharmony_ci	VkShaderStageFlagBits	stage;
3895e5c31af7Sopenharmony_ci}
3896e5c31af7Sopenharmony_cistages[]
3897e5c31af7Sopenharmony_ci{
3898e5c31af7Sopenharmony_ci	{ "rgen", VK_SHADER_STAGE_RAYGEN_BIT_KHR		},
3899e5c31af7Sopenharmony_ci	{ "ahit", VK_SHADER_STAGE_ANY_HIT_BIT_KHR		},
3900e5c31af7Sopenharmony_ci	{ "chit", VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR	},
3901e5c31af7Sopenharmony_ci	{ "sect", VK_SHADER_STAGE_INTERSECTION_BIT_KHR	},
3902e5c31af7Sopenharmony_ci	{ "miss", VK_SHADER_STAGE_MISS_BIT_KHR			},
3903e5c31af7Sopenharmony_ci	{ "call", VK_SHADER_STAGE_CALLABLE_BIT_KHR		},
3904e5c31af7Sopenharmony_ci};
3905e5c31af7Sopenharmony_ci
3906e5c31af7Sopenharmony_cistatic const struct GeomTypes
3907e5c31af7Sopenharmony_ci{
3908e5c31af7Sopenharmony_ci	const char*	name;
3909e5c31af7Sopenharmony_ci	GeomType	geomType;
3910e5c31af7Sopenharmony_ci}
3911e5c31af7Sopenharmony_cigeomTypes[] =
3912e5c31af7Sopenharmony_ci{
3913e5c31af7Sopenharmony_ci	{ "triangles",	GEOM_TYPE_TRIANGLES	},
3914e5c31af7Sopenharmony_ci	{ "aabs",		GEOM_TYPE_AABBS		},
3915e5c31af7Sopenharmony_ci};
3916e5c31af7Sopenharmony_ci
3917e5c31af7Sopenharmony_civoid createLaunchTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)
3918e5c31af7Sopenharmony_ci{
3919e5c31af7Sopenharmony_ci	const struct
3920e5c31af7Sopenharmony_ci	{
3921e5c31af7Sopenharmony_ci		deUint32	width;
3922e5c31af7Sopenharmony_ci		deUint32	height;
3923e5c31af7Sopenharmony_ci		deUint32	depth;
3924e5c31af7Sopenharmony_ci	}
3925e5c31af7Sopenharmony_ci	sizes[] =
3926e5c31af7Sopenharmony_ci	{
3927e5c31af7Sopenharmony_ci		{     1,     1,     1 },
3928e5c31af7Sopenharmony_ci		{    16,    16,    16 },
3929e5c31af7Sopenharmony_ci		{   256,   256,     1 },
3930e5c31af7Sopenharmony_ci		{ 16384,     1,     1 },
3931e5c31af7Sopenharmony_ci		{     1, 16384,     1 },
3932e5c31af7Sopenharmony_ci		{     1,     1, 16384 },
3933e5c31af7Sopenharmony_ci		{   128,   128,   128 },
3934e5c31af7Sopenharmony_ci		{  2048,  4096,     1 },
3935e5c31af7Sopenharmony_ci		{   317,  3331,     1 },
3936e5c31af7Sopenharmony_ci		{     1,  1331,   111 },
3937e5c31af7Sopenharmony_ci	};
3938e5c31af7Sopenharmony_ci
3939e5c31af7Sopenharmony_ci	de::MovePtr<tcu::TestCaseGroup>		group	(new tcu::TestCaseGroup(testCtx, de::toLower(name).c_str()));
3940e5c31af7Sopenharmony_ci
3941e5c31af7Sopenharmony_ci	for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
3942e5c31af7Sopenharmony_ci	{
3943e5c31af7Sopenharmony_ci		if ((shaderStageFlags & stages[stageNdx].stage) == 0)
3944e5c31af7Sopenharmony_ci			continue;
3945e5c31af7Sopenharmony_ci
3946e5c31af7Sopenharmony_ci		for (size_t sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizeNdx)
3947e5c31af7Sopenharmony_ci		{
3948e5c31af7Sopenharmony_ci			const deUint32	width					= sizes[sizeNdx].width;
3949e5c31af7Sopenharmony_ci			const deUint32	height					= sizes[sizeNdx].height;
3950e5c31af7Sopenharmony_ci			const deUint32	depth					= sizes[sizeNdx].depth;
3951e5c31af7Sopenharmony_ci			const bool		plain					= isPlain(width, height, depth);
3952e5c31af7Sopenharmony_ci			const deUint32	k						= (plain ? 1 : 6);
3953e5c31af7Sopenharmony_ci			const deUint32	largestGroup			= k * width * height * depth;
3954e5c31af7Sopenharmony_ci			const deUint32	squaresGroupCount		= largestGroup;
3955e5c31af7Sopenharmony_ci			const deUint32	geometriesGroupCount	= 1;
3956e5c31af7Sopenharmony_ci			const deUint32	instancesGroupCount		= 1;
3957e5c31af7Sopenharmony_ci			const CaseDef	caseDef					=
3958e5c31af7Sopenharmony_ci			{
3959e5c31af7Sopenharmony_ci				id,						//  TestId					id;
3960e5c31af7Sopenharmony_ci				name,					//  const char*				name;
3961e5c31af7Sopenharmony_ci				width,					//  deUint32				width;
3962e5c31af7Sopenharmony_ci				height,					//  deUint32				height;
3963e5c31af7Sopenharmony_ci				depth,					//  deUint32				depth;
3964e5c31af7Sopenharmony_ci				depth,					//  deUint32				raysDepth;
3965e5c31af7Sopenharmony_ci				VK_FORMAT_R32_SINT,		//  VkFormat				format;
3966e5c31af7Sopenharmony_ci				false,					//  bool					fixedPointScalarOutput;
3967e5c31af7Sopenharmony_ci				false,					//  bool					fixedPointVectorOutput;
3968e5c31af7Sopenharmony_ci				false,					//  bool					fixedPointMatrixOutput;
3969e5c31af7Sopenharmony_ci				GEOM_TYPE_TRIANGLES,	//  GeomType				geomType;
3970e5c31af7Sopenharmony_ci				squaresGroupCount,		//  deUint32				squaresGroupCount;
3971e5c31af7Sopenharmony_ci				geometriesGroupCount,	//  deUint32				geometriesGroupCount;
3972e5c31af7Sopenharmony_ci				instancesGroupCount,	//  deUint32				instancesGroupCount;
3973e5c31af7Sopenharmony_ci				stages[stageNdx].stage,	//  VkShaderStageFlagBits	stage;
3974e5c31af7Sopenharmony_ci				false,					//  bool					skipTriangles;
3975e5c31af7Sopenharmony_ci				false,					//  bool					skipAABSs;
3976e5c31af7Sopenharmony_ci				false,					//  bool					opaque;
3977e5c31af7Sopenharmony_ci				false,					//  bool					frontFace;
3978e5c31af7Sopenharmony_ci				0u,						//  VkPipelineCreateFlags	pipelineCreateFlags;
3979e5c31af7Sopenharmony_ci				false,					//	bool					useSpecConstants;
3980e5c31af7Sopenharmony_ci				false,					//	bool					skipClosestHit;
3981e5c31af7Sopenharmony_ci				false,					//  bool					useMaintenance5;
3982e5c31af7Sopenharmony_ci			};
3983e5c31af7Sopenharmony_ci			const std::string	suffix		= de::toString(caseDef.width) + '_' + de::toString(caseDef.height) + '_' + de::toString(caseDef.depth);
3984e5c31af7Sopenharmony_ci			const std::string	testName	= string(stages[stageNdx].name) + '_' + suffix;
3985e5c31af7Sopenharmony_ci
3986e5c31af7Sopenharmony_ci			group->addChild(new RayTracingTestCase(testCtx, testName.c_str(), caseDef));
3987e5c31af7Sopenharmony_ci		}
3988e5c31af7Sopenharmony_ci	}
3989e5c31af7Sopenharmony_ci
3990e5c31af7Sopenharmony_ci	builtinGroup->addChild(group.release());
3991e5c31af7Sopenharmony_ci}
3992e5c31af7Sopenharmony_ci
3993e5c31af7Sopenharmony_civoid createScalarTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)
3994e5c31af7Sopenharmony_ci{
3995e5c31af7Sopenharmony_ci	const struct
3996e5c31af7Sopenharmony_ci	{
3997e5c31af7Sopenharmony_ci		deUint32	width;
3998e5c31af7Sopenharmony_ci		deUint32	height;
3999e5c31af7Sopenharmony_ci		TestId		id;
4000e5c31af7Sopenharmony_ci	}
4001e5c31af7Sopenharmony_ci	sizes[] =
4002e5c31af7Sopenharmony_ci	{
4003e5c31af7Sopenharmony_ci		{  16,  16, TEST_ID_HIT_KIND_EXT	},
4004e5c31af7Sopenharmony_ci		{  16,  16, TEST_ID_HIT_T_EXT		},
4005e5c31af7Sopenharmony_ci		{  16,  16, TEST_ID_RAY_T_MIN_EXT	},
4006e5c31af7Sopenharmony_ci		{  16,  16, TEST_ID_RAY_T_MAX_EXT	},
4007e5c31af7Sopenharmony_ci		{  32,  32, TEST_ID_LAST			},
4008e5c31af7Sopenharmony_ci		{  64,  64, TEST_ID_LAST			},
4009e5c31af7Sopenharmony_ci		{ 256, 256, TEST_ID_LAST			},
4010e5c31af7Sopenharmony_ci	};
4011e5c31af7Sopenharmony_ci	const bool		fourGeometryGroups		=  id == TEST_ID_HIT_KIND_EXT
4012e5c31af7Sopenharmony_ci											|| id == TEST_ID_HIT_T_EXT
4013e5c31af7Sopenharmony_ci											|| id == TEST_ID_RAY_T_MIN_EXT
4014e5c31af7Sopenharmony_ci											|| id == TEST_ID_RAY_T_MAX_EXT;
4015e5c31af7Sopenharmony_ci	const bool		fixedPointScalarOutput	=  id == TEST_ID_HIT_T_EXT
4016e5c31af7Sopenharmony_ci											|| id == TEST_ID_RAY_T_MIN_EXT
4017e5c31af7Sopenharmony_ci											|| id == TEST_ID_RAY_T_MAX_EXT;
4018e5c31af7Sopenharmony_ci	const deUint32	imageDepth				= 1;
4019e5c31af7Sopenharmony_ci	const deUint32	rayDepth				= 1;
4020e5c31af7Sopenharmony_ci
4021e5c31af7Sopenharmony_ci	de::MovePtr<tcu::TestCaseGroup>		group	(new tcu::TestCaseGroup(testCtx, de::toLower(name).c_str()));
4022e5c31af7Sopenharmony_ci
4023e5c31af7Sopenharmony_ci	for (size_t geomTypesNdx = 0; geomTypesNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypesNdx)
4024e5c31af7Sopenharmony_ci	for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
4025e5c31af7Sopenharmony_ci	{
4026e5c31af7Sopenharmony_ci		const GeomType	geomType	= geomTypes[geomTypesNdx].geomType;
4027e5c31af7Sopenharmony_ci
4028e5c31af7Sopenharmony_ci		if ((shaderStageFlags & stages[stageNdx].stage) == 0)
4029e5c31af7Sopenharmony_ci			continue;
4030e5c31af7Sopenharmony_ci
4031e5c31af7Sopenharmony_ci		if (stages[stageNdx].stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR && geomTypes[geomTypesNdx].geomType == GEOM_TYPE_TRIANGLES)
4032e5c31af7Sopenharmony_ci			continue;
4033e5c31af7Sopenharmony_ci
4034e5c31af7Sopenharmony_ci		bool testAdded				= false;
4035e5c31af7Sopenharmony_ci		bool generalTestsStarted	= false;
4036e5c31af7Sopenharmony_ci
4037e5c31af7Sopenharmony_ci		for (size_t sizesNdx = 0; sizesNdx < DE_LENGTH_OF_ARRAY(sizes); ++sizesNdx)
4038e5c31af7Sopenharmony_ci		{
4039e5c31af7Sopenharmony_ci			const bool		specializedTest			= (sizes[sizesNdx].id != TEST_ID_LAST);
4040e5c31af7Sopenharmony_ci			const deUint32	width					= sizes[sizesNdx].width;
4041e5c31af7Sopenharmony_ci			const deUint32	height					= sizes[sizesNdx].height;
4042e5c31af7Sopenharmony_ci			const deUint32	instancesGroupCount		= fourGeometryGroups ? 1 : 4;
4043e5c31af7Sopenharmony_ci			const deUint32	geometriesGroupCount	= fourGeometryGroups ? 4 : 8;
4044e5c31af7Sopenharmony_ci			const deUint32	largestGroup			= width * height / geometriesGroupCount / instancesGroupCount;
4045e5c31af7Sopenharmony_ci			const deUint32	squaresGroupCount		= largestGroup;
4046e5c31af7Sopenharmony_ci			const CaseDef	caseDef					=
4047e5c31af7Sopenharmony_ci			{
4048e5c31af7Sopenharmony_ci				id,						//  TestId					id;
4049e5c31af7Sopenharmony_ci				name,					//  const char*				name;
4050e5c31af7Sopenharmony_ci				width,					//  deUint32				width;
4051e5c31af7Sopenharmony_ci				height,					//  deUint32				height;
4052e5c31af7Sopenharmony_ci				imageDepth,				//  deUint32				depth;
4053e5c31af7Sopenharmony_ci				rayDepth,				//  deUint32				raysDepth;
4054e5c31af7Sopenharmony_ci				VK_FORMAT_R32_SINT,		//  VkFormat				format;
4055e5c31af7Sopenharmony_ci				fixedPointScalarOutput,	//  bool					fixedPointScalarOutput;
4056e5c31af7Sopenharmony_ci				false,					//  bool					fixedPointVectorOutput;
4057e5c31af7Sopenharmony_ci				false,					//  bool					fixedPointMatrixOutput;
4058e5c31af7Sopenharmony_ci				geomType,				//  GeomType				geomType;
4059e5c31af7Sopenharmony_ci				squaresGroupCount,		//  deUint32				squaresGroupCount;
4060e5c31af7Sopenharmony_ci				geometriesGroupCount,	//  deUint32				geometriesGroupCount;
4061e5c31af7Sopenharmony_ci				instancesGroupCount,	//  deUint32				instancesGroupCount;
4062e5c31af7Sopenharmony_ci				stages[stageNdx].stage,	//  VkShaderStageFlagBits	stage;
4063e5c31af7Sopenharmony_ci				false,					//  bool					skipTriangles;
4064e5c31af7Sopenharmony_ci				false,					//  bool					skipAABSs;
4065e5c31af7Sopenharmony_ci				false,					//  bool					opaque;
4066e5c31af7Sopenharmony_ci				false,					//  bool					frontFace;
4067e5c31af7Sopenharmony_ci				0u,						//  VkPipelineCreateFlags	pipelineCreateFlags;
4068e5c31af7Sopenharmony_ci				false,					//	bool					useSpecConstants;
4069e5c31af7Sopenharmony_ci				false,					//	bool					skipClosestHit;
4070e5c31af7Sopenharmony_ci				false,					//  bool					useMaintenance5;
4071e5c31af7Sopenharmony_ci			};
4072e5c31af7Sopenharmony_ci			const std::string	suffix		= '_' + de::toString(caseDef.width) + '_' + de::toString(caseDef.height);
4073e5c31af7Sopenharmony_ci			const std::string	testName	= string(stages[stageNdx].name) + '_' + geomTypes[geomTypesNdx].name + (specializedTest ? "" : suffix);
4074e5c31af7Sopenharmony_ci
4075e5c31af7Sopenharmony_ci			if (specializedTest)
4076e5c31af7Sopenharmony_ci			{
4077e5c31af7Sopenharmony_ci				DE_UNREF(generalTestsStarted);
4078e5c31af7Sopenharmony_ci				DE_ASSERT(!generalTestsStarted);
4079e5c31af7Sopenharmony_ci
4080e5c31af7Sopenharmony_ci				if (sizes[sizesNdx].id != id)
4081e5c31af7Sopenharmony_ci					continue;
4082e5c31af7Sopenharmony_ci			}
4083e5c31af7Sopenharmony_ci			else
4084e5c31af7Sopenharmony_ci			{
4085e5c31af7Sopenharmony_ci				generalTestsStarted = true;
4086e5c31af7Sopenharmony_ci			}
4087e5c31af7Sopenharmony_ci
4088e5c31af7Sopenharmony_ci			group->addChild(new RayTracingTestCase(testCtx, testName.c_str(), caseDef));
4089e5c31af7Sopenharmony_ci			testAdded = true;
4090e5c31af7Sopenharmony_ci
4091e5c31af7Sopenharmony_ci			if (specializedTest)
4092e5c31af7Sopenharmony_ci				break;
4093e5c31af7Sopenharmony_ci		}
4094e5c31af7Sopenharmony_ci
4095e5c31af7Sopenharmony_ci		DE_ASSERT(testAdded);
4096e5c31af7Sopenharmony_ci		DE_UNREF(testAdded);
4097e5c31af7Sopenharmony_ci	}
4098e5c31af7Sopenharmony_ci
4099e5c31af7Sopenharmony_ci	builtinGroup->addChild(group.release());
4100e5c31af7Sopenharmony_ci}
4101e5c31af7Sopenharmony_ci
4102e5c31af7Sopenharmony_civoid createRayFlagsTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)
4103e5c31af7Sopenharmony_ci{
4104e5c31af7Sopenharmony_ci	const deUint32	width		= 16;
4105e5c31af7Sopenharmony_ci	const deUint32	height		= 16;
4106e5c31af7Sopenharmony_ci	const deUint32	imageDepth	= 1;
4107e5c31af7Sopenharmony_ci	const deUint32	rayDepth	= 1;
4108e5c31af7Sopenharmony_ci
4109e5c31af7Sopenharmony_ci	const struct Opaques
4110e5c31af7Sopenharmony_ci	{
4111e5c31af7Sopenharmony_ci		const char*	name;
4112e5c31af7Sopenharmony_ci		bool		flag;
4113e5c31af7Sopenharmony_ci	}
4114e5c31af7Sopenharmony_ci	opaques[] =
4115e5c31af7Sopenharmony_ci	{
4116e5c31af7Sopenharmony_ci		{ "opaque",		true	},
4117e5c31af7Sopenharmony_ci		{ "noopaque",	false	},
4118e5c31af7Sopenharmony_ci	};
4119e5c31af7Sopenharmony_ci	const struct Faces
4120e5c31af7Sopenharmony_ci	{
4121e5c31af7Sopenharmony_ci		const char*	name;
4122e5c31af7Sopenharmony_ci		bool		flag;
4123e5c31af7Sopenharmony_ci	}
4124e5c31af7Sopenharmony_ci	faces[] =
4125e5c31af7Sopenharmony_ci	{
4126e5c31af7Sopenharmony_ci		{ "frontface",	true	},
4127e5c31af7Sopenharmony_ci		{ "backface",	false	},
4128e5c31af7Sopenharmony_ci	};
4129e5c31af7Sopenharmony_ci	const struct SkipRayFlags
4130e5c31af7Sopenharmony_ci	{
4131e5c31af7Sopenharmony_ci		const char*	name;
4132e5c31af7Sopenharmony_ci		bool		skipTriangles;
4133e5c31af7Sopenharmony_ci		bool		skipAABBs;
4134e5c31af7Sopenharmony_ci	}
4135e5c31af7Sopenharmony_ci	skipRayFlags[] =
4136e5c31af7Sopenharmony_ci	{
4137e5c31af7Sopenharmony_ci		{ "raynoskipflags",			false,	false	},
4138e5c31af7Sopenharmony_ci		{ "rayskiptriangles",		true,	false	},
4139e5c31af7Sopenharmony_ci		{ "rayskipaabbs",			false,	true	},
4140e5c31af7Sopenharmony_ci	};
4141e5c31af7Sopenharmony_ci	const struct PipelineFlags
4142e5c31af7Sopenharmony_ci	{
4143e5c31af7Sopenharmony_ci		const char*				name;
4144e5c31af7Sopenharmony_ci		VkPipelineCreateFlags	flag;
4145e5c31af7Sopenharmony_ci	}
4146e5c31af7Sopenharmony_ci	pipelineFlags[] =
4147e5c31af7Sopenharmony_ci	{
4148e5c31af7Sopenharmony_ci		{ "pipelinenoskipflags",	static_cast<VkPipelineCreateFlags>(0)																		},
4149e5c31af7Sopenharmony_ci		{ "pipelineskiptriangles",	VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR														},
4150e5c31af7Sopenharmony_ci		{ "pipelineskipaabbs",		VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR															},
4151e5c31af7Sopenharmony_ci	};
4152e5c31af7Sopenharmony_ci
4153e5c31af7Sopenharmony_ci	de::MovePtr<tcu::TestCaseGroup>	group	(new tcu::TestCaseGroup(testCtx, de::toLower(name).c_str()));
4154e5c31af7Sopenharmony_ci
4155e5c31af7Sopenharmony_ci	for (size_t geomTypesNdx = 0; geomTypesNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypesNdx)
4156e5c31af7Sopenharmony_ci	{
4157e5c31af7Sopenharmony_ci		const GeomType					geomType	= geomTypes[geomTypesNdx].geomType;
4158e5c31af7Sopenharmony_ci		de::MovePtr<tcu::TestCaseGroup>	geomGroup	(new tcu::TestCaseGroup(testCtx, geomTypes[geomTypesNdx].name));
4159e5c31af7Sopenharmony_ci
4160e5c31af7Sopenharmony_ci		for (size_t skipRayFlagsNdx = 0; skipRayFlagsNdx < DE_LENGTH_OF_ARRAY(skipRayFlags); ++skipRayFlagsNdx)
4161e5c31af7Sopenharmony_ci		{
4162e5c31af7Sopenharmony_ci			de::MovePtr<tcu::TestCaseGroup>	rayFlagsGroup	(new tcu::TestCaseGroup(testCtx, skipRayFlags[skipRayFlagsNdx].name));
4163e5c31af7Sopenharmony_ci
4164e5c31af7Sopenharmony_ci			for (size_t pipelineFlagsNdx = 0; pipelineFlagsNdx < DE_LENGTH_OF_ARRAY(pipelineFlags); ++pipelineFlagsNdx)
4165e5c31af7Sopenharmony_ci			{
4166e5c31af7Sopenharmony_ci				const bool skipTriangles	= (skipRayFlags[skipRayFlagsNdx].skipTriangles	|| (pipelineFlags[pipelineFlagsNdx].flag & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR));
4167e5c31af7Sopenharmony_ci				const bool skipAABBs		= (skipRayFlags[skipRayFlagsNdx].skipAABBs		|| (pipelineFlags[pipelineFlagsNdx].flag & VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR));
4168e5c31af7Sopenharmony_ci
4169e5c31af7Sopenharmony_ci				// Skipping both triangles and AABBs is not legal according to the spec.
4170e5c31af7Sopenharmony_ci				if (skipTriangles && skipAABBs)
4171e5c31af7Sopenharmony_ci					continue;
4172e5c31af7Sopenharmony_ci
4173e5c31af7Sopenharmony_ci				// Skipping - SkipTrianglesKHR is mutually exclusive with CullBackFacingTrianglesKHR and CullFrontFacingTrianglesKHR
4174e5c31af7Sopenharmony_ci				if ((geomTypes[geomTypesNdx].geomType == GEOM_TYPE_TRIANGLES) && skipRayFlags[skipRayFlagsNdx].skipTriangles &&
4175e5c31af7Sopenharmony_ci					(pipelineFlags[pipelineFlagsNdx].flag == static_cast<VkPipelineCreateFlags>(0)))
4176e5c31af7Sopenharmony_ci				{
4177e5c31af7Sopenharmony_ci					continue;
4178e5c31af7Sopenharmony_ci				}
4179e5c31af7Sopenharmony_ci
4180e5c31af7Sopenharmony_ci				de::MovePtr<tcu::TestCaseGroup>	pipelineFlagsGroup	(new tcu::TestCaseGroup(testCtx, pipelineFlags[pipelineFlagsNdx].name));
4181e5c31af7Sopenharmony_ci
4182e5c31af7Sopenharmony_ci				for (size_t opaquesNdx = 0; opaquesNdx < DE_LENGTH_OF_ARRAY(opaques); ++opaquesNdx)
4183e5c31af7Sopenharmony_ci				for (size_t facesNdx = 0; facesNdx < DE_LENGTH_OF_ARRAY(faces); ++facesNdx)
4184e5c31af7Sopenharmony_ci				{
4185e5c31af7Sopenharmony_ci					const std::string				geomPropertiesGroupName	= string(opaques[opaquesNdx].name) + '_' + string(faces[facesNdx].name);
4186e5c31af7Sopenharmony_ci					de::MovePtr<tcu::TestCaseGroup>	geomPropertiesGroup		(new tcu::TestCaseGroup(testCtx, geomPropertiesGroupName.c_str()));
4187e5c31af7Sopenharmony_ci
4188e5c31af7Sopenharmony_ci					for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
4189e5c31af7Sopenharmony_ci					{
4190e5c31af7Sopenharmony_ci						if ((shaderStageFlags & stages[stageNdx].stage) == 0)
4191e5c31af7Sopenharmony_ci							continue;
4192e5c31af7Sopenharmony_ci
4193e5c31af7Sopenharmony_ci						if (stages[stageNdx].stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR && geomTypes[geomTypesNdx].geomType == GEOM_TYPE_TRIANGLES)
4194e5c31af7Sopenharmony_ci							continue;
4195e5c31af7Sopenharmony_ci
4196e5c31af7Sopenharmony_ci						const deUint32		instancesGroupCount		= 1;
4197e5c31af7Sopenharmony_ci						const deUint32		geometriesGroupCount	= 1;
4198e5c31af7Sopenharmony_ci						const deUint32		squaresGroupCount		= width * height / geometriesGroupCount / instancesGroupCount;
4199e5c31af7Sopenharmony_ci						const CaseDef		caseDef =
4200e5c31af7Sopenharmony_ci						{
4201e5c31af7Sopenharmony_ci							id,												//  TestId					id;
4202e5c31af7Sopenharmony_ci							name,											//  const char*				name;
4203e5c31af7Sopenharmony_ci							width,											//  deUint32				width;
4204e5c31af7Sopenharmony_ci							height,											//  deUint32				height;
4205e5c31af7Sopenharmony_ci							imageDepth,										//  deUint32				depth;
4206e5c31af7Sopenharmony_ci							rayDepth,										//  deUint32				raysDepth;
4207e5c31af7Sopenharmony_ci							VK_FORMAT_R32_SINT,								//  VkFormat				format;
4208e5c31af7Sopenharmony_ci							false,											//  bool					fixedPointScalarOutput;
4209e5c31af7Sopenharmony_ci							false,											//  bool					fixedPointVectorOutput;
4210e5c31af7Sopenharmony_ci							false,											//  bool					fixedPointMatrixOutput;
4211e5c31af7Sopenharmony_ci							geomType,										//  GeomType				geomType;
4212e5c31af7Sopenharmony_ci							squaresGroupCount,								//  deUint32				squaresGroupCount;
4213e5c31af7Sopenharmony_ci							geometriesGroupCount,							//  deUint32				geometriesGroupCount;
4214e5c31af7Sopenharmony_ci							instancesGroupCount,							//  deUint32				instancesGroupCount;
4215e5c31af7Sopenharmony_ci							stages[stageNdx].stage,							//  VkShaderStageFlagBits	stage;
4216e5c31af7Sopenharmony_ci							skipRayFlags[skipRayFlagsNdx].skipTriangles,	//  bool					skipTriangles;
4217e5c31af7Sopenharmony_ci							skipRayFlags[skipRayFlagsNdx].skipAABBs,		//  bool					skipAABSs;
4218e5c31af7Sopenharmony_ci							opaques[opaquesNdx].flag,						//  bool					opaque;
4219e5c31af7Sopenharmony_ci							faces[facesNdx].flag,							//  bool					frontFace;
4220e5c31af7Sopenharmony_ci							pipelineFlags[pipelineFlagsNdx].flag,			//  VkPipelineCreateFlags	pipelineCreateFlags;
4221e5c31af7Sopenharmony_ci							false,											//	bool					useSpecConstants;
4222e5c31af7Sopenharmony_ci							false,											//	bool					skipClosestHit;
4223e5c31af7Sopenharmony_ci							false,											//	bool					useMaintenance5;
4224e5c31af7Sopenharmony_ci						};
4225e5c31af7Sopenharmony_ci						const std::string	testName				= string(stages[stageNdx].name) ;
4226e5c31af7Sopenharmony_ci
4227e5c31af7Sopenharmony_ci						geomPropertiesGroup->addChild(new RayTracingTestCase(testCtx, testName.c_str(), caseDef));
4228e5c31af7Sopenharmony_ci					}
4229e5c31af7Sopenharmony_ci
4230e5c31af7Sopenharmony_ci					pipelineFlagsGroup->addChild(geomPropertiesGroup.release());
4231e5c31af7Sopenharmony_ci				}
4232e5c31af7Sopenharmony_ci
4233e5c31af7Sopenharmony_ci				rayFlagsGroup->addChild(pipelineFlagsGroup.release());
4234e5c31af7Sopenharmony_ci			}
4235e5c31af7Sopenharmony_ci
4236e5c31af7Sopenharmony_ci			geomGroup->addChild(rayFlagsGroup.release());
4237e5c31af7Sopenharmony_ci		}
4238e5c31af7Sopenharmony_ci
4239e5c31af7Sopenharmony_ci		group->addChild(geomGroup.release());
4240e5c31af7Sopenharmony_ci	}
4241e5c31af7Sopenharmony_ci
4242e5c31af7Sopenharmony_ci	{
4243e5c31af7Sopenharmony_ci		de::MovePtr<tcu::TestCaseGroup> miscGroup(new tcu::TestCaseGroup(testCtx, "misc", ""));
4244e5c31af7Sopenharmony_ci		CaseDef caseDef
4245e5c31af7Sopenharmony_ci		{
4246e5c31af7Sopenharmony_ci			TEST_ID_INCOMING_RAY_FLAGS_EXT,								//  TestId					id;
4247e5c31af7Sopenharmony_ci			name,														//  const char*				name;
4248e5c31af7Sopenharmony_ci			width,														//  deUint32				width;
4249e5c31af7Sopenharmony_ci			height,														//  deUint32				height;
4250e5c31af7Sopenharmony_ci			imageDepth,													//  deUint32				depth;
4251e5c31af7Sopenharmony_ci			rayDepth,													//  deUint32				raysDepth;
4252e5c31af7Sopenharmony_ci			VK_FORMAT_R32_SINT,											//  VkFormat				format;
4253e5c31af7Sopenharmony_ci			false,														//  bool					fixedPointScalarOutput;
4254e5c31af7Sopenharmony_ci			false,														//  bool					fixedPointVectorOutput;
4255e5c31af7Sopenharmony_ci			false,														//  bool					fixedPointMatrixOutput;
4256e5c31af7Sopenharmony_ci			GEOM_TYPE_TRIANGLES,										//  GeomType				geomType;
4257e5c31af7Sopenharmony_ci			width * height,												//  deUint32				squaresGroupCount;
4258e5c31af7Sopenharmony_ci			1,															//  deUint32				geometriesGroupCount;
4259e5c31af7Sopenharmony_ci			1,															//  deUint32				instancesGroupCount;
4260e5c31af7Sopenharmony_ci			VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,						//  VkShaderStageFlagBits	stage;
4261e5c31af7Sopenharmony_ci			false,														//  bool					skipTriangles;
4262e5c31af7Sopenharmony_ci			false,														//  bool					skipAABSs;
4263e5c31af7Sopenharmony_ci			false,														//  bool					opaque;
4264e5c31af7Sopenharmony_ci			true,														//  bool					frontFace;
4265e5c31af7Sopenharmony_ci			VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR,		//  VkPipelineCreateFlags	pipelineCreateFlags;
4266e5c31af7Sopenharmony_ci			false,														//	bool					useSpecConstants;
4267e5c31af7Sopenharmony_ci			false,														//	bool					skipClosestHit;
4268e5c31af7Sopenharmony_ci			true,														//	bool					useMaintenance5;
4269e5c31af7Sopenharmony_ci		};
4270e5c31af7Sopenharmony_ci
4271e5c31af7Sopenharmony_ci		miscGroup->addChild(new RayTracingTestCase(testCtx, "pipelineskiptriangles_maintenance5", caseDef));
4272e5c31af7Sopenharmony_ci		caseDef.pipelineCreateFlags = VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR;
4273e5c31af7Sopenharmony_ci		miscGroup->addChild(new RayTracingTestCase(testCtx, "pipelineskipaabbs_maintenance5", caseDef));
4274e5c31af7Sopenharmony_ci
4275e5c31af7Sopenharmony_ci		group->addChild(miscGroup.release());
4276e5c31af7Sopenharmony_ci	}
4277e5c31af7Sopenharmony_ci
4278e5c31af7Sopenharmony_ci	builtinGroup->addChild(group.release());
4279e5c31af7Sopenharmony_ci}
4280e5c31af7Sopenharmony_ci
4281e5c31af7Sopenharmony_civoid createMultiOutputTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup, TestId id, const char* name, const VkShaderStageFlags shaderStageFlags)
4282e5c31af7Sopenharmony_ci{
4283e5c31af7Sopenharmony_ci	const bool		fixedPointVectorOutput	=  id == TEST_ID_WORLD_RAY_ORIGIN_EXT
4284e5c31af7Sopenharmony_ci											|| id == TEST_ID_WORLD_RAY_DIRECTION_EXT
4285e5c31af7Sopenharmony_ci											|| id == TEST_ID_OBJECT_RAY_ORIGIN_EXT
4286e5c31af7Sopenharmony_ci											|| id == TEST_ID_OBJECT_RAY_DIRECTION_EXT;
4287e5c31af7Sopenharmony_ci	const bool		fixedPointMatrixOutput	=  id == TEST_ID_OBJECT_TO_WORLD_EXT
4288e5c31af7Sopenharmony_ci											|| id == TEST_ID_WORLD_TO_OBJECT_EXT
4289e5c31af7Sopenharmony_ci											|| id == TEST_ID_OBJECT_TO_WORLD_3X4_EXT
4290e5c31af7Sopenharmony_ci											|| id == TEST_ID_WORLD_TO_OBJECT_3X4_EXT;
4291e5c31af7Sopenharmony_ci	const deUint32	imageDepth				= fixedPointMatrixOutput ? 4 * 4
4292e5c31af7Sopenharmony_ci											: fixedPointVectorOutput ? 4
4293e5c31af7Sopenharmony_ci											: 0;
4294e5c31af7Sopenharmony_ci	const deUint32	rayDepth				= 1;
4295e5c31af7Sopenharmony_ci
4296e5c31af7Sopenharmony_ci	de::MovePtr<tcu::TestCaseGroup>		group	(new tcu::TestCaseGroup(testCtx, de::toLower(name).c_str()));
4297e5c31af7Sopenharmony_ci
4298e5c31af7Sopenharmony_ci	DE_ASSERT(imageDepth != 0);
4299e5c31af7Sopenharmony_ci
4300e5c31af7Sopenharmony_ci	for (size_t geomTypesNdx = 0; geomTypesNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypesNdx)
4301e5c31af7Sopenharmony_ci	for (size_t stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
4302e5c31af7Sopenharmony_ci	{
4303e5c31af7Sopenharmony_ci		const GeomType	geomType	= geomTypes[geomTypesNdx].geomType;
4304e5c31af7Sopenharmony_ci
4305e5c31af7Sopenharmony_ci		if ((shaderStageFlags & stages[stageNdx].stage) == 0)
4306e5c31af7Sopenharmony_ci			continue;
4307e5c31af7Sopenharmony_ci
4308e5c31af7Sopenharmony_ci		if (stages[stageNdx].stage == VK_SHADER_STAGE_INTERSECTION_BIT_KHR && geomTypes[geomTypesNdx].geomType == GEOM_TYPE_TRIANGLES)
4309e5c31af7Sopenharmony_ci			continue;
4310e5c31af7Sopenharmony_ci
4311e5c31af7Sopenharmony_ci		const deUint32		width					= 4;
4312e5c31af7Sopenharmony_ci		const deUint32		height					= 4;
4313e5c31af7Sopenharmony_ci		const deUint32		instancesGroupCount		= 4;
4314e5c31af7Sopenharmony_ci		const deUint32		geometriesGroupCount	= 1;
4315e5c31af7Sopenharmony_ci		const deUint32		largestGroup			= width * height / geometriesGroupCount / instancesGroupCount;
4316e5c31af7Sopenharmony_ci		const deUint32		squaresGroupCount		= largestGroup;
4317e5c31af7Sopenharmony_ci		const CaseDef		caseDef					=
4318e5c31af7Sopenharmony_ci		{
4319e5c31af7Sopenharmony_ci			id,						//  TestId					id;
4320e5c31af7Sopenharmony_ci			name,					//  const char*				name;
4321e5c31af7Sopenharmony_ci			width,					//  deUint32				width;
4322e5c31af7Sopenharmony_ci			height,					//  deUint32				height;
4323e5c31af7Sopenharmony_ci			imageDepth,				//  deUint32				depth;
4324e5c31af7Sopenharmony_ci			rayDepth,				//  deUint32				raysDepth;
4325e5c31af7Sopenharmony_ci			VK_FORMAT_R32_SINT,		//  VkFormat				format;
4326e5c31af7Sopenharmony_ci			false,					//  bool					fixedPointScalarOutput;
4327e5c31af7Sopenharmony_ci			fixedPointVectorOutput,	//  bool					fixedPointVectorOutput;
4328e5c31af7Sopenharmony_ci			fixedPointMatrixOutput,	//  bool					fixedPointMatrixOutput;
4329e5c31af7Sopenharmony_ci			geomType,				//  GeomType				geomType;
4330e5c31af7Sopenharmony_ci			squaresGroupCount,		//  deUint32				squaresGroupCount;
4331e5c31af7Sopenharmony_ci			geometriesGroupCount,	//  deUint32				geometriesGroupCount;
4332e5c31af7Sopenharmony_ci			instancesGroupCount,	//  deUint32				instancesGroupCount;
4333e5c31af7Sopenharmony_ci			stages[stageNdx].stage,	//  VkShaderStageFlagBits	stage;
4334e5c31af7Sopenharmony_ci			false,					//  bool					rayFlagSkipTriangles;
4335e5c31af7Sopenharmony_ci			false,					//  bool					rayFlagSkipAABSs;
4336e5c31af7Sopenharmony_ci			false,					//  bool					opaque;
4337e5c31af7Sopenharmony_ci			false,					//  bool					frontFace;
4338e5c31af7Sopenharmony_ci			0u,						//  VkPipelineCreateFlags	pipelineCreateFlags;
4339e5c31af7Sopenharmony_ci			false,					//	bool					useSpecConstants;
4340e5c31af7Sopenharmony_ci			false,					//	bool					skipClosestHit;
4341e5c31af7Sopenharmony_ci			false,					//	bool					useMaintenance5;
4342e5c31af7Sopenharmony_ci		};
4343e5c31af7Sopenharmony_ci		const std::string	testName				= string(stages[stageNdx].name) + '_' + geomTypes[geomTypesNdx].name;
4344e5c31af7Sopenharmony_ci
4345e5c31af7Sopenharmony_ci		group->addChild(new RayTracingTestCase(testCtx, testName.c_str(), caseDef));
4346e5c31af7Sopenharmony_ci	}
4347e5c31af7Sopenharmony_ci
4348e5c31af7Sopenharmony_ci	builtinGroup->addChild(group.release());
4349e5c31af7Sopenharmony_ci}
4350e5c31af7Sopenharmony_ci
4351e5c31af7Sopenharmony_civoid createIndirectTestCases(tcu::TestContext& testCtx, tcu::TestCaseGroup* indirectGroup, TestId id, const char* name)
4352e5c31af7Sopenharmony_ci{
4353e5c31af7Sopenharmony_ci	const struct
4354e5c31af7Sopenharmony_ci	{
4355e5c31af7Sopenharmony_ci		VkShaderStageFlagBits	stage;
4356e5c31af7Sopenharmony_ci		const char*				name;
4357e5c31af7Sopenharmony_ci	}
4358e5c31af7Sopenharmony_ci	types[] =
4359e5c31af7Sopenharmony_ci	{
4360e5c31af7Sopenharmony_ci		{ VK_SHADER_STAGE_RAYGEN_BIT_KHR,		"triangles"	},
4361e5c31af7Sopenharmony_ci		{ VK_SHADER_STAGE_INTERSECTION_BIT_KHR,	"aabbs"		},
4362e5c31af7Sopenharmony_ci	};
4363e5c31af7Sopenharmony_ci
4364e5c31af7Sopenharmony_ci	const CaseDef caseDef =
4365e5c31af7Sopenharmony_ci	{
4366e5c31af7Sopenharmony_ci		id,									//  TestId					id;
4367e5c31af7Sopenharmony_ci		"",									//  const char*				name;
4368e5c31af7Sopenharmony_ci		0,									//  deUint32				width;
4369e5c31af7Sopenharmony_ci		0,									//  deUint32				height;
4370e5c31af7Sopenharmony_ci		0,									//  deUint32				depth;
4371e5c31af7Sopenharmony_ci		0,									//  deUint32				raysDepth;
4372e5c31af7Sopenharmony_ci		VK_FORMAT_R32_SINT,					//  VkFormat				format;
4373e5c31af7Sopenharmony_ci		false,								//  bool					fixedPointScalarOutput;
4374e5c31af7Sopenharmony_ci		false,								//  bool					fixedPointVectorOutput;
4375e5c31af7Sopenharmony_ci		false,								//  bool					fixedPointMatrixOutput;
4376e5c31af7Sopenharmony_ci		GEOM_TYPE_TRIANGLES,				//  GeomType				geomType;
4377e5c31af7Sopenharmony_ci		0,									//  deUint32				squaresGroupCount;
4378e5c31af7Sopenharmony_ci		0,									//  deUint32				geometriesGroupCount;
4379e5c31af7Sopenharmony_ci		0,									//  deUint32				instancesGroupCount;
4380e5c31af7Sopenharmony_ci		VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM,	//  VkShaderStageFlagBits	stage;
4381e5c31af7Sopenharmony_ci		false,								//  bool					rayFlagSkipTriangles;
4382e5c31af7Sopenharmony_ci		false,								//  bool					rayFlagSkipAABSs;
4383e5c31af7Sopenharmony_ci		false,								//  bool					opaque;
4384e5c31af7Sopenharmony_ci		false,								//  bool					frontFace;
4385e5c31af7Sopenharmony_ci		0u,									//  VkPipelineCreateFlags	pipelineCreateFlags;
4386e5c31af7Sopenharmony_ci		false,								//	bool					useSpecConstants;
4387e5c31af7Sopenharmony_ci		false,								//	bool					skipClosestHit;
4388e5c31af7Sopenharmony_ci		false,								//	bool					useMaintenance5;
4389e5c31af7Sopenharmony_ci	};
4390e5c31af7Sopenharmony_ci
4391e5c31af7Sopenharmony_ci	de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, name));
4392e5c31af7Sopenharmony_ci
4393e5c31af7Sopenharmony_ci	for (size_t typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); ++typeNdx)
4394e5c31af7Sopenharmony_ci	{
4395e5c31af7Sopenharmony_ci		CaseDef params = caseDef;
4396e5c31af7Sopenharmony_ci		params.stage = types[typeNdx].stage;
4397e5c31af7Sopenharmony_ci		group->addChild(new RayTracingIndirectTestCase(testCtx, types[typeNdx].name, params));
4398e5c31af7Sopenharmony_ci	}
4399e5c31af7Sopenharmony_ci	indirectGroup->addChild(group.release());
4400e5c31af7Sopenharmony_ci}
4401e5c31af7Sopenharmony_ci
4402e5c31af7Sopenharmony_civoid createIndirectFlagsTestCases(tcu::TestContext& testCtx, tcu::TestCaseGroup* indirectGroup, TestId id, const char* name)
4403e5c31af7Sopenharmony_ci{
4404e5c31af7Sopenharmony_ci	const struct
4405e5c31af7Sopenharmony_ci	{
4406e5c31af7Sopenharmony_ci		VkShaderStageFlagBits	stage;
4407e5c31af7Sopenharmony_ci		const char*				name;
4408e5c31af7Sopenharmony_ci	}
4409e5c31af7Sopenharmony_ci	types[] =
4410e5c31af7Sopenharmony_ci	{
4411e5c31af7Sopenharmony_ci		{ VK_SHADER_STAGE_RAYGEN_BIT_KHR,		"triangles"	},
4412e5c31af7Sopenharmony_ci		{ VK_SHADER_STAGE_INTERSECTION_BIT_KHR,	"aabbs"		},
4413e5c31af7Sopenharmony_ci	};
4414e5c31af7Sopenharmony_ci
4415e5c31af7Sopenharmony_ci	const struct
4416e5c31af7Sopenharmony_ci	{
4417e5c31af7Sopenharmony_ci		bool			opaque;
4418e5c31af7Sopenharmony_ci		bool			skipClosestHit;
4419e5c31af7Sopenharmony_ci		const char*		name;
4420e5c31af7Sopenharmony_ci	}
4421e5c31af7Sopenharmony_ci	flags[] =
4422e5c31af7Sopenharmony_ci	{
4423e5c31af7Sopenharmony_ci		{ false,	false,	"none"				},
4424e5c31af7Sopenharmony_ci		{ true,		false,	"opaque"			},
4425e5c31af7Sopenharmony_ci		{ false,	true,	"skip_closest_hit"	},
4426e5c31af7Sopenharmony_ci	};
4427e5c31af7Sopenharmony_ci
4428e5c31af7Sopenharmony_ci	const CaseDef caseDef =
4429e5c31af7Sopenharmony_ci	{
4430e5c31af7Sopenharmony_ci		id,									//  TestId					id;
4431e5c31af7Sopenharmony_ci		"",									//  const char*				name;
4432e5c31af7Sopenharmony_ci		0,									//  deUint32				width;
4433e5c31af7Sopenharmony_ci		0,									//  deUint32				height;
4434e5c31af7Sopenharmony_ci		0,									//  deUint32				depth;
4435e5c31af7Sopenharmony_ci		0,									//  deUint32				raysDepth;
4436e5c31af7Sopenharmony_ci		VK_FORMAT_R32_SINT,					//  VkFormat				format;
4437e5c31af7Sopenharmony_ci		false,								//  bool					fixedPointScalarOutput;
4438e5c31af7Sopenharmony_ci		false,								//  bool					fixedPointVectorOutput;
4439e5c31af7Sopenharmony_ci		false,								//  bool					fixedPointMatrixOutput;
4440e5c31af7Sopenharmony_ci		GEOM_TYPE_TRIANGLES,				//  GeomType				geomType;
4441e5c31af7Sopenharmony_ci		0,									//  deUint32				squaresGroupCount;
4442e5c31af7Sopenharmony_ci		0,									//  deUint32				geometriesGroupCount;
4443e5c31af7Sopenharmony_ci		0,									//  deUint32				instancesGroupCount;
4444e5c31af7Sopenharmony_ci		VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM,	//  VkShaderStageFlagBits	stage;
4445e5c31af7Sopenharmony_ci		false,								//  bool					rayFlagSkipTriangles;
4446e5c31af7Sopenharmony_ci		false,								//  bool					rayFlagSkipAABSs;
4447e5c31af7Sopenharmony_ci		false,								//  bool					opaque;
4448e5c31af7Sopenharmony_ci		false,								//  bool					frontFace;
4449e5c31af7Sopenharmony_ci		0u,									//  VkPipelineCreateFlags	pipelineCreateFlags;
4450e5c31af7Sopenharmony_ci		false,								//	bool					useSpecConstants;
4451e5c31af7Sopenharmony_ci		false,								//	bool					skipClosestHit;
4452e5c31af7Sopenharmony_ci		false,								//	bool					useMaintenance5;
4453e5c31af7Sopenharmony_ci	};
4454e5c31af7Sopenharmony_ci
4455e5c31af7Sopenharmony_ci	de::MovePtr<tcu::TestCaseGroup> testGroup (new tcu::TestCaseGroup(testCtx, name));
4456e5c31af7Sopenharmony_ci
4457e5c31af7Sopenharmony_ci	for (size_t typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(types); ++typeNdx)
4458e5c31af7Sopenharmony_ci	{
4459e5c31af7Sopenharmony_ci		CaseDef params = caseDef;
4460e5c31af7Sopenharmony_ci		params.stage = types[typeNdx].stage;
4461e5c31af7Sopenharmony_ci		de::MovePtr<tcu::TestCaseGroup> typeGroup (new tcu::TestCaseGroup(testCtx, types[typeNdx].name));
4462e5c31af7Sopenharmony_ci
4463e5c31af7Sopenharmony_ci		for (size_t flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(flags); ++flagsNdx)
4464e5c31af7Sopenharmony_ci		{
4465e5c31af7Sopenharmony_ci			params.opaque = flags[flagsNdx].opaque;
4466e5c31af7Sopenharmony_ci			params.skipClosestHit = flags[flagsNdx].skipClosestHit;
4467e5c31af7Sopenharmony_ci			typeGroup->addChild(new RayTracingIndirectTestCase(testCtx, flags[flagsNdx].name, params));
4468e5c31af7Sopenharmony_ci		}
4469e5c31af7Sopenharmony_ci		testGroup->addChild(typeGroup.release());
4470e5c31af7Sopenharmony_ci	}
4471e5c31af7Sopenharmony_ci	indirectGroup->addChild(testGroup.release());
4472e5c31af7Sopenharmony_ci}
4473e5c31af7Sopenharmony_ci
4474e5c31af7Sopenharmony_civoid createIndirectTests (tcu::TestContext& testCtx, tcu::TestCaseGroup* builtinGroup)
4475e5c31af7Sopenharmony_ci{
4476e5c31af7Sopenharmony_ci	typedef void CreateIndirectTestsFunc (tcu::TestContext& testCtx, tcu::TestCaseGroup* group, TestId id, const char* name);
4477e5c31af7Sopenharmony_ci
4478e5c31af7Sopenharmony_ci	const struct
4479e5c31af7Sopenharmony_ci	{
4480e5c31af7Sopenharmony_ci		TestId						id;
4481e5c31af7Sopenharmony_ci		const char*					name;
4482e5c31af7Sopenharmony_ci		CreateIndirectTestsFunc*	createTestsFunc;
4483e5c31af7Sopenharmony_ci	}
4484e5c31af7Sopenharmony_ci	tests[] =
4485e5c31af7Sopenharmony_ci	{
4486e5c31af7Sopenharmony_ci		{ TEST_ID_INDICES_INDIRECT,				"indices",		createIndirectTestCases		},
4487e5c31af7Sopenharmony_ci		{ TEST_ID_TRANSFORMS_INDIRECT,			"transforms",	createIndirectTestCases			},
4488e5c31af7Sopenharmony_ci		{ TEST_ID_TMINMAX_INDIRECT,				"t_min_max",	createIndirectTestCases		},
4489e5c31af7Sopenharmony_ci		{ TEST_ID_INCOMING_RAY_FLAGS_INDIRECT,	"incoming_flag",createIndirectFlagsTestCases	},
4490e5c31af7Sopenharmony_ci		{ TEST_ID_HIT_KIND_INDIRECT,			"hit_kind",		createIndirectTestCases			},
4491e5c31af7Sopenharmony_ci	};
4492e5c31af7Sopenharmony_ci
4493e5c31af7Sopenharmony_ci	// Test builtins using indirect trace rays
4494e5c31af7Sopenharmony_ci	de::MovePtr<tcu::TestCaseGroup> indirectGroup (new tcu::TestCaseGroup(testCtx, "indirect"));
4495e5c31af7Sopenharmony_ci
4496e5c31af7Sopenharmony_ci	for (size_t testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
4497e5c31af7Sopenharmony_ci	{
4498e5c31af7Sopenharmony_ci		tests[testNdx].createTestsFunc(testCtx, indirectGroup.get(), tests[testNdx].id, tests[testNdx].name);
4499e5c31af7Sopenharmony_ci	}
4500e5c31af7Sopenharmony_ci	builtinGroup->addChild(indirectGroup.release());
4501e5c31af7Sopenharmony_ci}
4502e5c31af7Sopenharmony_ci}	// anonymous
4503e5c31af7Sopenharmony_ci
4504e5c31af7Sopenharmony_citcu::TestCaseGroup*	createBuiltinTests (tcu::TestContext& testCtx)
4505e5c31af7Sopenharmony_ci{
4506e5c31af7Sopenharmony_ci	typedef void CreateBuiltinTestsFunc (tcu::TestContext& testCtx, tcu::TestCaseGroup* group, TestId id, const char* name, const VkShaderStageFlags);
4507e5c31af7Sopenharmony_ci
4508e5c31af7Sopenharmony_ci	const VkShaderStageFlagBits	R	= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
4509e5c31af7Sopenharmony_ci	const VkShaderStageFlagBits	A	= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
4510e5c31af7Sopenharmony_ci	const VkShaderStageFlagBits	C	= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
4511e5c31af7Sopenharmony_ci	const VkShaderStageFlagBits	M	= VK_SHADER_STAGE_MISS_BIT_KHR;
4512e5c31af7Sopenharmony_ci	const VkShaderStageFlagBits	I	= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
4513e5c31af7Sopenharmony_ci	const VkShaderStageFlagBits	L	= VK_SHADER_STAGE_CALLABLE_BIT_KHR;
4514e5c31af7Sopenharmony_ci
4515e5c31af7Sopenharmony_ci	const struct
4516e5c31af7Sopenharmony_ci	{
4517e5c31af7Sopenharmony_ci		TestId					id;
4518e5c31af7Sopenharmony_ci		const char*				name;
4519e5c31af7Sopenharmony_ci		VkShaderStageFlags		stages;
4520e5c31af7Sopenharmony_ci		CreateBuiltinTestsFunc*	createBuiltinTestsFunc;
4521e5c31af7Sopenharmony_ci	}
4522e5c31af7Sopenharmony_ci	tests[] =
4523e5c31af7Sopenharmony_ci	{
4524e5c31af7Sopenharmony_ci		{ TEST_ID_LAUNCH_ID_EXT,				"LaunchIDEXT"			,	R	|	A	|	C	|	I	|	M	|	L	, createLaunchTests			},
4525e5c31af7Sopenharmony_ci		{ TEST_ID_LAUNCH_SIZE_EXT,				"LaunchSizeEXT"			,	R	|	A	|	C	|	I	|	M	|	L	, createLaunchTests			},
4526e5c31af7Sopenharmony_ci		{ TEST_ID_PRIMITIVE_ID,					"PrimitiveID"			,			A	|	C	|	I					, createScalarTests			},
4527e5c31af7Sopenharmony_ci		{ TEST_ID_INSTANCE_ID,					"InstanceID"			,			A	|	C	|	I					, createScalarTests			},
4528e5c31af7Sopenharmony_ci		{ TEST_ID_INSTANCE_CUSTOM_INDEX_EXT,	"InstanceCustomIndexEXT",			A	|	C	|	I					, createScalarTests			},
4529e5c31af7Sopenharmony_ci		{ TEST_ID_GEOMETRY_INDEX_EXT,			"GeometryIndexEXT"		,			A	|	C	|	I					, createScalarTests			},
4530e5c31af7Sopenharmony_ci		{ TEST_ID_WORLD_RAY_ORIGIN_EXT,			"WorldRayOriginEXT"		,			A	|	C	|	I	|	M			, createMultiOutputTests	},
4531e5c31af7Sopenharmony_ci		{ TEST_ID_WORLD_RAY_DIRECTION_EXT,		"WorldRayDirectionEXT"	,			A	|	C	|	I	|	M			, createMultiOutputTests	},
4532e5c31af7Sopenharmony_ci		{ TEST_ID_OBJECT_RAY_ORIGIN_EXT,		"ObjectRayOriginEXT"	,			A	|	C	|	I					, createMultiOutputTests	},
4533e5c31af7Sopenharmony_ci		{ TEST_ID_OBJECT_RAY_DIRECTION_EXT,		"ObjectRayDirectionEXT"	,			A	|	C	|	I					, createMultiOutputTests	},
4534e5c31af7Sopenharmony_ci		{ TEST_ID_RAY_T_MIN_EXT,				"RayTminEXT"			,			A	|	C	|	I	|	M			, createScalarTests			},
4535e5c31af7Sopenharmony_ci		{ TEST_ID_RAY_T_MAX_EXT,				"RayTmaxEXT"			,			A	|	C	|	I	|	M			, createScalarTests			},
4536e5c31af7Sopenharmony_ci		{ TEST_ID_INCOMING_RAY_FLAGS_EXT,		"IncomingRayFlagsEXT"	,			A	|	C	|	I	|	M			, createRayFlagsTests		},
4537e5c31af7Sopenharmony_ci		{ TEST_ID_HIT_T_EXT,					"HitTEXT"				,			A	|	C							, createScalarTests			},
4538e5c31af7Sopenharmony_ci		{ TEST_ID_HIT_KIND_EXT,					"HitKindEXT"			,			A	|	C							, createScalarTests			},
4539e5c31af7Sopenharmony_ci		{ TEST_ID_OBJECT_TO_WORLD_EXT,			"ObjectToWorldEXT"		,			A	|	C	|	I					, createMultiOutputTests	},
4540e5c31af7Sopenharmony_ci		{ TEST_ID_WORLD_TO_OBJECT_EXT,			"WorldToObjectEXT"		,			A	|	C	|	I					, createMultiOutputTests	},
4541e5c31af7Sopenharmony_ci		{ TEST_ID_OBJECT_TO_WORLD_3X4_EXT,		"ObjectToWorld3x4EXT"	,			A	|	C	|	I					, createMultiOutputTests	},
4542e5c31af7Sopenharmony_ci		{ TEST_ID_WORLD_TO_OBJECT_3X4_EXT,		"WorldToObject3x4EXT"	,			A	|	C	|	I					, createMultiOutputTests	},
4543e5c31af7Sopenharmony_ci	};
4544e5c31af7Sopenharmony_ci
4545e5c31af7Sopenharmony_ci	de::MovePtr<tcu::TestCaseGroup> builtinGroup(new tcu::TestCaseGroup(testCtx, "builtin", "Ray tracing shader builtin tests"));
4546e5c31af7Sopenharmony_ci
4547e5c31af7Sopenharmony_ci	for (size_t testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx)
4548e5c31af7Sopenharmony_ci	{
4549e5c31af7Sopenharmony_ci		tests[testNdx].createBuiltinTestsFunc(testCtx, builtinGroup.get(), tests[testNdx].id, tests[testNdx].name, tests[testNdx].stages);
4550e5c31af7Sopenharmony_ci	}
4551e5c31af7Sopenharmony_ci
4552e5c31af7Sopenharmony_ci	{
4553e5c31af7Sopenharmony_ci		createIndirectTests(testCtx, builtinGroup.get());
4554e5c31af7Sopenharmony_ci	}
4555e5c31af7Sopenharmony_ci
4556e5c31af7Sopenharmony_ci	return builtinGroup.release();
4557e5c31af7Sopenharmony_ci}
4558e5c31af7Sopenharmony_ci
4559e5c31af7Sopenharmony_citcu::TestCaseGroup* createSpecConstantTests	(tcu::TestContext& testCtx)
4560e5c31af7Sopenharmony_ci{
4561e5c31af7Sopenharmony_ci	de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "spec_constants", "Test using spec constants in ray tracing shader stages"));
4562e5c31af7Sopenharmony_ci
4563e5c31af7Sopenharmony_ci	const VkShaderStageFlags	stageFlags				= VK_SHADER_STAGE_RAYGEN_BIT_KHR
4564e5c31af7Sopenharmony_ci														| VK_SHADER_STAGE_ANY_HIT_BIT_KHR
4565e5c31af7Sopenharmony_ci														| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
4566e5c31af7Sopenharmony_ci														| VK_SHADER_STAGE_MISS_BIT_KHR
4567e5c31af7Sopenharmony_ci														| VK_SHADER_STAGE_INTERSECTION_BIT_KHR
4568e5c31af7Sopenharmony_ci														| VK_SHADER_STAGE_CALLABLE_BIT_KHR;
4569e5c31af7Sopenharmony_ci	const deUint32				width					= 256u;
4570e5c31af7Sopenharmony_ci	const deUint32				height					= 256u;
4571e5c31af7Sopenharmony_ci	const deUint32				depth					= 1u;
4572e5c31af7Sopenharmony_ci	const bool					plain					= isPlain(width, height, depth);
4573e5c31af7Sopenharmony_ci	const deUint32				k						= (plain ? 1 : 6);
4574e5c31af7Sopenharmony_ci	const deUint32				largestGroup			= k * width * height * depth;
4575e5c31af7Sopenharmony_ci	const deUint32				squaresGroupCount		= largestGroup;
4576e5c31af7Sopenharmony_ci	const deUint32				geometriesGroupCount	= 1;
4577e5c31af7Sopenharmony_ci	const deUint32				instancesGroupCount		= 1;
4578e5c31af7Sopenharmony_ci
4579e5c31af7Sopenharmony_ci	for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(stages); ++stageNdx)
4580e5c31af7Sopenharmony_ci	{
4581e5c31af7Sopenharmony_ci		if ((stageFlags & stages[stageNdx].stage) == 0)
4582e5c31af7Sopenharmony_ci			continue;
4583e5c31af7Sopenharmony_ci
4584e5c31af7Sopenharmony_ci		const CaseDef caseDef =
4585e5c31af7Sopenharmony_ci		{
4586e5c31af7Sopenharmony_ci			TEST_ID_LAUNCH_ID_EXT,	//  TestId					id;
4587e5c31af7Sopenharmony_ci			"LaunchIDEXT",			//  const char*				name;
4588e5c31af7Sopenharmony_ci			width,					//  deUint32				width;
4589e5c31af7Sopenharmony_ci			height,					//  deUint32				height;
4590e5c31af7Sopenharmony_ci			depth,					//  deUint32				depth;
4591e5c31af7Sopenharmony_ci			depth,					//  deUint32				raysDepth;
4592e5c31af7Sopenharmony_ci			VK_FORMAT_R32_SINT,		//  VkFormat				format;
4593e5c31af7Sopenharmony_ci			false,					//  bool					fixedPointScalarOutput;
4594e5c31af7Sopenharmony_ci			false,					//  bool					fixedPointVectorOutput;
4595e5c31af7Sopenharmony_ci			false,					//  bool					fixedPointMatrixOutput;
4596e5c31af7Sopenharmony_ci			GEOM_TYPE_TRIANGLES,	//  GeomType				geomType;
4597e5c31af7Sopenharmony_ci			squaresGroupCount,		//  deUint32				squaresGroupCount;
4598e5c31af7Sopenharmony_ci			geometriesGroupCount,	//  deUint32				geometriesGroupCount;
4599e5c31af7Sopenharmony_ci			instancesGroupCount,	//  deUint32				instancesGroupCount;
4600e5c31af7Sopenharmony_ci			stages[stageNdx].stage,	//  VkShaderStageFlagBits	stage;
4601e5c31af7Sopenharmony_ci			false,					//  bool					skipTriangles;
4602e5c31af7Sopenharmony_ci			false,					//  bool					skipAABSs;
4603e5c31af7Sopenharmony_ci			false,					//  bool					opaque;
4604e5c31af7Sopenharmony_ci			false,					//  bool					frontFace;
4605e5c31af7Sopenharmony_ci			0u,						//  VkPipelineCreateFlags	pipelineCreateFlags;
4606e5c31af7Sopenharmony_ci			true,					//	bool					useSpecConstants;
4607e5c31af7Sopenharmony_ci			false,					//	bool					skipClosestHit;
4608e5c31af7Sopenharmony_ci			false,					//	bool					useMaintenance5;
4609e5c31af7Sopenharmony_ci		};
4610e5c31af7Sopenharmony_ci
4611e5c31af7Sopenharmony_ci		group->addChild(new RayTracingTestCase(testCtx, stages[stageNdx].name, caseDef));
4612e5c31af7Sopenharmony_ci	}
4613e5c31af7Sopenharmony_ci
4614e5c31af7Sopenharmony_ci	return group.release();
4615e5c31af7Sopenharmony_ci}
4616e5c31af7Sopenharmony_ci
4617e5c31af7Sopenharmony_ci}	// RayTracing
4618e5c31af7Sopenharmony_ci}	// vkt
4619