/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2020 The Khronos Group Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *	  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Ray Query Builtin tests
 *//*--------------------------------------------------------------------*/

#include "vktRayQueryWatertightnessTests.hpp"

#include "vkDefs.hpp"

#include "vktTestCase.hpp"
#include "vktTestGroupUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkBuilderUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vkBufferWithMemory.hpp"
#include "vkImageWithMemory.hpp"
#include "vkTypeUtil.hpp"
#include "vkImageUtil.hpp"
#include "deRandom.hpp"
#include "tcuTexture.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuTestLog.hpp"
#include "tcuImageCompare.hpp"
#include "tcuCommandLine.hpp"

#include "vkRayTracingUtil.hpp"

namespace vkt
{
namespace RayQuery
{
namespace
{
using namespace vk;
using namespace vkt;

static const VkFlags	ALL_RAY_TRACING_STAGES	= VK_SHADER_STAGE_RAYGEN_BIT_KHR
												| VK_SHADER_STAGE_ANY_HIT_BIT_KHR
												| VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR
												| VK_SHADER_STAGE_MISS_BIT_KHR
												| VK_SHADER_STAGE_INTERSECTION_BIT_KHR
												| VK_SHADER_STAGE_CALLABLE_BIT_KHR;

enum TestType
{
	TEST_TYPE_NO_MISS		= 0,
	TEST_TYPE_SINGLE_HIT,
};

enum GeomType
{
	GEOM_TYPE_TRIANGLES,
	GEOM_TYPE_AABBS,
	GEOM_TYPE_LAST,
};

const deUint32	TEST_WIDTH					= 256u;
const deUint32	TEST_HEIGHT					= 256u;
const float		MIN_AABB_SIDE_LENGTH		= 1e-6f;
const float		MIN_TRIANGLE_EDGE_LENGTH	= 1.0f / float(10 * TEST_WIDTH * TEST_HEIGHT);
const float		MIN_TRIANGLE_AREA_SIZE		= 1.0f / float(10 * TEST_WIDTH * TEST_HEIGHT);

struct TestParams;

typedef void (*CheckSupportFunc)(Context& context, const TestParams& testParams);
typedef void (*InitProgramsFunc)(SourceCollections& programCollection, const TestParams& testParams);
typedef const std::string (*ShaderBodyTextFunc)(const TestParams& testParams);

class PipelineConfiguration
{
public:
					PipelineConfiguration	()	{};
	virtual			~PipelineConfiguration	()	{};

	virtual void	initConfiguration	(Context&							context,
										 TestParams&						testParams) = 0;
	virtual void	fillCommandBuffer	(Context&							context,
										 TestParams&						testParams,
										 VkCommandBuffer					commandBuffer,
										 const VkAccelerationStructureKHR*	rayQueryTopAccelerationStructurePtr,
										 const VkDescriptorImageInfo&		resultImageInfo) = 0;
};

class TestConfiguration
{
public:
																	TestConfiguration				()
																		: m_bottomAccelerationStructures	()
																		, m_topAccelerationStructure		()
																		, m_expected						()
																	{
																	}
	virtual															~TestConfiguration				()
																	{
																	}

	virtual const VkAccelerationStructureKHR*						initAccelerationStructures		(Context&							context,
																									 TestParams&						testParams,
																									 VkCommandBuffer					cmdBuffer) = 0;
	virtual bool													verify							(BufferWithMemory*					resultBuffer,
																									 Context&							context,
																									 TestParams&						testParams) = 0;

protected:
	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	m_bottomAccelerationStructures;
	de::SharedPtr<TopLevelAccelerationStructure>					m_topAccelerationStructure;
	std::vector<deInt32>											m_expected;
};

struct TestParams
{
	deUint32				width;
	deUint32				height;
	deUint32				depth;
	deUint32				randomSeed;
	TestType				testType;
	VkShaderStageFlagBits	stage;
	GeomType				geomType;
	deUint32				squaresGroupCount;
	deUint32				geometriesGroupCount;
	deUint32				instancesGroupCount;
	VkFormat				format;
	CheckSupportFunc		pipelineCheckSupport;
	InitProgramsFunc		pipelineInitPrograms;
	ShaderBodyTextFunc		testConfigShaderBodyText;
};

deUint32 getShaderGroupHandleSize (const InstanceInterface&	vki,
								   const VkPhysicalDevice	physicalDevice)
{
	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;

	rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physicalDevice);

	return rayTracingPropertiesKHR->getShaderGroupHandleSize();
}

deUint32 getShaderGroupBaseAlignment (const InstanceInterface&	vki,
									  const VkPhysicalDevice	physicalDevice)
{
	de::MovePtr<RayTracingProperties>	rayTracingPropertiesKHR;

	rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);

	return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
}

VkBuffer getVkBuffer (const de::MovePtr<BufferWithMemory>& buffer)
{
	VkBuffer result = (buffer.get() == DE_NULL) ? DE_NULL : buffer->get();

	return result;
}

VkStridedDeviceAddressRegionKHR makeStridedDeviceAddressRegion (const DeviceInterface& vkd, const VkDevice device, VkBuffer buffer, VkDeviceSize size)
{
	const VkDeviceSize sizeFixed = ((buffer == DE_NULL) ? 0ull : size);

	return makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, buffer, 0), sizeFixed, sizeFixed);
}

VkImageCreateInfo makeImageCreateInfo (VkFormat				format,
									   deUint32				width,
									   deUint32				height,
									   deUint32				depth,
									   VkImageType			imageType	= VK_IMAGE_TYPE_3D,
									   VkImageUsageFlags	usageFlags	= VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT)
{
	const VkImageCreateInfo	imageCreateInfo	=
	{
		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType;
		DE_NULL,								// const void*				pNext;
		(VkImageCreateFlags)0u,					// VkImageCreateFlags		flags;
		imageType,								// VkImageType				imageType;
		format,									// VkFormat					format;
		makeExtent3D(width, height, depth),		// VkExtent3D				extent;
		1u,										// deUint32					mipLevels;
		1u,										// deUint32					arrayLayers;
		VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples;
		VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling;
		usageFlags,								// VkImageUsageFlags		usage;
		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode;
		0u,										// deUint32					queueFamilyIndexCount;
		DE_NULL,								// const deUint32*			pQueueFamilyIndices;
		VK_IMAGE_LAYOUT_UNDEFINED				// VkImageLayout			initialLayout;
	};

	return imageCreateInfo;
}

Move<VkPipeline> makeComputePipeline (const DeviceInterface&		vk,
									  const VkDevice				device,
									  const VkPipelineLayout		pipelineLayout,
									  const VkShaderModule			shaderModule)
{
	const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
		DE_NULL,												// const void*							pNext;
		0u,														// VkPipelineShaderStageCreateFlags		flags;
		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
		shaderModule,											// VkShaderModule						module;
		"main",													// const char*							pName;
		DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
	};
	const VkComputePipelineCreateInfo pipelineCreateInfo =
	{
		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
		DE_NULL,											// const void*						pNext;
		0u,													// VkPipelineCreateFlags			flags;
		pipelineShaderStageParams,							// VkPipelineShaderStageCreateInfo	stage;
		pipelineLayout,										// VkPipelineLayout					layout;
		DE_NULL,											// VkPipeline						basePipelineHandle;
		0,													// deInt32							basePipelineIndex;
	};

	return createComputePipeline(vk, device, DE_NULL , &pipelineCreateInfo);
}

static const std::string getMissPassthrough (void)
{
	const std::string missPassthrough =
		"#version 460 core\n"
		"#extension GL_EXT_ray_tracing : require\n"
		"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
		"\n"
		"void main()\n"
		"{\n"
		"}\n";

	return missPassthrough;
}

static const std::string getHitPassthrough (void)
{
	const std::string hitPassthrough =
		"#version 460 core\n"
		"#extension GL_EXT_ray_tracing : require\n"
		"hitAttributeEXT vec3 attribs;\n"
		"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
		"\n"
		"void main()\n"
		"{\n"
		"}\n";

	return hitPassthrough;
}

static const std::string getGraphicsPassthrough (void)
{
	std::ostringstream src;

	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
		<< "\n"
		<< "void main(void)\n"
		<< "{\n"
		<< "}\n";

	return src.str();
}

static const std::string getVertexPassthrough (void)
{
	std::ostringstream src;

	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
		<< "\n"
		<< "layout(location = 0) in vec4 in_position;\n"
		<< "\n"
		<< "void main(void)\n"
		<< "{\n"
		<< "  gl_Position = in_position;\n"
		<< "}\n";

	return src.str();
}

static inline tcu::Vec2 mixVec2 (const tcu::Vec2& a, const tcu::Vec2& b, const float alpha)
{
	const tcu::Vec2 result = a * alpha + b * (1.0f - alpha);

	return result;
}

static inline tcu::Vec2 mixCoordsVec2 (const tcu::Vec2& a, const tcu::Vec2& b, const float alpha, const float beta)
{
	const tcu::Vec2	result	= tcu::Vec2(deFloatMix(a.x(), b.x(), alpha), deFloatMix(a.y(), b.y(), beta));

	return result;
}

inline float triangleEdgeLength (const tcu::Vec2& vertexA, const tcu::Vec2& vertexB)
{
	const float	abx	= vertexA.x() - vertexB.x();
	const float	aby	= vertexA.y() - vertexB.y();
	const float abq	= abx * abx + aby * aby;
	const float	ab	= deFloatSqrt(abq);

	return ab;
}

inline float triangleArea (const float edgeALen, const float edgeBLen, const float edgeCLen)
{
	const float	s	= (edgeALen + edgeBLen + edgeCLen) / 2.0f;
	const float	q	= s * (s - edgeALen) * (s - edgeBLen) * (s - edgeCLen);

	if (q <= 0.0f)
		return 0.0f;

	return deFloatSqrt(q);
}

class GraphicsConfiguration : public PipelineConfiguration
{
public:
	static void						checkSupport			(Context&							context,
															 const TestParams&					testParams);
	static void						initPrograms			(SourceCollections&					programCollection,
															 const TestParams&					testParams);

									GraphicsConfiguration	();
	virtual							~GraphicsConfiguration	() {};

