/*------------------------------------------------------------------------
 * 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:
	case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
	case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
	case VK_SHADER_STAGE_GEOMETRY_BIT:
		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
		break;
	default:
		break;
	}

	switch (testParams.stage)
	{
	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;
	default:
		break;
	}
}

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;
		case TEST_TYPE_SINGLE_HIT:	return getShaderBodyText;
		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
