/*------------------------------------------------------------------------
 * 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;	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