	void							initVertexBuffer		(Context&							context,
															 TestParams&						testParams);
	Move<VkPipeline>				makeGraphicsPipeline	(Context&							context,
															 TestParams&						testParams);
	virtual void					initConfiguration		(Context&							context,
															 TestParams&						testParams) override;
	virtual void					fillCommandBuffer		(Context&							context,
															 TestParams&						testParams,
															 VkCommandBuffer					commandBuffer,
															 const VkAccelerationStructureKHR*	rayQueryTopAccelerationStructurePtr,
															 const VkDescriptorImageInfo&		resultImageInfo) override;

private:
	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
	Move<VkDescriptorPool>			m_descriptorPool;
	Move<VkDescriptorSet>			m_descriptorSet;

	VkFormat						m_framebufferFormat;
	Move<VkImage>					m_framebufferImage;
	de::MovePtr<Allocation>			m_framebufferImageAlloc;
	Move<VkImageView>				m_framebufferAttachment;

	Move<VkShaderModule>			m_vertShaderModule;
	Move<VkShaderModule>			m_geomShaderModule;
	Move<VkShaderModule>			m_tescShaderModule;
	Move<VkShaderModule>			m_teseShaderModule;
	Move<VkShaderModule>			m_fragShaderModule;

	Move<VkRenderPass>				m_renderPass;
	Move<VkFramebuffer>				m_framebuffer;
	Move<VkPipelineLayout>			m_pipelineLayout;
	Move<VkPipeline>				m_pipeline;

	deUint32						m_vertexCount;
	Move<VkBuffer>					m_vertexBuffer;
	de::MovePtr<Allocation>			m_vertexBufferAlloc;
};

GraphicsConfiguration::GraphicsConfiguration()
	: PipelineConfiguration		()
	, m_descriptorSetLayout		()
	, m_descriptorPool			()
	, m_descriptorSet			()
	, m_framebufferFormat		(VK_FORMAT_R8G8B8A8_UNORM)
	, m_framebufferImage		()
	, m_framebufferImageAlloc	()
	, m_framebufferAttachment	()
	, m_vertShaderModule		()
	, m_geomShaderModule		()
	, m_tescShaderModule		()
	, m_teseShaderModule		()
	, m_fragShaderModule		()
	, m_renderPass				()
	, m_framebuffer				()
	, m_pipelineLayout			()
	, m_pipeline				()
	, m_vertexCount				(0)
	, m_vertexBuffer			()
	, m_vertexBufferAlloc		()
{
}

void GraphicsConfiguration::checkSupport (Context&			context,
										  const TestParams&	testParams)
{
	switch (testParams.stage)
	{
		case VK_SHADER_STAGE_VERTEX_BIT:
			break;

		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
		{
			context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);

			break;
		}

		case VK_SHADER_STAGE_GEOMETRY_BIT:
		{
			context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);

			break;
		}

		case VK_SHADER_STAGE_FRAGMENT_BIT:
			break;

		default:
			TCU_THROW(InternalError, "Unknown stage");
	}
}

void GraphicsConfiguration::initPrograms (SourceCollections&	programCollection,
										  const TestParams&		testParams)
{
	const vk::ShaderBuildOptions	buildOptions	(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
	const std::string				testShaderBody	= testParams.testConfigShaderBodyText(testParams);

	switch (testParams.stage)
	{
		case VK_SHADER_STAGE_VERTEX_BIT:
		{
			{
				std::ostringstream src;
				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_ray_query : require\n"
					<< "#extension GL_EXT_ray_tracing : require\n"
					<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
					<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
					<< "\n"
					<< "void testFunc(ivec3 pos, ivec3 size)\n"
					<< "{\n"
					<< testShaderBody
					<< "}\n"
					<< "\n"
					<< "void main(void)\n"
					<< "{\n"
					<< "  const int   posId    = int(gl_VertexIndex / 3);\n"
					<< "  const int   vertId   = int(gl_VertexIndex % 3);\n"
					<< "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
					<< "  const ivec3 pos      = ivec3(posId % size.x, posId / size.x, 0);\n"
					<< "\n"
					<< "  if (vertId == 0)\n"
					<< "  {\n"
					<< "    testFunc(pos, size);\n"
					<< "  }\n"
					<< "}\n";

				programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
			}

			programCollection.glslSources.add("frag") << glu::FragmentSource(getGraphicsPassthrough()) << buildOptions;

			break;
		}

		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
		{
			{
				std::ostringstream src;
				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "\n"
					<< "layout(location = 0) in vec4 in_position;\n"
					<< "out gl_PerVertex\n"
					<< "{\n"
					<< "  vec4 gl_Position;\n"
					<< "};\n"
					<< "\n"
					<< "void main(void)\n"
					<< "{\n"
					<< "  gl_Position = in_position;\n"
					<< "}\n";

				programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
			}

			{
				std::ostringstream src;
				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_tessellation_shader : require\n"
					<< "#extension GL_EXT_ray_query : require\n"
					<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
					<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
					<< "in gl_PerVertex\n"
					<< "{\n"
					<< "  vec4 gl_Position;\n"
					<< "} gl_in[];\n"
					<< "layout(vertices = 3) out;\n"
					<< "out gl_PerVertex\n"
					<< "{\n"
					<< "  vec4 gl_Position;\n"
					<< "} gl_out[];\n"
					<< "\n"
					<< "void testFunc(ivec3 pos, ivec3 size)\n"
					<< "{\n"
					<< testShaderBody
					<< "}\n"
					<< "\n"
					<< "void main(void)\n"
					<< "{\n"
					<< "\n"
					<< "  if (gl_InvocationID == 0)\n"
					<< "  {\n"
					<< "    const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
					<< "    int index = int(gl_in[gl_InvocationID].gl_Position.z);\n"
					<< "    int x = index % size.x;\n"
					<< "    int y = index / size.y;\n"
					<< "    const ivec3 pos = ivec3(x, y, 0);\n"
					<< "    testFunc(pos, size);\n"
					<< "  }\n"
					<< "\n"
					<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
					<< "  gl_TessLevelInner[0] = 1;\n"
					<< "  gl_TessLevelInner[1] = 1;\n"
					<< "  gl_TessLevelOuter[gl_InvocationID] = 1;\n"
					<< "}\n";

				programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions;
			}

			{
				std::ostringstream src;
				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_tessellation_shader : require\n"
					<< "layout(triangles, equal_spacing, ccw) in;\n"
					<< "in gl_PerVertex\n"
					<< "{\n"
					<< "  vec4 gl_Position;\n"
					<< "} gl_in[];\n"
					<< "\n"
					<< "void main(void)\n"
					<< "{\n"
					<< "  gl_Position = gl_in[0].gl_Position;\n"
					<< "}\n";

				programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions;
			}

			break;
		}

		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
		{
			{
				std::ostringstream src;
				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "\n"
					<< "layout(location = 0) in vec4 in_position;\n"
					<< "out gl_PerVertex"
					<< "{\n"
					<< "  vec4 gl_Position;\n"
					<< "};\n"
					<< "\n"
					<< "void main(void)\n"
					<< "{\n"
					<< "  gl_Position = in_position;\n"
					<< "}\n";

				programCollection.glslSources.add("vert") << glu::VertexSource(src.str()) << buildOptions;
			}

			{
				std::ostringstream src;
				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_tessellation_shader : require\n"
					<< "in gl_PerVertex\n"
					<< "{\n"
					<< "  vec4 gl_Position;\n"
					<< "} gl_in[];\n"
					<< "layout(vertices = 3) out;\n"
					<< "out gl_PerVertex\n"
					<< "{\n"
					<< "  vec4 gl_Position;\n"
					<< "} gl_out[];\n"
					<< "\n"
					<< "void main(void)\n"
					<< "{\n"
					<< "  gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
					<< "  gl_TessLevelInner[0] = 1;\n"
					<< "  gl_TessLevelInner[1] = 1;\n"
					<< "  gl_TessLevelOuter[gl_InvocationID] = 1;\n"
					<< "}\n";

				programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()) << buildOptions;
			}

			{
				std::ostringstream src;
				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_tessellation_shader : require\n"
					<< "#extension GL_EXT_ray_query : require\n"
					<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
					<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
					<< "layout(triangles, equal_spacing, ccw) in;\n"
					<< "in gl_PerVertex\n"
					<< "{\n"
					<< "  vec4 gl_Position;\n"
					<< "} gl_in[];\n"
					<< "\n"
					<< "void testFunc(ivec3 pos, ivec3 size)\n"
					<< "{\n"
					<< testShaderBody
					<< "}\n"
					<< "\n"
					<< "void main(void)\n"
					<< "{\n"
					<< "	const ivec3 size = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
					<< "	int index = int(gl_in[0].gl_Position.z);\n"
					<< "	int x = index % size.x;\n"
					<< "	int y = index / size.y;\n"
					<< "	const ivec3 pos = ivec3(x, y, 0);\n"
					<< "	testFunc(pos, size);\n"
					<< "	gl_Position = gl_in[0].gl_Position;\n"
					<< "}\n";

				programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()) << buildOptions;
			}

			break;
		}

		case VK_SHADER_STAGE_GEOMETRY_BIT:
		{
			programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions;

			{
				std::ostringstream src;
				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_ray_query : require\n"
					<< "layout(triangles) in;\n"
					<< "layout(points, max_vertices = 1) out;\n"
					<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
					<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
					<< "\n"
					<< "void testFunc(ivec3 pos, ivec3 size)\n"
					<< "{\n"
					<< testShaderBody
					<< "}\n"
					<< "\n"
					<< "void main(void)\n"
					<< "{\n"
					<< "  const int   posId    = int(gl_PrimitiveIDIn);\n"
					<< "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
					<< "  const ivec3 pos      = ivec3(posId % size.x, posId / size.x, 0);\n"
					<< "\n"
					<< "  testFunc(pos, size);\n"
					<< "}\n";

				programCollection.glslSources.add("geom") << glu::GeometrySource(src.str()) << buildOptions;
			}

			break;
		}

		case VK_SHADER_STAGE_FRAGMENT_BIT:
		{
			programCollection.glslSources.add("vert") << glu::VertexSource(getVertexPassthrough()) << buildOptions;

			{
				std::ostringstream src;
				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_ray_query : require\n"
					<< "layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
					<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
					<< "\n"
					<< "void testFunc(ivec3 pos, ivec3 size)\n"
					<< "{\n"
					<< testShaderBody
					<< "}\n"
					<< "\n"
					<< "void main(void)\n"
					<< "{\n"
					<< "  const ivec3 size     = ivec3(" << testParams.width << ", " << testParams.height << ", 1);\n"
					<< "  const ivec3 pos      = ivec3(int(gl_FragCoord.x - 0.5f), int(gl_FragCoord.y - 0.5f), 0);\n"
					<< "\n"
					<< "  testFunc(pos, size);\n"
					<< "}\n";

				programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()) << buildOptions;
			}

			break;
		}

		default:
			TCU_THROW(InternalError, "Unknown stage");
	}
}

void GraphicsConfiguration::initVertexBuffer (Context&		context,
											  TestParams&	testParams)
{
	const DeviceInterface&	vkd			= context.getDeviceInterface();
	const VkDevice			device		= context.getDevice();
	const deUint32			width		= testParams.width;
	const deUint32			height		= testParams.height;
	Allocator&				allocator	= context.getDefaultAllocator();
	std::vector<tcu::Vec4>	vertices;

	switch (testParams.stage)
	{
		case VK_SHADER_STAGE_VERTEX_BIT:
		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
		{
			float z = 0.0f;
			const float w = 1.0f;

			vertices.reserve(3 * height * width);

			for (deUint32 y = 0; y < height; ++y)
			for (deUint32 x = 0; x < width; ++x)
			{
				const float	x0	= float(x + 0) / float(width);
				const float	y0	= float(y + 0) / float(height);
				const float	x1	= float(x + 1) / float(width);
				const float	y1	= float(y + 1) / float(height);
				const float	xm	= (x0 + x1) / 2.0f;
				const float	ym	= (y0 + y1) / 2.0f;

				vertices.push_back(tcu::Vec4(x0, y0, z, w));
				vertices.push_back(tcu::Vec4(xm, y1, z, w));
				vertices.push_back(tcu::Vec4(x1, ym, z, w));

				z += 1.f;
			}

			break;
		}

		case VK_SHADER_STAGE_GEOMETRY_BIT:
		{
			const float z = 0.0f;
			const float w = 1.0f;

			vertices.reserve(3 * height * width);

			for (deUint32 y = 0; y < height; ++y)
			for (deUint32 x = 0; x < width; ++x)
			{
				const float	x0	= float(x + 0) / float(width);
				const float	y0	= float(y + 0) / float(height);
				const float	x1	= float(x + 1) / float(width);
				const float	y1	= float(y + 1) / float(height);
				const float	xm	= (x0 + x1) / 2.0f;
				const float	ym	= (y0 + y1) / 2.0f;

				vertices.push_back(tcu::Vec4(x0, y0, z, w));
				vertices.push_back(tcu::Vec4(xm, y1, z, w));
				vertices.push_back(tcu::Vec4(x1, ym, z, w));
			}

			break;
		}

		case VK_SHADER_STAGE_FRAGMENT_BIT:
		{
			const float		z = 1.0f;
			const float		w = 1.0f;
			const tcu::Vec4	a = tcu::Vec4(-1.0f, -1.0f, z, w);
			const tcu::Vec4	b = tcu::Vec4(+1.0f, -1.0f, z, w);
			const tcu::Vec4	c = tcu::Vec4(-1.0f, +1.0f, z, w);
			const tcu::Vec4	d = tcu::Vec4(+1.0f, +1.0f, z, w);

			vertices.push_back(a);
			vertices.push_back(b);
			vertices.push_back(c);

			vertices.push_back(b);
			vertices.push_back(c);
			vertices.push_back(d);

			break;
		}

		default:
			TCU_THROW(InternalError, "Unknown stage");

	}

	// Initialize vertex buffer
	{
		const VkDeviceSize			vertexBufferSize		= sizeof(vertices[0][0]) * vertices[0].SIZE * vertices.size();
		const VkBufferCreateInfo	vertexBufferCreateInfo	= makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);

		m_vertexCount		= static_cast<deUint32>(vertices.size());
		m_vertexBuffer		= createBuffer(vkd, device, &vertexBufferCreateInfo);
		m_vertexBufferAlloc	= bindBuffer(vkd, device, allocator, *m_vertexBuffer, vk::MemoryRequirement::HostVisible);

		deMemcpy(m_vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexBufferSize);
		flushAlloc(vkd, device, *m_vertexBufferAlloc);
	}
}

Move<VkPipeline> GraphicsConfiguration::makeGraphicsPipeline (Context&		context,
															  TestParams&	testParams)
{
	const DeviceInterface&			vkd					= context.getDeviceInterface();
	const VkDevice					device				= context.getDevice();
	const bool						tessStageTest		= (testParams.stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || testParams.stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
	const VkPrimitiveTopology		topology			= tessStageTest ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
	const deUint32					patchControlPoints	= tessStageTest ? 3 : 0;
	const std::vector<VkViewport>	viewports			(1, makeViewport(testParams.width, testParams.height));
	const std::vector<VkRect2D>		scissors			(1, makeRect2D(testParams.width, testParams.height));

	return vk::makeGraphicsPipeline	(vkd,
									 device,
									 *m_pipelineLayout,
									 *m_vertShaderModule,
									 *m_tescShaderModule,
									 *m_teseShaderModule,
									 *m_geomShaderModule,
									 *m_fragShaderModule,
									 *m_renderPass,
									 viewports,
									 scissors,
									 topology,
									 0,
									 patchControlPoints);
}

void GraphicsConfiguration::initConfiguration (Context&		context,
											   TestParams&	testParams)
{
	const DeviceInterface&	vkd			= context.getDeviceInterface();
	const VkDevice			device		= context.getDevice();
	Allocator&				allocator	= context.getDefaultAllocator();
	vk::BinaryCollection&	collection	= context.getBinaryCollection();
	VkShaderStageFlags		shaders		= static_cast<VkShaderStageFlags>(0);
	deUint32				shaderCount	= 0;

	if (collection.contains("vert")) shaders |= VK_SHADER_STAGE_VERTEX_BIT;
	if (collection.contains("geom")) shaders |= VK_SHADER_STAGE_GEOMETRY_BIT;
	if (collection.contains("tesc")) shaders |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
	if (collection.contains("tese")) shaders |= VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
	if (collection.contains("frag")) shaders |= VK_SHADER_STAGE_FRAGMENT_BIT;

	for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
		shaderCount++;

	if (shaderCount != (deUint32)dePop32(shaders))
		TCU_THROW(InternalError, "Unused shaders detected in the collection");

	if (0 != (shaders & VK_SHADER_STAGE_VERTEX_BIT))					m_vertShaderModule = createShaderModule(vkd, device, collection.get("vert"), 0);
	if (0 != (shaders & VK_SHADER_STAGE_GEOMETRY_BIT))					m_geomShaderModule = createShaderModule(vkd, device, collection.get("geom"), 0);
	if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT))		m_tescShaderModule = createShaderModule(vkd, device, collection.get("tesc"), 0);
	if (0 != (shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))	m_teseShaderModule = createShaderModule(vkd, device, collection.get("tese"), 0);
	if (0 != (shaders & VK_SHADER_STAGE_FRAGMENT_BIT))					m_fragShaderModule = createShaderModule(vkd, device, collection.get("frag"), 0);

	m_descriptorSetLayout	= DescriptorSetLayoutBuilder()
								.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_ALL_GRAPHICS)
								.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_ALL_GRAPHICS)
								.build(vkd, device);
	m_descriptorPool		= DescriptorPoolBuilder()
								.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
								.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
								.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
	m_descriptorSet			= makeDescriptorSet		(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
	m_framebufferImage		= makeImage				(vkd, device, makeImageCreateInfo(m_framebufferFormat, testParams.width, testParams.height, 1u, VK_IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
	m_framebufferImageAlloc	= bindImage				(vkd, device, allocator, *m_framebufferImage, MemoryRequirement::Any);
	m_framebufferAttachment	= makeImageView			(vkd, device, *m_framebufferImage, VK_IMAGE_VIEW_TYPE_2D, m_framebufferFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
	m_renderPass			= makeRenderPass		(vkd, device, m_framebufferFormat);
	m_framebuffer			= makeFramebuffer		(vkd, device, *m_renderPass, *m_framebufferAttachment, testParams.width, testParams.height);
	m_pipelineLayout		= makePipelineLayout	(vkd, device, m_descriptorSetLayout.get());
	m_pipeline				= makeGraphicsPipeline	(context, testParams);

	initVertexBuffer(context, testParams);
}

void GraphicsConfiguration::fillCommandBuffer (Context&								context,
											   TestParams&							testParams,
											   VkCommandBuffer						cmdBuffer,
											   const VkAccelerationStructureKHR*	rayQueryTopAccelerationStructurePtr,
											   const VkDescriptorImageInfo&			resultImageInfo)
{
	const DeviceInterface&								vkd												= context.getDeviceInterface();
	const VkDevice										device											= context.getDevice();
	const VkDeviceSize									vertexBufferOffset								= 0;
	const VkWriteDescriptorSetAccelerationStructureKHR	rayQueryAccelerationStructureWriteDescriptorSet	=
	{
		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
		DE_NULL,															//  const void*							pNext;
		1u,																	//  deUint32							accelerationStructureCount;
		rayQueryTopAccelerationStructurePtr,								//  const VkAccelerationStructureKHR*	pAccelerationStructures;
	};

	DescriptorSetUpdateBuilder()
		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
		.update(vkd, device);

	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
	vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);

	beginRenderPass(vkd, cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, testParams.width, testParams.height), tcu::UVec4());

	vkd.cmdDraw(cmdBuffer, m_vertexCount, 1u, 0u, 0u);

	endRenderPass(vkd, cmdBuffer);
}

class ComputeConfiguration : public PipelineConfiguration
{
public:
								ComputeConfiguration	();
	virtual						~ComputeConfiguration	() {};

	static void					checkSupport			(Context&							context,
														 const TestParams&					testParams);
	static void					initPrograms			(SourceCollections&					programCollection,
														 const TestParams&					testParams);

	virtual void				initConfiguration		(Context&							context,
														 TestParams&						testParams) override;
	virtual void				fillCommandBuffer		(Context&							context,
														 TestParams&						testParams,
														 VkCommandBuffer					commandBuffer,
														 const VkAccelerationStructureKHR*	rayQueryTopAccelerationStructurePtr,
														 const VkDescriptorImageInfo&		resultImageInfo) override;

protected:
	Move<VkDescriptorSetLayout>	m_descriptorSetLayout;
	Move<VkDescriptorPool>		m_descriptorPool;
	Move<VkDescriptorSet>		m_descriptorSet;
	Move<VkPipelineLayout>		m_pipelineLayout;

	Move<VkShaderModule>		m_shaderModule;

	Move<VkPipeline>			m_pipeline;
};

ComputeConfiguration::ComputeConfiguration ()
	: PipelineConfiguration	()
	, m_descriptorSetLayout	()
	, m_descriptorPool		()
	, m_descriptorSet		()
	, m_pipelineLayout		()

	, m_shaderModule		()

	, m_pipeline			()
{
}

void ComputeConfiguration::checkSupport (Context&			context,
										 const TestParams&	testParams)
{
	DE_UNREF(context);
	DE_UNREF(testParams);
}

void ComputeConfiguration::initPrograms (SourceCollections&	programCollection,
										 const TestParams&	testParams)
{
	const vk::ShaderBuildOptions	buildOptions		(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);
	const std::string				testShaderBody		= testParams.testConfigShaderBodyText(testParams);
	const std::string				testBody			=
		"  ivec3       pos      = ivec3(gl_WorkGroupID);\n"
		"  ivec3       size     = ivec3(gl_NumWorkGroups);\n"
		+ testShaderBody;

	switch (testParams.stage)
	{
		case VK_SHADER_STAGE_COMPUTE_BIT:
		{
			std::stringstream css;
			css <<
				"#version 460 core\n"
				"#extension GL_EXT_ray_query : require\n"
				"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
				"layout(set = 0, binding = 1) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
				"\n"
				"void main()\n"
				"{\n"
				<< testBody <<
				"}\n";

			programCollection.glslSources.add("comp") << glu::ComputeSource(updateRayTracingGLSL(css.str())) << buildOptions;

			break;
		}

		default:
			TCU_THROW(InternalError, "Unknown stage");
	}
}

void ComputeConfiguration::initConfiguration (Context&		context,
											  TestParams&	testParams)
{
	DE_UNREF(testParams);

	const DeviceInterface&	vkd			= context.getDeviceInterface();
	const VkDevice			device		= context.getDevice();
	vk::BinaryCollection&	collection	= context.getBinaryCollection();

	m_descriptorSetLayout	= DescriptorSetLayoutBuilder()
								.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
								.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, VK_SHADER_STAGE_COMPUTE_BIT)
								.build(vkd, device);
	m_descriptorPool		= DescriptorPoolBuilder()
								.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
								.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
								.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
	m_descriptorSet			= makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
	m_pipelineLayout		= makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
	m_shaderModule			= createShaderModule(vkd, device, collection.get("comp"), 0);
	m_pipeline				= makeComputePipeline(vkd, device, *m_pipelineLayout, *m_shaderModule);
}

void ComputeConfiguration::fillCommandBuffer (Context&							context,
											  TestParams&						testParams,
											  VkCommandBuffer					cmdBuffer,
											  const VkAccelerationStructureKHR*	rayQueryTopAccelerationStructurePtr,
											  const VkDescriptorImageInfo&		resultImageInfo)
{
	const DeviceInterface&								vkd												= context.getDeviceInterface();
	const VkDevice										device											= context.getDevice();
	const VkWriteDescriptorSetAccelerationStructureKHR	rayQueryAccelerationStructureWriteDescriptorSet	=
	{
		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
		DE_NULL,															//  const void*							pNext;
		1u,																	//  deUint32							accelerationStructureCount;
		rayQueryTopAccelerationStructurePtr,								//  const VkAccelerationStructureKHR*	pAccelerationStructures;
	};

	DescriptorSetUpdateBuilder()
		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
		.update(vkd, device);

	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);

	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline.get());

	vkd.cmdDispatch(cmdBuffer, testParams.width, testParams.height, 1);
}

class RayTracingConfiguration : public PipelineConfiguration
{
public:
													RayTracingConfiguration				();
	virtual											~RayTracingConfiguration			() {};

	static void										checkSupport						(Context&							context,
																						 const TestParams&					testParams);
	static void										initPrograms						(SourceCollections&					programCollection,
																						 const TestParams&					testParams);

	virtual void									initConfiguration					(Context&							context,
																						 TestParams&						testParams) override;
	virtual void									fillCommandBuffer					(Context&							context,
																						 TestParams&						testParams,
																						 VkCommandBuffer					commandBuffer,
																						 const VkAccelerationStructureKHR*	rayQueryTopAccelerationStructurePtr,
																						 const VkDescriptorImageInfo&		resultImageInfo) override;

protected:
	de::MovePtr<BufferWithMemory>					createShaderBindingTable			(const InstanceInterface&			vki,
																						 const DeviceInterface&				vkd,
																						 const VkDevice						device,
																						 const VkPhysicalDevice				physicalDevice,
																						 const VkPipeline					pipeline,
																						 Allocator&							allocator,
																						 de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
																						 const deUint32						group);

protected:
	deUint32										m_shaders;
	deUint32										m_raygenShaderGroup;
	deUint32										m_missShaderGroup;
	deUint32										m_hitShaderGroup;
	deUint32										m_callableShaderGroup;
	deUint32										m_shaderGroupCount;

	Move<VkDescriptorSetLayout>						m_descriptorSetLayout;
	Move<VkDescriptorPool>							m_descriptorPool;
	Move<VkDescriptorSet>							m_descriptorSet;
	Move<VkPipelineLayout>							m_pipelineLayout;

	de::MovePtr<RayTracingPipeline>					m_rayTracingPipeline;
	Move<VkPipeline>								m_pipeline;

	de::MovePtr<BufferWithMemory>					m_raygenShaderBindingTable;
	de::MovePtr<BufferWithMemory>					m_hitShaderBindingTable;
	de::MovePtr<BufferWithMemory>					m_missShaderBindingTable;
	de::MovePtr<BufferWithMemory>					m_callableShaderBindingTable;

	VkStridedDeviceAddressRegionKHR					m_raygenShaderBindingTableRegion;
	VkStridedDeviceAddressRegionKHR					m_missShaderBindingTableRegion;
	VkStridedDeviceAddressRegionKHR					m_hitShaderBindingTableRegion;
	VkStridedDeviceAddressRegionKHR					m_callableShaderBindingTableRegion;

	de::SharedPtr<BottomLevelAccelerationStructure>	m_bottomLevelAccelerationStructure;
	de::SharedPtr<TopLevelAccelerationStructure>	m_topLevelAccelerationStructure;
};

RayTracingConfiguration::RayTracingConfiguration()
	: m_shaders								(0)
	, m_raygenShaderGroup					(~0u)
	, m_missShaderGroup						(~0u)
	, m_hitShaderGroup						(~0u)
	, m_callableShaderGroup					(~0u)
	, m_shaderGroupCount					(0)

	, m_descriptorSetLayout					()
	, m_descriptorPool						()
	, m_descriptorSet						()
	, m_pipelineLayout						()

	, m_rayTracingPipeline					()
	, m_pipeline							()

	, m_raygenShaderBindingTable			()
	, m_hitShaderBindingTable				()
	, m_missShaderBindingTable				()
	, m_callableShaderBindingTable			()

	, m_raygenShaderBindingTableRegion		()
	, m_missShaderBindingTableRegion		()
	, m_hitShaderBindingTableRegion			()
	, m_callableShaderBindingTableRegion	()

	, m_bottomLevelAccelerationStructure	()
	, m_topLevelAccelerationStructure		()
{
}

void RayTracingConfiguration::checkSupport (Context&			context,
											const TestParams&	testParams)
{
	DE_UNREF(testParams);

	context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");
	const VkPhysicalDeviceRayTracingPipelineFeaturesKHR&	rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();
	if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE)
		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");
}

void RayTracingConfiguration::initPrograms (SourceCollections&	programCollection,
											const TestParams&	testParams)
{
	const vk::ShaderBuildOptions	buildOptions		(programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true);

	const std::string				testShaderBody		= testParams.testConfigShaderBodyText(testParams);
	const std::string				testBody			=
		"  ivec3       pos      = ivec3(gl_LaunchIDEXT);\n"
		"  ivec3       size     = ivec3(gl_LaunchSizeEXT);\n"
		+ testShaderBody;

	switch (testParams.stage)
	{
		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
		{
			std::stringstream css;
			css <<
				"#version 460 core\n"
				"#extension GL_EXT_ray_tracing : require\n"
				"#extension GL_EXT_ray_query : require\n"
				"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
				"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
				"\n"
				"void main()\n"
				"{\n"
				<< testBody <<
				"}\n";

			programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;

			break;
		}

		case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
		{
			programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;

			{
				std::stringstream css;
				css <<
					"#version 460 core\n"
					"#extension GL_EXT_ray_tracing : require\n"
					"#extension GL_EXT_ray_query : require\n"
					"hitAttributeEXT vec3 attribs;\n"
					"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
					"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
					"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
					"\n"
					"void main()\n"
					"{\n"
					<< testBody <<
					"}\n";

				programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
			}

			programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
			programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;

			break;
		}

		case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
		{
			programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;

			{
				std::stringstream css;
				css <<
					"#version 460 core\n"
					"#extension GL_EXT_ray_tracing : require\n"
					"#extension GL_EXT_ray_query : require\n"
					"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
					"hitAttributeEXT vec3 attribs;\n"
					"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
					"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
					"\n"
					"void main()\n"
					"{\n"
					<< testBody <<
					"}\n";

				programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(css.str())) << buildOptions;
			}

			programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
			programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;

			break;
		}

		case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
		{
			programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;

			{
				std::stringstream css;
				css <<
					"#version 460 core\n"
					"#extension GL_EXT_ray_tracing : require\n"
					"#extension GL_EXT_ray_query : require\n"
					"hitAttributeEXT vec3 hitAttribute;\n"
					"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
					"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
					"\n"
					"void main()\n"
					"{\n"
					<< testBody <<
					"  hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n"
					"  reportIntersectionEXT(1.0f, 0);\n"
					"}\n";

				programCollection.glslSources.add("sect") << glu::IntersectionSource(updateRayTracingGLSL(css.str())) << buildOptions;
			}

			programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
			programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
			programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;

			break;
		}

		case VK_SHADER_STAGE_MISS_BIT_KHR:
		{
			programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;

			{
				std::stringstream css;
				css <<
					"#version 460 core\n"
					"#extension GL_EXT_ray_tracing : require\n"
					"#extension GL_EXT_ray_query : require\n"
					"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
					"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
					"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
					"\n"
					"void main()\n"
					"{\n"
					<< testBody <<
					"}\n";

				programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(css.str())) << buildOptions;
			}

			programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
			programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;

			break;
		}

		case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
		{
			{
				std::stringstream css;
				css <<
					"#version 460 core\n"
					"#extension GL_EXT_ray_tracing : require\n"
					"#extension GL_EXT_ray_query : require\n"
					"layout(location = 0) callableDataEXT float dummy;"
					"layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
					"\n"
					"void main()\n"
					"{\n"
					"  executeCallableEXT(0, 0);\n"
					"}\n";

				programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(css.str())) << buildOptions;
			}

			{
				std::stringstream css;
				css <<
					"#version 460 core\n"
					"#extension GL_EXT_ray_tracing : require\n"
					"#extension GL_EXT_ray_query : require\n"
					"layout(location = 0) callableDataInEXT float dummy;"
					"layout(set = 0, binding = 0, r32i) uniform iimage3D result;\n"
					"layout(set = 0, binding = 2) uniform accelerationStructureEXT rayQueryTopLevelAccelerationStructure;\n"
					"\n"
					"void main()\n"
					"{\n"
					<< testBody <<
					"}\n";

				programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(css.str())) << buildOptions;
			}

			programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
			programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(getHitPassthrough())) << buildOptions;
			programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(getMissPassthrough())) << buildOptions;

			break;
		}

		default:
			TCU_THROW(InternalError, "Unknown stage");
	}
}

de::MovePtr<BufferWithMemory> RayTracingConfiguration::createShaderBindingTable (const InstanceInterface&			vki,
																				 const DeviceInterface&				vkd,
																				 const VkDevice						device,
																				 const VkPhysicalDevice				physicalDevice,
																				 const VkPipeline					pipeline,
																				 Allocator&							allocator,
																				 de::MovePtr<RayTracingPipeline>&	rayTracingPipeline,
																				 const deUint32						group)
{
	de::MovePtr<BufferWithMemory>	shaderBindingTable;

	if (group < m_shaderGroupCount)
	{
		const deUint32	shaderGroupHandleSize		= getShaderGroupHandleSize(vki, physicalDevice);
		const deUint32	shaderGroupBaseAlignment	= getShaderGroupBaseAlignment(vki, physicalDevice);

		shaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, allocator, shaderGroupHandleSize, shaderGroupBaseAlignment, group, 1u);
	}

	return shaderBindingTable;
}

void RayTracingConfiguration::initConfiguration (Context&		context,
												 TestParams&	testParams)
{
	DE_UNREF(testParams);

	const InstanceInterface&	vki						= context.getInstanceInterface();
	const DeviceInterface&		vkd						= context.getDeviceInterface();
	const VkDevice				device					= context.getDevice();
	const VkPhysicalDevice		physicalDevice			= context.getPhysicalDevice();
	vk::BinaryCollection&		collection				= context.getBinaryCollection();
	Allocator&					allocator				= context.getDefaultAllocator();
	const deUint32				shaderGroupHandleSize	= getShaderGroupHandleSize(vki, physicalDevice);
	const VkShaderStageFlags	hitStages				= VK_SHADER_STAGE_ANY_HIT_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
	deUint32					shaderCount				= 0;

	m_shaderGroupCount = 0;

	if (collection.contains("rgen")) m_shaders |= VK_SHADER_STAGE_RAYGEN_BIT_KHR;
	if (collection.contains("ahit")) m_shaders |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
	if (collection.contains("chit")) m_shaders |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
	if (collection.contains("miss")) m_shaders |= VK_SHADER_STAGE_MISS_BIT_KHR;
	if (collection.contains("sect")) m_shaders |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR;
	if (collection.contains("call")) m_shaders |= VK_SHADER_STAGE_CALLABLE_BIT_KHR;

	for (BinaryCollection::Iterator it = collection.begin(); it != collection.end(); ++it)
		shaderCount++;

	if (shaderCount != (deUint32)dePop32(m_shaders))
		TCU_THROW(InternalError, "Unused shaders detected in the collection");

	if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))
		m_raygenShaderGroup		= m_shaderGroupCount++;

	if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))
		m_missShaderGroup		= m_shaderGroupCount++;

	if (0 != (m_shaders & hitStages))
		m_hitShaderGroup		= m_shaderGroupCount++;

	if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))
		m_callableShaderGroup	= m_shaderGroupCount++;

	m_rayTracingPipeline				= de::newMovePtr<RayTracingPipeline>();

	m_descriptorSetLayout				= DescriptorSetLayoutBuilder()
											.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, ALL_RAY_TRACING_STAGES)
											.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
											.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
											.build(vkd, device);
	m_descriptorPool					= DescriptorPoolBuilder()
											.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
											.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
											.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR)
											.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
	m_descriptorSet						= makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);

	if (0 != (m_shaders & VK_SHADER_STAGE_RAYGEN_BIT_KHR))			m_rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR			, createShaderModule(vkd, device, collection.get("rgen"), 0), m_raygenShaderGroup);
	if (0 != (m_shaders & VK_SHADER_STAGE_ANY_HIT_BIT_KHR))			m_rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR			, createShaderModule(vkd, device, collection.get("ahit"), 0), m_hitShaderGroup);
	if (0 != (m_shaders & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR))		m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR		, createShaderModule(vkd, device, collection.get("chit"), 0), m_hitShaderGroup);
	if (0 != (m_shaders & VK_SHADER_STAGE_MISS_BIT_KHR))			m_rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR			, createShaderModule(vkd, device, collection.get("miss"), 0), m_missShaderGroup);
	if (0 != (m_shaders & VK_SHADER_STAGE_INTERSECTION_BIT_KHR))	m_rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR	, createShaderModule(vkd, device, collection.get("sect"), 0), m_hitShaderGroup);
	if (0 != (m_shaders & VK_SHADER_STAGE_CALLABLE_BIT_KHR))		m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR		, createShaderModule(vkd, device, collection.get("call"), 0), m_callableShaderGroup);

	m_pipelineLayout					= makePipelineLayout(vkd, device, m_descriptorSetLayout.get());
	m_pipeline							= m_rayTracingPipeline->createPipeline(vkd, device, *m_pipelineLayout);

	m_raygenShaderBindingTable			= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_raygenShaderGroup);
	m_missShaderBindingTable			= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_missShaderGroup);
	m_hitShaderBindingTable				= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_hitShaderGroup);
	m_callableShaderBindingTable		= createShaderBindingTable(vki, vkd, device, physicalDevice, *m_pipeline, allocator, m_rayTracingPipeline, m_callableShaderGroup);

	m_raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_raygenShaderBindingTable),		shaderGroupHandleSize);
	m_missShaderBindingTableRegion		= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_missShaderBindingTable),		shaderGroupHandleSize);
	m_hitShaderBindingTableRegion		= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_hitShaderBindingTable),			shaderGroupHandleSize);
	m_callableShaderBindingTableRegion	= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_callableShaderBindingTable),	shaderGroupHandleSize);
}

void RayTracingConfiguration::fillCommandBuffer (Context&							context,
												 TestParams&						testParams,
												 VkCommandBuffer					commandBuffer,
												 const VkAccelerationStructureKHR*	rayQueryTopAccelerationStructurePtr,
												 const VkDescriptorImageInfo&		resultImageInfo)
{
	const DeviceInterface&							vkd									= context.getDeviceInterface();
	const VkDevice									device								= context.getDevice();
	Allocator&										allocator							= context.getDefaultAllocator();
	de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure	= makeBottomLevelAccelerationStructure();
	de::MovePtr<TopLevelAccelerationStructure>		topLevelAccelerationStructure		= makeTopLevelAccelerationStructure();

	m_bottomLevelAccelerationStructure = de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release());
	m_bottomLevelAccelerationStructure->setDefaultGeometryData(testParams.stage);
	m_bottomLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);

	m_topLevelAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(topLevelAccelerationStructure.release());
	m_topLevelAccelerationStructure->setInstanceCount(1);
	m_topLevelAccelerationStructure->addInstance(m_bottomLevelAccelerationStructure);
	m_topLevelAccelerationStructure->createAndBuild(vkd, device, commandBuffer, allocator);

	const TopLevelAccelerationStructure*				topLevelAccelerationStructurePtr				= m_topLevelAccelerationStructure.get();
	const VkWriteDescriptorSetAccelerationStructureKHR	accelerationStructureWriteDescriptorSet			=
	{
		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
		DE_NULL,															//  const void*							pNext;
		1u,																	//  deUint32							accelerationStructureCount;
		topLevelAccelerationStructurePtr->getPtr(),							//  const VkAccelerationStructureKHR*	pAccelerationStructures;
	};
	const VkWriteDescriptorSetAccelerationStructureKHR	rayQueryAccelerationStructureWriteDescriptorSet	=
	{
		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
		DE_NULL,															//  const void*							pNext;
		1u,																	//  deUint32							accelerationStructureCount;
		rayQueryTopAccelerationStructurePtr,								//  const VkAccelerationStructureKHR*	pAccelerationStructures;
	};

	DescriptorSetUpdateBuilder()
		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
		.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &rayQueryAccelerationStructureWriteDescriptorSet)
		.update(vkd, device);

	vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);

	vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, m_pipeline.get());

	cmdTraceRays(vkd,
		commandBuffer,
		&m_raygenShaderBindingTableRegion,
		&m_missShaderBindingTableRegion,
		&m_hitShaderBindingTableRegion,
		&m_callableShaderBindingTableRegion,
		testParams.width, testParams.height, 1);
}


const std::string getShaderBodyText (const TestParams& testParams)
{
	if (testParams.geomType == GEOM_TYPE_AABBS)
	{
		const std::string result =
			"  uint        rayFlags = 0;\n"
			"  uint        cullMask = 0xFF;\n"
			"  float       tmin     = 0.0;\n"
			"  float       tmax     = 9.0;\n"
			"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
			"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
			"  uint        count    = 0;\n"
			"  rayQueryEXT rayQuery;\n"
			"\n"
			"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
			"\n"
			"  while(rayQueryProceedEXT(rayQuery))\n"
			"  {\n"
			"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionAABBEXT)\n"
			"    {\n"
			"      rayQueryGenerateIntersectionEXT(rayQuery, 0.5f);\n"
			"      count++;\n"
			"    }\n"
			"  }\n"
			"  imageStore(result, pos, ivec4(count, 0, 0, 0));\n"
			"\n";

		return result;
	}
	else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
	{
		const std::string result =
			"  uint        rayFlags = gl_RayFlagsNoOpaqueEXT;\n"
			"  uint        cullMask = 0xFF;\n"
			"  float       tmin     = 0.0;\n"
			"  float       tmax     = 9.0;\n"
			"  vec3        origin   = vec3((float(pos.x) + 0.5f) / float(size.x), (float(pos.y) + 0.5f) / float(size.y), 0.0);\n"
			"  vec3        direct   = vec3(0.0, 0.0, -1.0);\n"
			"  uint        count    = 0;\n"
			"  rayQueryEXT rayQuery;\n"
			"\n"
			"  rayQueryInitializeEXT(rayQuery, rayQueryTopLevelAccelerationStructure, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
			"\n"
			"  while(rayQueryProceedEXT(rayQuery))\n"
			"  {\n"
			"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
			"    {\n"
			"      rayQueryConfirmIntersectionEXT(rayQuery);\n"
			"      count++;\n"
			"    }\n"
			"  }\n"
			"  imageStore(result, pos, ivec4(count, 0, 0, 0));\n"
			"\n";

		return result;
	}
	else
	{
		TCU_THROW(InternalError, "Unknown geometry type");
	}
}


class TestConfigurationNoMiss : public TestConfiguration
{
public:
	virtual const VkAccelerationStructureKHR*	initAccelerationStructures	(Context&							context,
																			 TestParams&						testParams,
																			 VkCommandBuffer					cmdBuffer) override;

	virtual bool								verify						(BufferWithMemory*					resultBuffer,
																			 Context&							context,
																			 TestParams&						testParams) override;
private:
	deUint32									chooseAABB					(de::Random&						rng,
																			 const std::vector<tcu::Vec2>&		vertices,
																			 const std::vector<tcu::UVec2>&		aabbs);
	deUint32									chooseTriangle				(de::Random&						rng,
																			 const std::vector<tcu::Vec2>&		vertices,
																			 const std::vector<tcu::UVec3>&		triangles);
};

deUint32 TestConfigurationNoMiss::chooseAABB (de::Random&						rng,
											  const std::vector<tcu::Vec2>&		vertices,
											  const std::vector<tcu::UVec2>&	aabbs)
{
	while (true)
	{
		const deUint32		n	= (deUint32)rng.getInt(0, (deUint32)aabbs.size() - 1);
		const tcu::UVec2&	t	= aabbs[n];
		const tcu::Vec2&	a	= vertices[t.x()];
		const tcu::Vec2&	b	= vertices[t.y()];

		if (deFloatAbs(a.x() - b.x()) < MIN_AABB_SIDE_LENGTH || deFloatAbs(a.y() - b.y()) < MIN_AABB_SIDE_LENGTH)
			continue;

		return n;
	}
}

deUint32 TestConfigurationNoMiss::chooseTriangle (de::Random&						rng,
												  const std::vector<tcu::Vec2>&		vertices,
												  const std::vector<tcu::UVec3>&	triangles)
{
	while (true)
	{
		const deUint32		n	= (deUint32)rng.getInt(0, (deUint32)triangles.size() - 1);
		const tcu::UVec3&	t	= triangles[n];
		const tcu::Vec2&	a	= vertices[t.x()];
		const tcu::Vec2&	b	= vertices[t.y()];
		const tcu::Vec2&	c	= vertices[t.z()];
		const float			ab	= triangleEdgeLength(a, b);
		const float			bc	= triangleEdgeLength(b, c);
		const float			ca	= triangleEdgeLength(c, a);

		if (ab < MIN_TRIANGLE_EDGE_LENGTH || bc < MIN_TRIANGLE_EDGE_LENGTH || ca < MIN_TRIANGLE_EDGE_LENGTH || triangleArea(ab, bc, ca) < MIN_TRIANGLE_AREA_SIZE)
			continue;

		return n;
	}
}

const VkAccelerationStructureKHR* TestConfigurationNoMiss::initAccelerationStructures (Context&			context,
																					   TestParams&		testParams,
																					   VkCommandBuffer	cmdBuffer)
{
	const DeviceInterface&							vkd											= context.getDeviceInterface();
	const VkDevice									device										= context.getDevice();
	Allocator&										allocator									= context.getDefaultAllocator();
	const tcu::Vec2									centerPixelCenter							= tcu::Vec2(0.5f - 0.5f / float(testParams.width), 0.5f - 0.5f / float(testParams.height));
	de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure	= makeBottomLevelAccelerationStructure();
	de::MovePtr<TopLevelAccelerationStructure>		rayQueryTopLevelAccelerationStructure		= makeTopLevelAccelerationStructure();
	de::Random										rng											(testParams.randomSeed);
	std::vector<tcu::Vec3>							geometryData;

	if (testParams.geomType == GEOM_TYPE_AABBS)
	{
		std::vector<tcu::UVec2>	aabbs;
		std::vector<tcu::Vec2>	vertices;

		vertices.reserve(2u * testParams.squaresGroupCount);
		aabbs.reserve(testParams.squaresGroupCount);

		{
			// a---g---+
			// |   |   |
			// e---d---h
			// |   |   |
			// +---f---b
			//
			// a-d, d-b, e-f, g-h

			const tcu::Vec2		d	= centerPixelCenter;
			const tcu::Vec2		a	= tcu::Vec2(0.0f, 0.0f);
			const tcu::Vec2		b	= tcu::Vec2(1.0f, 1.0f);
			const tcu::Vec2		e	= tcu::Vec2(a.x(), d.y());
			const tcu::Vec2		f	= tcu::Vec2(d.x(), b.y());
			const tcu::Vec2		g	= tcu::Vec2(d.x(), a.y());
			const tcu::Vec2		h	= tcu::Vec2(b.x(), d.y());
			const deUint32		A	= 0;
			const deUint32		B	= 1;
			const deUint32		D	= 2;
			const deUint32		E	= 3;
			const deUint32		F	= 4;
			const deUint32		G	= 5;
			const deUint32		H	= 6;

			vertices.push_back(a);
			vertices.push_back(b);
			vertices.push_back(d);
			vertices.push_back(e);
			vertices.push_back(f);
			vertices.push_back(g);
			vertices.push_back(h);

			aabbs.push_back(tcu::UVec2(A, D));
			aabbs.push_back(tcu::UVec2(D, B));
			aabbs.push_back(tcu::UVec2(E, F));
			aabbs.push_back(tcu::UVec2(G, H));
		}

		while (aabbs.size() < testParams.squaresGroupCount)
		{
			// a-------+      a---g---+
			// |       |      |   |   |
			// |       |  ->  e---d---h
			// |       |      |   |   |
			// +-------b      +---f---b
			//
			// a-b        ->  a-d, d-b, e-f, g-h

			const deUint32		n		= chooseAABB(rng, vertices, aabbs);
			tcu::UVec2&			t		= aabbs[n];
			const tcu::Vec2&	a		= vertices[t.x()];
			const tcu::Vec2&	b		= vertices[t.y()];
			const float			alfa	= rng.getFloat(0.2f, 0.8f);
			const float			beta	= rng.getFloat(0.2f, 0.8f);
			const tcu::Vec2		d		= mixCoordsVec2(a, b, alfa, beta);
			const tcu::Vec2		e		= tcu::Vec2(a.x(), d.y());
			const tcu::Vec2		f		= tcu::Vec2(d.x(), b.y());
			const tcu::Vec2		g		= tcu::Vec2(d.x(), a.y());
			const tcu::Vec2		h		= tcu::Vec2(b.x(), d.y());
			const deUint32		B		= t.y();
			const deUint32		D		= (deUint32)vertices.size();
			const deUint32		E		= D + 1;
			const deUint32		F		= D + 2;
			const deUint32		G		= D + 3;
			const deUint32		H		= D + 4;

			if (d.x() <= a.x() || d.x() >= b.x() || d.y() <= a.y() || d.y() >= b.y())
				continue;

			vertices.push_back(d);
			vertices.push_back(e);
			vertices.push_back(f);
			vertices.push_back(g);
			vertices.push_back(h);

			t.y() = D;
			aabbs.push_back(tcu::UVec2(D, B));
			aabbs.push_back(tcu::UVec2(E, F));
			aabbs.push_back(tcu::UVec2(G, H));
		}

		geometryData.reserve(2u * aabbs.size());

		for (size_t i = 0; i < aabbs.size(); ++i)
		{
			const tcu::Vec2&	a	= vertices[aabbs[i].x()];
			const tcu::Vec2&	b	= vertices[aabbs[i].y()];
			const float			az	= -rng.getFloat(0.1f, 0.5f);
			const float			bz	= az + 0.01f;
			const tcu::Vec3		A	= tcu::Vec3(a.x(), a.y(), az);
			const tcu::Vec3		B	= tcu::Vec3(b.x(), b.y(), bz);

			geometryData.push_back(A);
			geometryData.push_back(B);
		}
	}
	else if (testParams.geomType == GEOM_TYPE_TRIANGLES)
	{
		std::vector<tcu::UVec3>	triangles;
		std::vector<tcu::Vec2>	vertices;
		std::vector<float>		verticesZ;

		vertices.reserve(3u * testParams.squaresGroupCount);
		triangles.reserve(testParams.squaresGroupCount);

		{
			// Initial triangle set: aeb, bec, cef, fei, ieh, heg, ged, dea
			// e - is not math middle, but centrum of one of the pixels
			// a---b---c
			// | \ | / |
			// d---e---f
			// | / | \ |
			// g---h---i

			const tcu::Vec2		e	= centerPixelCenter;
			const tcu::Vec2		a	= tcu::Vec2( 0.0f,  0.0f);
			const tcu::Vec2		i	= tcu::Vec2( 1.0f,  1.0f);
			const tcu::Vec2		c	= tcu::Vec2(i.x(), a.y());
			const tcu::Vec2		g	= tcu::Vec2(a.x(), i.y());
			const tcu::Vec2		b	= tcu::Vec2(e.x(), a.y());
			const tcu::Vec2		d	= tcu::Vec2(a.x(), e.y());
			const tcu::Vec2		f	= tcu::Vec2(i.x(), e.y());
			const tcu::Vec2		h	= tcu::Vec2(e.x(), i.y());
			const deUint32		A	= 0;
			const deUint32		B	= 1;
			const deUint32		C	= 2;
			const deUint32		D	= 3;
			const deUint32		E	= 4;
			const deUint32		F	= 5;
			const deUint32		G	= 6;
			const deUint32		H	= 7;
			const deUint32		I	= 8;

			vertices.push_back(a);
			vertices.push_back(b);
			vertices.push_back(c);
			vertices.push_back(d);
			vertices.push_back(e);
			vertices.push_back(f);
			vertices.push_back(g);
			vertices.push_back(h);
			vertices.push_back(i);

			triangles.push_back(tcu::UVec3(A, E, B));
			triangles.push_back(tcu::UVec3(B, E, C));
			triangles.push_back(tcu::UVec3(C, E, F));
			triangles.push_back(tcu::UVec3(F, E, I));
			triangles.push_back(tcu::UVec3(I, E, H));
			triangles.push_back(tcu::UVec3(H, E, G));
			triangles.push_back(tcu::UVec3(G, E, D));
			triangles.push_back(tcu::UVec3(D, E, A));
		}

		while (triangles.size() < testParams.squaresGroupCount)
		{
			const deUint32		n		= chooseTriangle(rng, vertices, triangles);
			tcu::UVec3&			t		= triangles[n];
			const tcu::Vec2&	a		= vertices[t.x()];
			const tcu::Vec2&	b		= vertices[t.y()];
			const tcu::Vec2&	c		= vertices[t.z()];
			const float			alfa	= rng.getFloat(0.2f, 0.8f);
			const float			beta	= rng.getFloat(0.2f, 0.8f);
			const tcu::Vec2		d		= mixVec2(mixVec2(a, b, alfa), c, beta);
			const deUint32&		p		= t.x();
			const deUint32&		q		= t.y();
			deUint32&			r		= t.z();
			const deUint32		R		= (deUint32)vertices.size();

			vertices.push_back(d);

			triangles.push_back(tcu::UVec3(q, r, R));
			triangles.push_back(tcu::UVec3(p, r, R));
			r = R;
		}

		verticesZ.reserve(vertices.size());
		for (size_t i = 0; i < vertices.size(); ++i)
			verticesZ.push_back(-rng.getFloat(0.01f, 0.99f));

		geometryData.reserve(3u * triangles.size());

		for (size_t i = 0; i < triangles.size(); ++i)
		{
			const deUint32	a = triangles[i].x();
			const deUint32	b = triangles[i].y();
			const deUint32	c = triangles[i].z();

			geometryData.push_back(tcu::Vec3(vertices[a].x(), vertices[a].y(), verticesZ[a]));
			geometryData.push_back(tcu::Vec3(vertices[b].x(), vertices[b].y(), verticesZ[b]));
			geometryData.push_back(tcu::Vec3(vertices[c].x(), vertices[c].y(), verticesZ[c]));
		}
	}
	else
	{
		TCU_THROW(InternalError, "Unknown geometry type");
	}

	rayQueryBottomLevelAccelerationStructure->setGeometryCount(1u);
	rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, testParams.geomType == GEOM_TYPE_TRIANGLES);
	rayQueryBottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);
	m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));
	m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
	m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back());
	m_topAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, allocator);

	return m_topAccelerationStructure.get()->getPtr();
}

bool TestConfigurationNoMiss::verify (BufferWithMemory*					resultBuffer,
									  Context&							context,
									  TestParams&						testParams)
{
	tcu::TestLog&	log			= context.getTestContext().getLog();
	const deUint32	width		= testParams.width;
	const deUint32	height		= testParams.height;
	const deInt32*	resultPtr	= (deInt32*)resultBuffer->getAllocation().getHostPtr();
	deUint32		failures	= 0;
	deUint32		pos			= 0;

	for (deUint32 y = 0; y < height; ++y)
	for (deUint32 x = 0; x < width; ++x)
	{
		if (resultPtr[pos] <= 0)
			failures++;

		pos++;
	}

	if (failures != 0)
	{
		std::stringstream	css;

		pos = 0;

		for (deUint32 y = 0; y < height; ++y)
		{
			for (deUint32 x = 0; x < width; ++x)
			{
				if (resultPtr[pos] <= 0)
					css << std::setw(3) << resultPtr[pos] << ",";
				else
					css << "___,";

				pos++;
			}

			css << std::endl;
		}

		log << tcu::TestLog::Message << "Retrieved:" << tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
	}

	return (failures == 0);
}


class TestConfigurationSingleHit : public TestConfigurationNoMiss
{
public:
	virtual bool								verify						(BufferWithMemory*					resultBuffer,
																			 Context&							context,
																			 TestParams&						testParams) override;
};

bool TestConfigurationSingleHit::verify (BufferWithMemory*					resultBuffer,
										 Context&							context,
										 TestParams&						testParams)
{
	tcu::TestLog&	log				= context.getTestContext().getLog();
	const deUint32	width			= testParams.width;
	const deUint32	height			= testParams.height;
	const deInt32*	resultPtr		= (deInt32*)resultBuffer->getAllocation().getHostPtr();
	const deInt32	expectedValue	= 1;
	deUint32		failures		= 0;
	deUint32		pos				= 0;

	for (deUint32 y = 0; y < height; ++y)
	for (deUint32 x = 0; x < width; ++x)
	{
		if (resultPtr[pos] != expectedValue)
			failures++;

		pos++;
	}

	if (failures != 0)
	{
		std::stringstream	css;

		pos = 0;

		for (deUint32 y = 0; y < height; ++y)
		{
			for (deUint32 x = 0; x < width; ++x)
			{
				if (resultPtr[pos] != expectedValue)
					css << std::setw(3) << resultPtr[pos] << ",";
				else
					css << "___,";

				pos++;
			}

			css << std::endl;
		}

		log << tcu::TestLog::Message << "Retrieved:" << tcu::TestLog::EndMessage;
		log << tcu::TestLog::Message << css.str() << tcu::TestLog::EndMessage;
	}

	return (failures == 0);
}


class RayQueryBuiltinTestInstance : public TestInstance
{
public:
										RayQueryBuiltinTestInstance		(Context& context, const TestParams& data);
	virtual								~RayQueryBuiltinTestInstance	(void);
	tcu::TestStatus						iterate							(void);

private:
	TestParams							m_data;
	de::MovePtr<TestConfiguration>		m_testConfig;
	de::MovePtr<PipelineConfiguration>	m_pipelineConfig;
};

RayQueryBuiltinTestInstance::RayQueryBuiltinTestInstance (Context& context, const TestParams& data)
	: vkt::TestInstance		(context)
	, m_data				(data)
{
	switch (m_data.testType)
	{
		case TEST_TYPE_NO_MISS:		m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationNoMiss());		break;
		case TEST_TYPE_SINGLE_HIT:	m_testConfig = de::MovePtr<TestConfiguration>(new TestConfigurationSingleHit());	break;
		default: TCU_THROW(InternalError, "Unknown test type");
	}

	switch (m_data.stage)
	{
		case VK_SHADER_STAGE_VERTEX_BIT:
		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
		case VK_SHADER_STAGE_GEOMETRY_BIT:
		case VK_SHADER_STAGE_FRAGMENT_BIT:
		{
			m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new GraphicsConfiguration());
			break;
		}

		case VK_SHADER_STAGE_COMPUTE_BIT:
		{
			m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new ComputeConfiguration());
			break;
		}

		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
		case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
		case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
		case VK_SHADER_STAGE_MISS_BIT_KHR:
		case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
		case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
		{
			m_pipelineConfig = de::MovePtr<PipelineConfiguration>(new RayTracingConfiguration());
			break;
		}

		default:
			TCU_THROW(InternalError, "Unknown shader stage");
	}
}

RayQueryBuiltinTestInstance::~RayQueryBuiltinTestInstance (void)
{
}

tcu::TestStatus RayQueryBuiltinTestInstance::iterate (void)
{
	const DeviceInterface&				vkd									= m_context.getDeviceInterface();
	const VkDevice						device								= m_context.getDevice();
	const VkQueue						queue								= m_context.getUniversalQueue();
	Allocator&							allocator							= m_context.getDefaultAllocator();
	const deUint32						queueFamilyIndex					= m_context.getUniversalQueueFamilyIndex();

	const deUint32						width								= m_data.width;
	const deUint32						height								= m_data.height;
	const deUint32						depth								= m_data.depth;
	const VkImageCreateInfo				imageCreateInfo						= makeImageCreateInfo(m_data.format, width, height, depth);
	const VkImageSubresourceRange		imageSubresourceRange				= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	const de::MovePtr<ImageWithMemory>	image								= de::MovePtr<ImageWithMemory>(new ImageWithMemory(vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any));
	const Move<VkImageView>				imageView							= makeImageView(vkd, device, **image, VK_IMAGE_VIEW_TYPE_3D, m_data.format, imageSubresourceRange);

	const deUint32						pixelSize							= mapVkFormat(m_data.format).getPixelSize();
	const VkBufferCreateInfo			resultBufferCreateInfo				= makeBufferCreateInfo(width * height * depth * pixelSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
	const VkImageSubresourceLayers		resultBufferImageSubresourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
	const VkBufferImageCopy				resultBufferImageRegion				= makeBufferImageCopy(makeExtent3D(width, height, depth), resultBufferImageSubresourceLayers);
	de::MovePtr<BufferWithMemory>		resultBuffer						= de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, allocator, resultBufferCreateInfo, MemoryRequirement::HostVisible));

	const VkDescriptorImageInfo			resultImageInfo						= makeDescriptorImageInfo(DE_NULL, *imageView, VK_IMAGE_LAYOUT_GENERAL);

	const Move<VkCommandPool>			cmdPool								= createCommandPool(vkd, device, 0, queueFamilyIndex);
	const Move<VkCommandBuffer>			cmdBuffer							= allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	const VkAccelerationStructureKHR*	topAccelerationStructurePtr			= DE_NULL;

	m_pipelineConfig->initConfiguration(m_context, m_data);

	beginCommandBuffer(vkd, *cmdBuffer, 0u);
	{
		const VkImageMemoryBarrier	preImageBarrier			= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, **image, imageSubresourceRange);
		const VkClearValue			clearValue				= makeClearValueColorU32(0u, 0u, 0u, 0u);
		const VkImageMemoryBarrier	postImageBarrier		= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR | VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, **image, imageSubresourceRange);
		const VkMemoryBarrier		postTestMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
		const VkMemoryBarrier		postCopyMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);

		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preImageBarrier);
		vkd.cmdClearColorImage(*cmdBuffer, **image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &imageSubresourceRange);
		cmdPipelineImageMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, &postImageBarrier);

		topAccelerationStructurePtr = m_testConfig->initAccelerationStructures(m_context, m_data, *cmdBuffer);

		m_pipelineConfig->fillCommandBuffer(m_context, m_data, *cmdBuffer, topAccelerationStructurePtr, resultImageInfo);

		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTestMemoryBarrier);

		vkd.cmdCopyImageToBuffer(*cmdBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);

		cmdPipelineMemoryBarrier(vkd, *cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyMemoryBarrier);
	}
	endCommandBuffer(vkd, *cmdBuffer);

	submitCommandsAndWait(vkd, device, queue, cmdBuffer.get());

	invalidateMappedMemoryRange(vkd, device, resultBuffer->getAllocation().getMemory(), resultBuffer->getAllocation().getOffset(), VK_WHOLE_SIZE);

	if (m_testConfig->verify(resultBuffer.get(), m_context, m_data))
		return tcu::TestStatus::pass("Pass");
	else
		return tcu::TestStatus::fail("Fail");
}

class RayQueryBuiltinTestCase : public TestCase
{
	public:
							RayQueryBuiltinTestCase		(tcu::TestContext& context, const char* name, const char* desc, const TestParams data);
							~RayQueryBuiltinTestCase	(void);

	virtual void			checkSupport				(Context& context) const;
	virtual	void			initPrograms				(SourceCollections& programCollection) const;
	virtual TestInstance*	createInstance				(Context& context) const;

private:
	TestParams				m_data;
};

RayQueryBuiltinTestCase::RayQueryBuiltinTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams data)
	: vkt::TestCase	(context, name, desc)
	, m_data		(data)
{
}

RayQueryBuiltinTestCase::~RayQueryBuiltinTestCase (void)
{
}

void RayQueryBuiltinTestCase::checkSupport (Context& context) const
{
	context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
	context.requireDeviceFunctionality("VK_KHR_ray_query");

	const VkPhysicalDeviceRayQueryFeaturesKHR&				rayQueryFeaturesKHR					= context.getRayQueryFeatures();
	if (rayQueryFeaturesKHR.rayQuery == DE_FALSE)
		TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");

	const VkPhysicalDeviceAccelerationStructureFeaturesKHR&	accelerationStructureFeaturesKHR	= context.getAccelerationStructureFeatures();
	if (accelerationStructureFeaturesKHR.accelerationStructure == DE_FALSE)
		TCU_THROW(TestError, "VK_KHR_ray_query requires VkPhysicalDeviceAccelerationStructureFeaturesKHR.accelerationStructure");

	m_data.pipelineCheckSupport(context, m_data);
}

TestInstance* RayQueryBuiltinTestCase::createInstance (Context& context) const
{
	return new RayQueryBuiltinTestInstance(context, m_data);
}

void RayQueryBuiltinTestCase::initPrograms (SourceCollections& programCollection) const
{
	m_data.pipelineInitPrograms(programCollection, m_data);
}

static inline CheckSupportFunc getPipelineCheckSupport (const VkShaderStageFlagBits stage)
{
	switch (stage)
	{
		case VK_SHADER_STAGE_VERTEX_BIT:
		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
		case VK_SHADER_STAGE_GEOMETRY_BIT:
		case VK_SHADER_STAGE_FRAGMENT_BIT:
			return GraphicsConfiguration::checkSupport;

		case VK_SHADER_STAGE_COMPUTE_BIT:
			return ComputeConfiguration::checkSupport;

		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
		case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
		case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
		case VK_SHADER_STAGE_MISS_BIT_KHR:
		case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
		case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
			return RayTracingConfiguration::checkSupport;

		default:
			TCU_THROW(InternalError, "Unknown shader stage");
	}
}

static inline InitProgramsFunc getPipelineInitPrograms (const VkShaderStageFlagBits stage)
{
	switch (stage)
	{
		case VK_SHADER_STAGE_VERTEX_BIT:
		case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
		case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
		case VK_SHADER_STAGE_GEOMETRY_BIT:
		case VK_SHADER_STAGE_FRAGMENT_BIT:
			return GraphicsConfiguration::initPrograms;

		case VK_SHADER_STAGE_COMPUTE_BIT:
			return ComputeConfiguration::initPrograms;

		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
		case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
		case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
		case VK_SHADER_STAGE_MISS_BIT_KHR:
		case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
		case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
			return RayTracingConfiguration::initPrograms;

		default:
			TCU_THROW(InternalError, "Unknown shader stage");
	}
}

static inline ShaderBodyTextFunc getShaderBodyTextFunc (const TestType testType)
{
	switch (testType)
	{
		case TEST_TYPE_NO_MISS:		return getShaderBodyText;	break;
		case TEST_TYPE_SINGLE_HIT:	return getShaderBodyText;	break;
		default:					TCU_THROW(InternalError, "Unknown test type");
	}
}

}	// anonymous

tcu::TestCaseGroup*	createWatertightnessTests	(tcu::TestContext& testCtx)
{
	const deUint32					seed	= (deUint32)(testCtx.getCommandLine().getBaseSeed());
	de::MovePtr<tcu::TestCaseGroup> group	(new tcu::TestCaseGroup(testCtx, "watertightness", "Tests watertightness of ray query"));

	const struct PipelineStages
	{
		VkShaderStageFlagBits	stage;
		const char*				name;
	}
	pipelineStages[] =
	{
		{ VK_SHADER_STAGE_VERTEX_BIT,					"vert"			},
		{ VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,		"tesc"			},
		{ VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,	"tese"			},
		{ VK_SHADER_STAGE_GEOMETRY_BIT,					"geom"			},
		{ VK_SHADER_STAGE_FRAGMENT_BIT,					"frag"			},
		{ VK_SHADER_STAGE_COMPUTE_BIT,					"comp"			},
		{ VK_SHADER_STAGE_RAYGEN_BIT_KHR,				"rgen"			},
		{ VK_SHADER_STAGE_ANY_HIT_BIT_KHR,				"ahit"			},
		{ VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,			"chit"			},
		{ VK_SHADER_STAGE_MISS_BIT_KHR,					"miss"			},
		{ VK_SHADER_STAGE_INTERSECTION_BIT_KHR,			"sect"			},
		{ VK_SHADER_STAGE_CALLABLE_BIT_KHR,				"call"			},
	};
	const struct TestTypes
	{
		TestType	testType;
		const char*	name;
	}
	testTypes[] =
	{
		{ TEST_TYPE_NO_MISS,							"nomiss"		},
		{ TEST_TYPE_SINGLE_HIT,							"singlehit"		},
	};
	const struct GeomTypes
	{
		GeomType	geomType;
		const char*	name;
	}
	geomTypes[] =
	{
		{ GEOM_TYPE_TRIANGLES,							"triangles"		},
		{ GEOM_TYPE_AABBS,								"aabbs"			},
	};

	for (size_t testTypeNdx = 0; testTypeNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypeNdx)
	{
		de::MovePtr<tcu::TestCaseGroup>	testTypeGroup		(new tcu::TestCaseGroup(group->getTestContext(), testTypes[testTypeNdx].name, ""));
		const TestType					testType			= testTypes[testTypeNdx].testType;
		const ShaderBodyTextFunc		shaderBodyTextFunc	= getShaderBodyTextFunc(testType);
		const deUint32					imageDepth			= 1;

		for (size_t pipelineStageNdx = 0; pipelineStageNdx < DE_LENGTH_OF_ARRAY(pipelineStages); ++pipelineStageNdx)
		{
			de::MovePtr<tcu::TestCaseGroup>	sourceTypeGroup			(new tcu::TestCaseGroup(group->getTestContext(), pipelineStages[pipelineStageNdx].name, ""));
			const VkShaderStageFlagBits		stage					= pipelineStages[pipelineStageNdx].stage;
			const CheckSupportFunc			pipelineCheckSupport	= getPipelineCheckSupport(stage);
			const InitProgramsFunc			pipelineInitPrograms	= getPipelineInitPrograms(stage);
			const deUint32					instancesGroupCount		= 1;
			const deUint32					geometriesGroupCount	= 1;
			const deUint32					squaresGroupCount		= (TEST_WIDTH * TEST_HEIGHT) / geometriesGroupCount / instancesGroupCount;

			DE_ASSERT(instancesGroupCount * geometriesGroupCount * squaresGroupCount == TEST_WIDTH * TEST_HEIGHT);

			for (size_t geomTypeNdx = 0; geomTypeNdx < DE_LENGTH_OF_ARRAY(geomTypes); ++geomTypeNdx)
			{
				const GeomType		geomType	= geomTypes[geomTypeNdx].geomType;
				const TestParams	testParams	=
				{
					TEST_WIDTH,				//  deUint32				width;
					TEST_HEIGHT,			//  deUint32				height;
					imageDepth,				//  deUint32				depth;
					seed,					//  deUint32				randomSeed;
					testType,				//  TestType				testType;
					stage,					//  VkShaderStageFlagBits	stage;
					geomType,				//  GeomType				geomType;
					squaresGroupCount,		//  deUint32				squaresGroupCount;
					geometriesGroupCount,	//  deUint32				geometriesGroupCount;
					instancesGroupCount,	//  deUint32				instancesGroupCount;
					VK_FORMAT_R32_SINT,		//  VkFormat				format;
					pipelineCheckSupport,	//  CheckSupportFunc		pipelineCheckSupport;
					pipelineInitPrograms,	//  InitProgramsFunc		pipelineInitPrograms;
					shaderBodyTextFunc,		//  ShaderTestTextFunc		testConfigShaderBodyText;
				};

				if (testType == TEST_TYPE_SINGLE_HIT && geomType == GEOM_TYPE_AABBS)
					continue;

				sourceTypeGroup->addChild(new RayQueryBuiltinTestCase(group->getTestContext(), geomTypes[geomTypeNdx].name, "", testParams));
			}

			testTypeGroup->addChild(sourceTypeGroup.release());
		}

		group->addChild(testTypeGroup.release());
	}

	return group.release();
}

}	// RayQuery
}	// vkt
