/*------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2021 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 Acceleration Structure binding tests
 *//*--------------------------------------------------------------------*/

#include "vktBindingDescriptorUpdateASTests.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 BindingModel
{
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_USING_RAY_QUERY		= 0,
	TEST_TYPE_USING_RAY_TRACING,
};

enum UpdateMethod
{
	UPDATE_METHOD_NORMAL = 0,			//!< use vkUpdateDescriptorSets				vkUpdateDescriptorSets
	UPDATE_METHOD_WITH_TEMPLATE,		//!< use descriptor update templates		vkUpdateDescriptorSetWithTemplate
	UPDATE_METHOD_WITH_PUSH,			//!< use push descriptor updates			vkCmdPushDescriptorSetKHR
	UPDATE_METHOD_WITH_PUSH_TEMPLATE,	//!< use push descriptor update templates	vkCmdPushDescriptorSetWithTemplateKHR

	UPDATE_METHOD_LAST
};

const deUint32	TEST_WIDTH			= 16u;
const deUint32	TEST_HEIGHT			= 16u;
const deUint32	FIXED_POINT_DIVISOR	= 1024 * 1024;
const float		PLAIN_Z0			= 2.0f;
const float		PLAIN_Z1			= 4.0f;

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);

struct TestParams
{
	deUint32				width;
	deUint32				height;
	deUint32				depth;
	TestType				testType;
	UpdateMethod			updateMethod;
	VkShaderStageFlagBits	stage;
	VkFormat				format;
	CheckSupportFunc		pipelineCheckSupport;
	InitProgramsFunc		pipelineInitPrograms;
	ShaderBodyTextFunc		testConfigShaderBodyText;
};


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

	rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physicalDevice);

	return rayTracingPropertiesKHR->getShaderGroupHandleSize();
}

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

	rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice);

	return rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
}

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

	return result;
}

static VkStridedDeviceAddressRegionKHR makeStridedDeviceAddressRegion (const DeviceInterface& vkd, const VkDevice device, VkBuffer buffer, deUint32 stride, deUint32 count)
{
	if (buffer == DE_NULL)
	{
		return makeStridedDeviceAddressRegionKHR(0, 0, 0);
	}
	else
	{
		return makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, buffer, 0), stride, stride * count);
	}
}

static Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&		vk,
												  const VkDevice				device,
												  const VkDescriptorSetLayout	descriptorSetLayout0,
												  const VkDescriptorSetLayout	descriptorSetLayout1,
												  const VkDescriptorSetLayout	descriptorSetLayoutOpt = DE_NULL)
{
	std::vector<VkDescriptorSetLayout> descriptorSetLayouts;

	descriptorSetLayouts.push_back(descriptorSetLayout0);
	descriptorSetLayouts.push_back(descriptorSetLayout1);

	if (descriptorSetLayoutOpt != DE_NULL)
		descriptorSetLayouts.push_back(descriptorSetLayoutOpt);

	return makePipelineLayout(vk, device, (deUint32)descriptorSetLayouts.size(), descriptorSetLayouts.data());
}

static VkWriteDescriptorSetAccelerationStructureKHR makeWriteDescriptorSetAccelerationStructureKHR (const VkAccelerationStructureKHR* accelerationStructureKHR)
{
	const VkWriteDescriptorSetAccelerationStructureKHR	result	=
	{
		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR,	//  VkStructureType						sType;
		DE_NULL,															//  const void*							pNext;
		1u,																	//  deUint32							accelerationStructureCount;
		accelerationStructureKHR											//  const VkAccelerationStructureKHR*	pAccelerationStructures;
	};

	return result;
}

static bool isPushUpdateMethod (const UpdateMethod	updateMethod)
{
	switch (updateMethod)
	{
		case UPDATE_METHOD_NORMAL:				return false;
		case UPDATE_METHOD_WITH_TEMPLATE:		return false;
		case UPDATE_METHOD_WITH_PUSH:			return true;
		case UPDATE_METHOD_WITH_PUSH_TEMPLATE:	return true;
		default: TCU_THROW(InternalError, "Unknown update method");
	}
}

static bool isTemplateUpdateMethod (const UpdateMethod	updateMethod)
{
	switch (updateMethod)
	{
		case UPDATE_METHOD_NORMAL:				return false;
		case UPDATE_METHOD_WITH_TEMPLATE:		return true;
		case UPDATE_METHOD_WITH_PUSH:			return false;
		case UPDATE_METHOD_WITH_PUSH_TEMPLATE:	return true;
		default: TCU_THROW(InternalError, "Unknown update method");
	}
}

static Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&		vki,
												const VkDevice				device,
												const VkDescriptorPool		descriptorPool,
												const VkDescriptorSetLayout	setLayout,
												UpdateMethod				updateMethod)
{
	const bool				pushUpdateMethod	= isPushUpdateMethod(updateMethod);
	Move<VkDescriptorSet>	descriptorSet		= pushUpdateMethod
												? vk::Move<vk::VkDescriptorSet>()
												: vk::makeDescriptorSet(vki, device, descriptorPool, setLayout, DE_NULL);

	return descriptorSet;
}

static 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;
}

static 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)
{
	std::ostringstream src;

	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
		<< "#extension GL_EXT_ray_tracing : require\n"
		<< "\n"
		<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
		<< "\n"
		<< "void main()\n"
		<< "{\n"
		<< "}\n";

	return src.str();
}

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

	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\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 src.str();
}

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 VkDescriptorSetLayoutCreateFlags getDescriptorSetLayoutCreateFlags(const UpdateMethod updateMethod)
{
	vk::VkDescriptorSetLayoutCreateFlags	extraFlags	= 0;

	if (updateMethod == UPDATE_METHOD_WITH_PUSH_TEMPLATE || updateMethod == UPDATE_METHOD_WITH_PUSH)
	{
		extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
	}

	return extraFlags;
}

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

protected:
	virtual void													initPipeline								(void) = 0;
	virtual deUint32												getExtraAccelerationDescriptorCount			(void) = 0;
	virtual VkShaderStageFlags										getShaderStageFlags							(void) = 0;
	virtual VkPipelineBindPoint										getPipelineBindPoint						(void) = 0;

	virtual void													fillCommandBuffer							(VkCommandBuffer	commandBuffer) = 0;

	virtual const	VkAccelerationStructureKHR*						createAccelerationStructures				(Context&			context,
																												 TestParams&		testParams);
	virtual void													buildAccelerationStructures					(Context&			context,
																												 TestParams&		testParams,
																												 VkCommandBuffer	commandBuffer);
	virtual bool													verify										(BufferWithMemory*	resultBuffer,
																												 Context&			context,
																												 TestParams&		testParams);

	TestParams														m_testParams;

	std::vector<de::SharedPtr<BottomLevelAccelerationStructure>>	m_bottomAccelerationStructures;
	de::SharedPtr<TopLevelAccelerationStructure>					m_topAccelerationStructure;

	Move<VkDescriptorPool>											m_descriptorPool;

	Move<VkDescriptorSetLayout>										m_descriptorSetLayoutImg;
	Move<VkDescriptorSet>											m_descriptorSetImg;

	Move<VkDescriptorSetLayout>										m_descriptorSetLayoutAS;
	Move<VkDescriptorSet>											m_descriptorSetAS;

	Move<VkPipelineLayout>											m_pipelineLayout;
	Move<VkPipeline>												m_pipeline;

	Move<VkDescriptorUpdateTemplate>								m_updateTemplate;
};

BindingAcceleratioStructureTestInstance::BindingAcceleratioStructureTestInstance (Context& context, const TestParams& testParams)
	: TestInstance						(context)
	, m_testParams						(testParams)
	, m_bottomAccelerationStructures	()
	, m_topAccelerationStructure		()
	, m_descriptorPool					()
	, m_descriptorSetLayoutImg			()
	, m_descriptorSetImg				()
	, m_descriptorSetLayoutAS			()
	, m_descriptorSetAS					()
	, m_pipelineLayout					()
	, m_pipeline						()
	, m_updateTemplate					()
{
}

tcu::TestStatus BindingAcceleratioStructureTestInstance::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 bool											templateUpdateMethod					= isTemplateUpdateMethod(m_testParams.updateMethod);
	const bool											pushUpdateMethod						= isPushUpdateMethod(m_testParams.updateMethod);

	const deUint32										width									= m_testParams.width;
	const deUint32										height									= m_testParams.height;
	const deUint32										depth									= m_testParams.depth;
	const VkImageCreateInfo								imageCreateInfo							= makeImageCreateInfo(m_testParams.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_testParams.format, imageSubresourceRange);

	const deUint32										pixelSize								= mapVkFormat(m_testParams.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>							commandPool								= createCommandPool(vkd, device, 0, queueFamilyIndex);
	const Move<VkCommandBuffer>							commandBuffer							= allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	const VkAccelerationStructureKHR*					topAccelerationStructurePtr				= createAccelerationStructures(m_context, m_testParams);
	const VkWriteDescriptorSetAccelerationStructureKHR	writeDescriptorSetAccelerationStructure	= makeWriteDescriptorSetAccelerationStructureKHR(topAccelerationStructurePtr);
	const deUint32										accelerationStructureDescriptorCount	= 1 + getExtraAccelerationDescriptorCount();
	deUint32											updateCount								= 0;

	m_descriptorPool			= DescriptorPoolBuilder()
									.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
									.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, accelerationStructureDescriptorCount)
									.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u + accelerationStructureDescriptorCount);

	m_descriptorSetLayoutImg	= DescriptorSetLayoutBuilder()
									.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, getShaderStageFlags())
									.build(vkd, device);
	m_descriptorSetImg			= makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutImg);

	DescriptorSetUpdateBuilder()
		.writeSingle(*m_descriptorSetImg, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &resultImageInfo)
		.update(vkd, device);

	m_descriptorSetLayoutAS		= DescriptorSetLayoutBuilder()
									.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, getShaderStageFlags())
									.build(vkd, device, getDescriptorSetLayoutCreateFlags(m_testParams.updateMethod));
	m_descriptorSetAS			= makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutAS, m_testParams.updateMethod);

	initPipeline();

	if (m_testParams.updateMethod == UPDATE_METHOD_NORMAL)
	{
		DescriptorSetUpdateBuilder()
			.writeSingle(*m_descriptorSetAS, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &writeDescriptorSetAccelerationStructure)
			.update(vkd, device);

		updateCount++;
	}

	if (templateUpdateMethod)
	{
		const VkDescriptorUpdateTemplateType		updateTemplateType		= isPushUpdateMethod(m_testParams.updateMethod)
																			? VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR
																			: VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET;
		const VkDescriptorUpdateTemplateEntry		updateTemplateEntry		=
		{
			0,												//  deUint32			dstBinding;
			0,												//  deUint32			dstArrayElement;
			1,												//  deUint32			descriptorCount;
			VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR,	//  VkDescriptorType	descriptorType;
			0,												//  deUintptr			offset;
			0,												//  deUintptr			stride;
		};
		const VkDescriptorUpdateTemplateCreateInfo	templateCreateInfo	=
		{
			VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,	//  VkStructureType							sType;
			DE_NULL,														//  const void*								pNext;
			0,																//  VkDescriptorUpdateTemplateCreateFlags	flags;
			1,																//  deUint32								descriptorUpdateEntryCount;
			&updateTemplateEntry,											//  const VkDescriptorUpdateTemplateEntry*	pDescriptorUpdateEntries;
			updateTemplateType,												//  VkDescriptorUpdateTemplateType			templateType;
			*m_descriptorSetLayoutAS,										//  VkDescriptorSetLayout					descriptorSetLayout;
			getPipelineBindPoint(),											//  VkPipelineBindPoint						pipelineBindPoint;
			*m_pipelineLayout,												//  VkPipelineLayout						pipelineLayout;
			0,																//  deUint32								set;
		};

		m_updateTemplate = vk::createDescriptorUpdateTemplate(vkd, device, &templateCreateInfo);

		if (!pushUpdateMethod)
		{
			vkd.updateDescriptorSetWithTemplate(device, *m_descriptorSetAS, *m_updateTemplate, topAccelerationStructurePtr);

			updateCount++;
		}
	}

	beginCommandBuffer(vkd, *commandBuffer, 0u);
	{
		{
			const VkClearValue			clearValue				= makeClearValueColorU32(0u, 0u, 0u, 0u);
			const VkImageMemoryBarrier	preImageBarrier			= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, **image, imageSubresourceRange);
			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);

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

			vkd.cmdBindDescriptorSets(*commandBuffer, getPipelineBindPoint(), *m_pipelineLayout, 1, 1, &m_descriptorSetImg.get(), 0, DE_NULL);
		}

		switch (m_testParams.updateMethod)
		{
			case UPDATE_METHOD_NORMAL:			// fallthrough
			case UPDATE_METHOD_WITH_TEMPLATE:
			{
				vkd.cmdBindDescriptorSets(*commandBuffer, getPipelineBindPoint(), *m_pipelineLayout, 0, 1, &m_descriptorSetAS.get(), 0, DE_NULL);

				break;
			}

			case UPDATE_METHOD_WITH_PUSH:
			{
				DescriptorSetUpdateBuilder()
					.writeSingle(*m_descriptorSetAS, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &writeDescriptorSetAccelerationStructure)
					.updateWithPush(vkd, *commandBuffer, getPipelineBindPoint(), *m_pipelineLayout, 0, 0, 1);

				updateCount++;

				break;
			}

			case UPDATE_METHOD_WITH_PUSH_TEMPLATE:
			{
				vkd.cmdPushDescriptorSetWithTemplateKHR(*commandBuffer, *m_updateTemplate, *m_pipelineLayout, 0, topAccelerationStructurePtr);

				updateCount++;

				break;
			}

			default: TCU_THROW(InternalError, "Unknown update method");
		}

		{
			const VkMemoryBarrier		preTraceMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR, VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR);
			const VkPipelineStageFlags	dstStageFlags			= VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR;

			buildAccelerationStructures(m_context, m_testParams, *commandBuffer);

			cmdPipelineMemoryBarrier(vkd, *commandBuffer, VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR, dstStageFlags, &preTraceMemoryBarrier);
		}

		fillCommandBuffer(*commandBuffer);

		{
			const VkMemoryBarrier		postTestMemoryBarrier	= makeMemoryBarrier(VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);

			cmdPipelineMemoryBarrier(vkd, *commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &postTestMemoryBarrier);
		}

		vkd.cmdCopyImageToBuffer(*commandBuffer, **image, VK_IMAGE_LAYOUT_GENERAL, **resultBuffer, 1u, &resultBufferImageRegion);
	}
	endCommandBuffer(vkd, *commandBuffer);

	if (updateCount != 1)
		TCU_THROW(InternalError, "Invalid descriptor update");

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

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

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

const VkAccelerationStructureKHR* BindingAcceleratioStructureTestInstance::createAccelerationStructures (Context&		context,
																										 TestParams&	testParams)
{
	DE_UNREF(testParams);

	const DeviceInterface&							vkd											= context.getDeviceInterface();
	const VkDevice									device										= context.getDevice();
	Allocator&										allocator									= context.getDefaultAllocator();
	de::MovePtr<BottomLevelAccelerationStructure>	rayQueryBottomLevelAccelerationStructure	= makeBottomLevelAccelerationStructure();
	de::MovePtr<TopLevelAccelerationStructure>		rayQueryTopLevelAccelerationStructure		= makeTopLevelAccelerationStructure();
	std::vector<tcu::Vec3>							geometryData;

	// Generate in-plain square starting at (0,0,PLAIN_Z0) and ending at (1,1,PLAIN_Z1).
	// Vertices 1,0 and 0,1 by Z axis are in the middle between PLAIN_Z0 and PLAIN_Z1
	geometryData.push_back(tcu::Vec3(0.0f, 0.0f, PLAIN_Z0));
	geometryData.push_back(tcu::Vec3(1.0f, 0.0f, (PLAIN_Z0 + PLAIN_Z1) / 2.0f));
	geometryData.push_back(tcu::Vec3(0.0f, 1.0f, (PLAIN_Z0 + PLAIN_Z1) / 2.0f));
	geometryData.push_back(tcu::Vec3(1.0f, 1.0f, PLAIN_Z1));
	geometryData.push_back(tcu::Vec3(0.0f, 1.0f, (PLAIN_Z0 + PLAIN_Z1) / 2.0f));
	geometryData.push_back(tcu::Vec3(1.0f, 0.0f, (PLAIN_Z0 + PLAIN_Z1) / 2.0f));

	rayQueryBottomLevelAccelerationStructure->setGeometryCount(1u);
	rayQueryBottomLevelAccelerationStructure->addGeometry(geometryData, true);
	rayQueryBottomLevelAccelerationStructure->create(vkd, device, allocator, 0);
	m_bottomAccelerationStructures.push_back(de::SharedPtr<BottomLevelAccelerationStructure>(rayQueryBottomLevelAccelerationStructure.release()));

	m_topAccelerationStructure = de::SharedPtr<TopLevelAccelerationStructure>(rayQueryTopLevelAccelerationStructure.release());
	m_topAccelerationStructure->addInstance(m_bottomAccelerationStructures.back());
	m_topAccelerationStructure->create(vkd, device, allocator);

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

void BindingAcceleratioStructureTestInstance::buildAccelerationStructures	(Context&			context,
																			 TestParams&		testParams,
																			 VkCommandBuffer	commandBuffer)
{
	DE_UNREF(testParams);

	const DeviceInterface&	vkd		= context.getDeviceInterface();
	const VkDevice			device	= context.getDevice();

	for (size_t blStructNdx = 0; blStructNdx < m_bottomAccelerationStructures.size(); ++blStructNdx)
		m_bottomAccelerationStructures[blStructNdx]->build(vkd, device, commandBuffer);

	m_topAccelerationStructure->build(vkd, device, commandBuffer);
}

bool BindingAcceleratioStructureTestInstance::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*			retrieved	= (deInt32*)resultBuffer->getAllocation().getHostPtr();
	deUint32				failures	= 0;
	deUint32				pos			= 0;
	std::vector<deInt32>	expected;

	expected.reserve(width * height);

	for (deUint32 y = 0; y < height; ++y)
	{
		const float	expectedY	= deFloatMix(PLAIN_Z0, PLAIN_Z1, (0.5f + float(y)) / float(height));

		for (deUint32 x = 0; x < width; ++x)
		{
			const float		expectedX	= deFloatMix(PLAIN_Z0, PLAIN_Z1, (0.5f + float(x)) / float(width));
			const deInt32	expectedV	= deInt32(float(FIXED_POINT_DIVISOR / 2) * (expectedX + expectedY));

			expected.push_back(expectedV);
		}
	}

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

			if (failures < 10)
			{
				const deInt32	expectedValue	= expected[pos];
				const deInt32	retrievedValue	= retrieved[pos];

				log << tcu::TestLog::Message
					<< "At (" << x <<"," << y << ") "
					<< "expected " << std::fixed << std::setprecision(6) << std::setw(8) << float(expectedValue) / float(FIXED_POINT_DIVISOR) << " (" << expectedValue << ") "
					<< "retrieved " << std::fixed << std::setprecision(6) << std::setw(8) << float(retrievedValue) / float(FIXED_POINT_DIVISOR) << " (" << retrievedValue << ") "
					<< tcu::TestLog::EndMessage;
			}
		}

		pos++;
	}

	if (failures != 0)
	{
		for (deUint32 dumpNdx = 0; dumpNdx < 2; ++dumpNdx)
		{
			const deInt32*		data		= (dumpNdx == 0) ? expected.data() : retrieved;
			const char*			dataName	= (dumpNdx == 0) ? "Expected" : "Retrieved";
			std::ostringstream	css;

			pos = 0;

			for (deUint32 y = 0; y < height; ++y)
			{
				for (deUint32 x = 0; x < width; ++x)
				{
					if (expected[pos] != retrieved[pos])
						css << std::fixed << std::setprecision(6) << std::setw(8) << float(data[pos]) / float(FIXED_POINT_DIVISOR) << ",";
					else
						css << "________,";

					pos++;
				}

				css << std::endl;
			}

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

	return (failures == 0);
}


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

										BindingAcceleratioStructureGraphicsTestInstance		(Context&			context,
																							 const TestParams&	testParams);
	virtual								~BindingAcceleratioStructureGraphicsTestInstance	() {}

protected:
	virtual void						initPipeline										(void) override;
	virtual void						fillCommandBuffer									(VkCommandBuffer	commandBuffer) override;

	void								initVertexBuffer									(void);
	Move<VkPipeline>					makeGraphicsPipeline								(void);

	virtual deUint32					getExtraAccelerationDescriptorCount					(void) override									{ return 0; }
	virtual VkShaderStageFlags			getShaderStageFlags									(void) override									{ return VK_SHADER_STAGE_ALL_GRAPHICS; }
	virtual VkPipelineBindPoint			getPipelineBindPoint								(void) override									{ return VK_PIPELINE_BIND_POINT_GRAPHICS; }

	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;

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

BindingAcceleratioStructureGraphicsTestInstance::BindingAcceleratioStructureGraphicsTestInstance (Context&			context,
																								  const TestParams&	testParams)
	: BindingAcceleratioStructureTestInstance	(context, testParams)
	, 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_vertexCount								(0)
	, m_vertexBuffer							()
	, m_vertexBufferAlloc						()
{
}

void BindingAcceleratioStructureGraphicsTestInstance::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 BindingAcceleratioStructureGraphicsTestInstance::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"
					<< "\n"
					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\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"
					<< "\n"
					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
					<< "\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"
					<< "\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"
					<< "\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"
					<< "\n"
					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
					<< "\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"
					<< "\n"
					<< "layout(triangles) in;\n"
					<< "layout(points, max_vertices = 1) out;\n"
					<< "\n"
					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\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"
					<< "  gl_PointSize = 1.0;\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"
					<< "\n"
					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\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 BindingAcceleratioStructureGraphicsTestInstance::initVertexBuffer (void)
{
	const DeviceInterface&	vkd			= m_context.getDeviceInterface();
	const VkDevice			device		= m_context.getDevice();
	const deUint32			width		= m_testParams.width;
	const deUint32			height		= m_testParams.height;
	Allocator&				allocator	= m_context.getDefaultAllocator();
	std::vector<tcu::Vec4>	vertices;

	switch (m_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:
		{
			float z = 0.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, 1.0f));
				vertices.push_back(tcu::Vec4(xm, y1, z, 1.0f));
				vertices.push_back(tcu::Vec4(x1, ym, z, 1.0f));

				z += 1.f;
			}

			break;
		}

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

			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> BindingAcceleratioStructureGraphicsTestInstance::makeGraphicsPipeline (void)
{
	const DeviceInterface&			vkd					= m_context.getDeviceInterface();
	const VkDevice					device				= m_context.getDevice();
	const bool						tessStageTest		= (m_testParams.stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || m_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(m_testParams.width, m_testParams.height));
	const std::vector<VkRect2D>		scissors			(1, makeRect2D(m_testParams.width, m_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 BindingAcceleratioStructureGraphicsTestInstance::initPipeline (void)
{
	const DeviceInterface&	vkd			= m_context.getDeviceInterface();
	const VkDevice			device		= m_context.getDevice();
	Allocator&				allocator	= m_context.getDefaultAllocator();
	vk::BinaryCollection&	collection	= m_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_framebufferImage		= makeImage				(vkd, device, makeImageCreateInfo(m_framebufferFormat, m_testParams.width, m_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, m_testParams.width, m_testParams.height);
	m_pipelineLayout		= makePipelineLayout	(vkd, device, m_descriptorSetLayoutAS.get(), m_descriptorSetLayoutImg.get());
	m_pipeline				= makeGraphicsPipeline	();

	initVertexBuffer();
}

void BindingAcceleratioStructureGraphicsTestInstance::fillCommandBuffer (VkCommandBuffer	commandBuffer)
{
	const DeviceInterface&	vkd					= m_context.getDeviceInterface();
	const VkDeviceSize		vertexBufferOffset	= 0;

	vkd.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
	vkd.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &m_vertexBuffer.get(), &vertexBufferOffset);

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

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

	endRenderPass(vkd, commandBuffer);
}

class BindingAcceleratioStructureComputeTestInstance : public BindingAcceleratioStructureTestInstance
{
public:
									BindingAcceleratioStructureComputeTestInstance	(Context&			context,
																					 const TestParams&	testParams);

	virtual							~BindingAcceleratioStructureComputeTestInstance	() {}

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

protected:
	virtual void					initPipeline									(void) override;
	virtual void					fillCommandBuffer								(VkCommandBuffer	commandBuffer) override;

	virtual deUint32				getExtraAccelerationDescriptorCount				(void) override									{ return 0; }
	virtual VkShaderStageFlags		getShaderStageFlags								(void) override									{ return VK_SHADER_STAGE_COMPUTE_BIT; }
	virtual VkPipelineBindPoint		getPipelineBindPoint							(void) override									{ return VK_PIPELINE_BIND_POINT_COMPUTE; }

	Move<VkShaderModule>			m_shaderModule;
};

BindingAcceleratioStructureComputeTestInstance::BindingAcceleratioStructureComputeTestInstance (Context&			context,
																								const TestParams&	testParams)
	: BindingAcceleratioStructureTestInstance	(context, testParams)
	, m_shaderModule	()
{
}

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

void BindingAcceleratioStructureComputeTestInstance::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 << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
				<< "#extension GL_EXT_ray_query : require\n"
				<< "\n"
				<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
				<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
				<< "\n"
				<< "void main()\n"
				<< "{\n"
				<< testBody
				<< "}\n";

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

			break;
		}

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

void BindingAcceleratioStructureComputeTestInstance::initPipeline (void)
{
	const DeviceInterface&	vkd			= m_context.getDeviceInterface();
	const VkDevice			device		= m_context.getDevice();
	vk::BinaryCollection&	collection	= m_context.getBinaryCollection();

	m_shaderModule		= createShaderModule(vkd, device, collection.get("comp"), 0);
	m_pipelineLayout	= makePipelineLayout(vkd, device, m_descriptorSetLayoutAS.get(), m_descriptorSetLayoutImg.get());
	m_pipeline			= makeComputePipeline(vkd, device, *m_pipelineLayout, *m_shaderModule);
}

void BindingAcceleratioStructureComputeTestInstance::fillCommandBuffer (VkCommandBuffer	commandBuffer)
{
	const DeviceInterface&	vkd	= m_context.getDeviceInterface();

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

	vkd.cmdDispatch(commandBuffer, m_testParams.width, m_testParams.height, 1);
}

class BindingAcceleratioStructureRayTracingTestInstance : public BindingAcceleratioStructureTestInstance
{
public:
													BindingAcceleratioStructureRayTracingTestInstance	(Context&							context,
																										 const TestParams&					testParams);
	virtual											~BindingAcceleratioStructureRayTracingTestInstance	() {}

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

protected:
	virtual void									initPipeline										(void) override;
	virtual void									fillCommandBuffer									(VkCommandBuffer					commandBuffer) override;

	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);

	virtual deUint32								getExtraAccelerationDescriptorCount					(void) override													{ return 1; }
	virtual VkShaderStageFlags						getShaderStageFlags									(void) override													{ return ALL_RAY_TRACING_STAGES; }
	virtual VkPipelineBindPoint						getPipelineBindPoint								(void) override													{ return VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR; }

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

	Move<VkDescriptorSetLayout>						m_descriptorSetLayoutSvc;
	Move<VkDescriptorSet>							m_descriptorSetSvc;

	de::MovePtr<RayTracingPipeline>					m_rayTracingPipeline;

	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;
};

BindingAcceleratioStructureRayTracingTestInstance::BindingAcceleratioStructureRayTracingTestInstance (Context&			context,
																									  const TestParams&	testParams)
	: BindingAcceleratioStructureTestInstance	(context, testParams)
	, m_shaders									(0)
	, m_raygenShaderGroup						(~0u)
	, m_missShaderGroup							(~0u)
	, m_hitShaderGroup							(~0u)
	, m_callableShaderGroup						(~0u)
	, m_shaderGroupCount						(0)

	, m_descriptorSetLayoutSvc					()
	, m_descriptorSetSvc						()

	, m_rayTracingPipeline						()

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

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

	, m_bottomLevelAccelerationStructure		()
	, m_topLevelAccelerationStructure			()
{
}

void BindingAcceleratioStructureRayTracingTestInstance::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 BindingAcceleratioStructureRayTracingTestInstance::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;
	const std::string				commonRayGenerationShader	=
		std::string(glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460)) + "\n"
		"#extension GL_EXT_ray_tracing : require\n"
		"\n"
		"layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
		"layout(set = 2, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
		"\n"
		"void main()\n"
		"{\n"
		"  uint  rayFlags = 0;\n"
		"  uint  cullMask = 0xFF;\n"
		"  float tmin     = 0.0;\n"
		"  float tmax     = 9.0;\n"
		"  vec3  origin   = vec3((float(gl_LaunchIDEXT.x) + 0.5f) / float(gl_LaunchSizeEXT.x), (float(gl_LaunchIDEXT.y) + 0.5f) / float(gl_LaunchSizeEXT.y), 0.0);\n"
		"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
		"  traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
		"}\n";

	switch (testParams.stage)
	{
		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
		{
			std::stringstream css;
			css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
				<< "#extension GL_EXT_ray_tracing : require\n"
				<< "#extension GL_EXT_ray_query : require\n"
				<< "\n"
				<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
				<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
				<< "\n"
				<< "void main()\n"
				<< "{\n"
				<< testBody
				<< "}\n";

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

			break;
		}

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

			{
				std::stringstream css;
				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_ray_tracing : require\n"
					<< "#extension GL_EXT_ray_query : require\n"
					<< "\n"
					<< "hitAttributeEXT vec3 attribs;\n"
					<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
					<< "\n"
					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
					<< "\n"
					<< "void main()\n"
					<< "{\n"
					<< testBody
					<< "}\n";

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

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

			break;
		}

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

			{
				std::stringstream css;
				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_ray_tracing : require\n"
					<< "#extension GL_EXT_ray_query : require\n"
					<< "\n"
					<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
					<< "hitAttributeEXT vec3 attribs;\n"
					<< "\n"
					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
					<< "\n"
					<< "void main()\n"
					<< "{\n"
					<< testBody
					<< "}\n";

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

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

			break;
		}

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

			{
				std::stringstream css;
				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_ray_tracing : require\n"
					<< "#extension GL_EXT_ray_query : require\n"
					<< "hitAttributeEXT vec3 hitAttribute;\n"
					<< "\n"
					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\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(css.str()) << buildOptions;
			}

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

			break;
		}

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

			{
				std::stringstream css;
				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_ray_tracing : require\n"
					<< "#extension GL_EXT_ray_query : require\n"
					<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
					<< "\n"
					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
					<< "\n"
					<< "void main()\n"
					<< "{\n"
					<< testBody
					<< "}\n";

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

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

			break;
		}

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

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

			{
				std::stringstream css;
				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_ray_tracing : require\n"
					<< "#extension GL_EXT_ray_query : require\n"
					<< "layout(location = 0) callableDataInEXT float dummy;"
					<< "\n"
					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT tlas;\n"
					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
					<< "\n"
					<< "void main()\n"
					<< "{\n"
					<< testBody
					<< "}\n";

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

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

			break;
		}

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

void BindingAcceleratioStructureRayTracingTestInstance::initPipeline (void)
{
	const InstanceInterface&	vki						= m_context.getInstanceInterface();
	const DeviceInterface&		vkd						= m_context.getDeviceInterface();
	const VkDevice				device					= m_context.getDevice();
	const VkPhysicalDevice		physicalDevice			= m_context.getPhysicalDevice();
	vk::BinaryCollection&		collection				= m_context.getBinaryCollection();
	Allocator&					allocator				= m_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_descriptorSetLayoutSvc	= DescriptorSetLayoutBuilder()
									.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
									.build(vkd, device);
	m_descriptorSetSvc			= makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutSvc);

	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_descriptorSetLayoutAS.get(), m_descriptorSetLayoutImg.get(), m_descriptorSetLayoutSvc.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, 1);
	m_missShaderBindingTableRegion		= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_missShaderBindingTable),		shaderGroupHandleSize, 1);
	m_hitShaderBindingTableRegion		= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_hitShaderBindingTable),			shaderGroupHandleSize, 1);
	m_callableShaderBindingTableRegion	= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_callableShaderBindingTable),	shaderGroupHandleSize, 1);
}

void BindingAcceleratioStructureRayTracingTestInstance::fillCommandBuffer (VkCommandBuffer	commandBuffer)
{
	const DeviceInterface&							vkd									= m_context.getDeviceInterface();
	const VkDevice									device								= m_context.getDevice();
	Allocator&										allocator							= m_context.getDefaultAllocator();
	de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure	= makeBottomLevelAccelerationStructure();
	de::MovePtr<TopLevelAccelerationStructure>		topLevelAccelerationStructure		= makeTopLevelAccelerationStructure();

	m_bottomLevelAccelerationStructure = de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release());
	m_bottomLevelAccelerationStructure->setDefaultGeometryData(m_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	= makeWriteDescriptorSetAccelerationStructureKHR(topLevelAccelerationStructurePtr->getPtr());

	DescriptorSetUpdateBuilder()
		.writeSingle(*m_descriptorSetSvc, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
		.update(vkd, device);

	vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *m_pipelineLayout, 2, 1, &m_descriptorSetSvc.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,
		m_testParams.width, m_testParams.height, 1);
}

de::MovePtr<BufferWithMemory> BindingAcceleratioStructureRayTracingTestInstance::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;
}


class BindingAcceleratioStructureRayTracingRayTracingTestInstance : public BindingAcceleratioStructureTestInstance
{
public:
													BindingAcceleratioStructureRayTracingRayTracingTestInstance		(Context&							context,
																													 const TestParams&					testParams);
	virtual											~BindingAcceleratioStructureRayTracingRayTracingTestInstance	() {}

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

protected:
	virtual void									initPipeline													(void) override;
	virtual void									fillCommandBuffer												(VkCommandBuffer					commandBuffer) override;

	void											calcShaderGroup													(deUint32&							shaderGroupCounter,
																													 const VkShaderStageFlags			shaders1,
																													 const VkShaderStageFlags			shaders2,
																													 const VkShaderStageFlags			shaderStageFlags,
																													 deUint32&							shaderGroup,
																													 deUint32&							shaderGroupCount) const;


	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,
																													 const deUint32						groupCount = 1);

	virtual deUint32								getExtraAccelerationDescriptorCount								(void) override													{ return 1; }
	virtual VkShaderStageFlags						getShaderStageFlags												(void) override													{ return ALL_RAY_TRACING_STAGES; }
	virtual VkPipelineBindPoint						getPipelineBindPoint											(void) override													{ return VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR; }

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

	Move<VkDescriptorSetLayout>						m_descriptorSetLayoutSvc;
	Move<VkDescriptorSet>							m_descriptorSetSvc;

	de::MovePtr<RayTracingPipeline>					m_rayTracingPipeline;

	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;
};

BindingAcceleratioStructureRayTracingRayTracingTestInstance::BindingAcceleratioStructureRayTracingRayTracingTestInstance (Context&			context,
																														  const TestParams&	testParams)
	: BindingAcceleratioStructureTestInstance	(context, testParams)
	, m_shaders									(0)
	, m_raygenShaderGroup						(~0u)
	, m_missShaderGroup							(~0u)
	, m_hitShaderGroup							(~0u)
	, m_callableShaderGroup						(~0u)
	, m_shaderGroupCount						(0)

	, m_descriptorSetLayoutSvc					()
	, m_descriptorSetSvc						()

	, m_rayTracingPipeline						()

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

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

	, m_bottomLevelAccelerationStructure		()
	, m_topLevelAccelerationStructure			()
{
}

void BindingAcceleratioStructureRayTracingRayTracingTestInstance::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 BindingAcceleratioStructureRayTracingRayTracingTestInstance::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;
	const std::string				testOutClosestHitShader		=
		std::string(glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460)) + "\n"
		"#extension GL_EXT_ray_tracing : require\n"
		"\n"
		"hitAttributeEXT vec3 attribs;\n"
		"layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
		"layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
		"\n"
		"void main()\n"
		"{\n"
		+ testBody +
		"}\n";
	const std::string				testInShaderFragment		=
		"  uint  rayFlags = 0;\n"
		"  uint  cullMask = 0xFF;\n"
		"  float tmin     = 0.0;\n"
		"  float tmax     = 9.0;\n"
		"  vec3  origin   = vec3((float(gl_LaunchIDEXT.x) + 0.5f) / float(gl_LaunchSizeEXT.x), (float(gl_LaunchIDEXT.y) + 0.5f) / float(gl_LaunchSizeEXT.y), 0.0);\n"
		"  vec3  direct   = vec3(0.0, 0.0, 1.0);\n"
		"\n"
		"  traceRayEXT(topLevelAS, rayFlags, cullMask, 1, 0, 1, origin, tmin, direct, tmax, 0);\n";
	const std::string				commonRayGenerationShader	=
		std::string(glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460)) + "\n"
		"#extension GL_EXT_ray_tracing : require\n"
		"\n"
		"layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
		"layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
		"layout(set = 2, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
		"\n"
		"void main()\n"
		"{\n"
		"  uint  rayFlags = 0;\n"
		"  uint  cullMask = 0xFF;\n"
		"  float tmin     = 0.0;\n"
		"  float tmax     = 9.0;\n"
		"  vec3  origin   = vec3((float(gl_LaunchIDEXT.x) + 0.5f) / float(gl_LaunchSizeEXT.x), (float(gl_LaunchIDEXT.y) + 0.5f) / float(gl_LaunchSizeEXT.y), 0.0);\n"
		"  vec3  direct   = vec3(0.0, 0.0, -1.0);\n"
		"\n"
		"  traceRayEXT(topLevelAS, rayFlags, cullMask, 0, 0, 0, origin, tmin, direct, tmax, 0);\n"
		"}\n";

	programCollection.glslSources.add("chit0") << glu::ClosestHitSource(testOutClosestHitShader) << buildOptions;
	programCollection.glslSources.add("ahit0") << glu::AnyHitSource(getHitPassthrough()) << buildOptions;
	programCollection.glslSources.add("miss0") << glu::MissSource(getMissPassthrough()) << buildOptions;

	switch (testParams.stage)
	{
		case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
		{
			{
				std::stringstream css;
				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_ray_tracing : require\n"
					<< "\n"
					<< "layout(location = 0) rayPayloadEXT vec3 hitValue;\n"
					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
					<< "\n"
					<< "void main()\n"
					<< "{\n"
					<< testInShaderFragment
					<< "}\n";

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

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

			break;
		}

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

			{
				std::stringstream css;
				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_ray_tracing : require\n"
					<< "\n"
					<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
					<< "hitAttributeEXT vec3 attribs;\n"
					<< "\n"
					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
					<< "\n"
					<< "void main()\n"
					<< "{\n"
					<< testInShaderFragment
					<< "}\n";

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

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

			break;
		}

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

			{
				std::stringstream css;
				css << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_460) << "\n"
					<< "#extension GL_EXT_ray_tracing : require\n"
					<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
					<< "\n"
					<< "layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;\n"
					<< "layout(set = 1, binding = 0, r32i) uniform iimage3D result;\n"
					<< "\n"
					<< "void main()\n"
					<< "{\n"
					<< testInShaderFragment
					<< "}\n";

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

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

			break;
		}

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

void BindingAcceleratioStructureRayTracingRayTracingTestInstance::calcShaderGroup (deUint32&				shaderGroupCounter,
																				   const VkShaderStageFlags	shaders1,
																				   const VkShaderStageFlags	shaders2,
																				   const VkShaderStageFlags	shaderStageFlags,
																				   deUint32&				shaderGroup,
																				   deUint32&				shaderGroupCount) const
{
	const deUint32	shader1Count = ((shaders1 & shaderStageFlags) != 0) ? 1 : 0;
	const deUint32	shader2Count = ((shaders2 & shaderStageFlags) != 0) ? 1 : 0;

	shaderGroupCount = shader1Count + shader2Count;

	if (shaderGroupCount != 0)
	{
		shaderGroup			= shaderGroupCounter;
		shaderGroupCounter += shaderGroupCount;
	}
}

void BindingAcceleratioStructureRayTracingRayTracingTestInstance::initPipeline (void)
{
	const InstanceInterface&	vki						= m_context.getInstanceInterface();
	const DeviceInterface&		vkd						= m_context.getDeviceInterface();
	const VkDevice				device					= m_context.getDevice();
	const VkPhysicalDevice		physicalDevice			= m_context.getPhysicalDevice();
	vk::BinaryCollection&		collection				= m_context.getBinaryCollection();
	Allocator&					allocator				= m_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;
	VkShaderStageFlags			shaders0				= static_cast<VkShaderStageFlags>(0);
	deUint32					raygenShaderGroupCount	= 0;
	deUint32					hitShaderGroupCount		= 0;
	deUint32					missShaderGroupCount	= 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("ahit0")) shaders0 |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR;
	if (collection.contains("chit0")) shaders0 |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;
	if (collection.contains("miss0")) shaders0 |= VK_SHADER_STAGE_MISS_BIT_KHR;

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

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

	calcShaderGroup(m_shaderGroupCount, m_shaders, shaders0, VK_SHADER_STAGE_RAYGEN_BIT_KHR, m_raygenShaderGroup, raygenShaderGroupCount);
	calcShaderGroup(m_shaderGroupCount, m_shaders, shaders0, VK_SHADER_STAGE_MISS_BIT_KHR,   m_missShaderGroup,   missShaderGroupCount);
	calcShaderGroup(m_shaderGroupCount, m_shaders, shaders0, hitStages,                      m_hitShaderGroup,    hitShaderGroupCount);

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

	m_descriptorSetLayoutSvc	= DescriptorSetLayoutBuilder()
									.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, ALL_RAY_TRACING_STAGES)
									.build(vkd, device);
	m_descriptorSetSvc			= makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutSvc);

	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);

	// The "chit" and "miss" cases both generate more rays from their shaders.
	if (m_testParams.testType == TEST_TYPE_USING_RAY_TRACING && (m_testParams.stage == VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR || m_testParams.stage == VK_SHADER_STAGE_MISS_BIT_KHR))
		m_rayTracingPipeline->setMaxRecursionDepth(2u);

	if (0 != (shaders0 & VK_SHADER_STAGE_ANY_HIT_BIT_KHR))			m_rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR			, createShaderModule(vkd, device, collection.get("ahit0"), 0), m_hitShaderGroup + 1);
	if (0 != (shaders0 & VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR))		m_rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR		, createShaderModule(vkd, device, collection.get("chit0"), 0), m_hitShaderGroup + 1);
	if (0 != (shaders0 & VK_SHADER_STAGE_MISS_BIT_KHR))				m_rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR			, createShaderModule(vkd, device, collection.get("miss0"), 0), m_missShaderGroup + 1);

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

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

	m_raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_raygenShaderBindingTable),	shaderGroupHandleSize, raygenShaderGroupCount);
	m_missShaderBindingTableRegion		= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_missShaderBindingTable),	shaderGroupHandleSize, missShaderGroupCount);
	m_hitShaderBindingTableRegion		= makeStridedDeviceAddressRegion(vkd, device, getVkBuffer(m_hitShaderBindingTable),		shaderGroupHandleSize, hitShaderGroupCount);
	m_callableShaderBindingTableRegion	= makeStridedDeviceAddressRegion(vkd, device, DE_NULL, 0, 0);
}

void BindingAcceleratioStructureRayTracingRayTracingTestInstance::fillCommandBuffer (VkCommandBuffer	commandBuffer)
{
	const DeviceInterface&							vkd									= m_context.getDeviceInterface();
	const VkDevice									device								= m_context.getDevice();
	Allocator&										allocator							= m_context.getDefaultAllocator();
	de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure	= makeBottomLevelAccelerationStructure();
	de::MovePtr<TopLevelAccelerationStructure>		topLevelAccelerationStructure		= makeTopLevelAccelerationStructure();

	m_bottomLevelAccelerationStructure = de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release());
	m_bottomLevelAccelerationStructure->setDefaultGeometryData(m_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	= makeWriteDescriptorSetAccelerationStructureKHR(topLevelAccelerationStructurePtr->getPtr());

	DescriptorSetUpdateBuilder()
		.writeSingle(*m_descriptorSetSvc, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelerationStructureWriteDescriptorSet)
		.update(vkd, device);

	vkd.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, *m_pipelineLayout, 2, 1, &m_descriptorSetSvc.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,
		m_testParams.width, m_testParams.height, 1);
}

de::MovePtr<BufferWithMemory> BindingAcceleratioStructureRayTracingRayTracingTestInstance::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,
																													 const deUint32						groupCount)
{
	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, groupCount);
	}

	return shaderBindingTable;
}


const std::string getRayQueryShaderBodyText (const TestParams& testParams)
{
	DE_UNREF(testParams);

	const std::string result =
		"  const float mult     = " + de::toString(FIXED_POINT_DIVISOR) + ".0f;\n"
		"  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"
		"  int         value    = 0;\n"
		"  rayQueryEXT rayQuery;\n"
		"\n"
		"  rayQueryInitializeEXT(rayQuery, tlas, rayFlags, cullMask, origin, tmin, direct, tmax);\n"
		"\n"
		"  while(rayQueryProceedEXT(rayQuery))\n"
		"  {\n"
		"    if (rayQueryGetIntersectionTypeEXT(rayQuery, false) == gl_RayQueryCandidateIntersectionTriangleEXT)\n"
		"    {\n"
		"      const float t = rayQueryGetIntersectionTEXT(rayQuery, false);"
		"\n"
		"      value = int(round(mult * t));\n"
		"    }\n"
		"  }\n"
		"\n"
		"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";

	return result;
}

const std::string getRayTracingShaderBodyText (const TestParams& testParams)
{
	DE_UNREF(testParams);

	const std::string result =
		"  const float mult     = " + de::toString(FIXED_POINT_DIVISOR) + ".0f;\n"
		"  int         value    = int(round(mult * gl_HitTEXT));\n"
		"\n"
		"  imageStore(result, pos, ivec4(value, 0, 0, 0));\n";

	return result;
}

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

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

private:
	TestParams				m_testParams;
};

BindingAccelerationStructureTestCase::BindingAccelerationStructureTestCase (tcu::TestContext& context, const char* name, const char* desc, const TestParams testParams)
	: vkt::TestCase	(context, name, desc)
	, m_testParams		(testParams)
{
}

BindingAccelerationStructureTestCase::~BindingAccelerationStructureTestCase (void)
{
}

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

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

	switch (m_testParams.testType)
	{
		case TEST_TYPE_USING_RAY_QUERY:
		{
			context.requireDeviceFunctionality("VK_KHR_ray_query");

			const VkPhysicalDeviceRayQueryFeaturesKHR&	rayQueryFeaturesKHR	= context.getRayQueryFeatures();

			if (rayQueryFeaturesKHR.rayQuery == DE_FALSE)
				TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayQueryFeaturesKHR.rayQuery");

			break;
		}

		case TEST_TYPE_USING_RAY_TRACING:
		{
			context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");

			const VkPhysicalDeviceRayTracingPipelineFeaturesKHR&	rayTracingPipelineFeaturesKHR = context.getRayTracingPipelineFeatures();

			if (rayTracingPipelineFeaturesKHR.rayTracingPipeline == DE_FALSE)
				TCU_THROW(NotSupportedError, "Requires VkPhysicalDeviceRayTracingPipelineFeaturesKHR.rayTracingPipeline");

			break;
		}

		default:
			TCU_THROW(InternalError, "Unknown test type");
	}

	switch (m_testParams.updateMethod)
	{
		case UPDATE_METHOD_NORMAL:
		{
			break;
		}

		case UPDATE_METHOD_WITH_TEMPLATE:
		{
			context.requireDeviceFunctionality("VK_KHR_descriptor_update_template");

			break;
		}

		case UPDATE_METHOD_WITH_PUSH:
		{
			context.requireDeviceFunctionality("VK_KHR_push_descriptor");

			break;
		}

		case UPDATE_METHOD_WITH_PUSH_TEMPLATE:
		{
			context.requireDeviceFunctionality("VK_KHR_push_descriptor");
			context.requireDeviceFunctionality("VK_KHR_descriptor_update_template");

			break;
		}

		default:
			TCU_THROW(InternalError, "Unknown update method");
	}

	m_testParams.pipelineCheckSupport(context, m_testParams);
}

TestInstance* BindingAccelerationStructureTestCase::createInstance (Context& context) const
{
	switch (m_testParams.testType)
	{
		case TEST_TYPE_USING_RAY_QUERY:
		{
			switch (m_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:
				case VK_SHADER_STAGE_FRAGMENT_BIT:
				{
					return new BindingAcceleratioStructureGraphicsTestInstance(context, m_testParams);
				}

				case VK_SHADER_STAGE_COMPUTE_BIT:
				{
					return new BindingAcceleratioStructureComputeTestInstance(context, m_testParams);
				}

				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 new BindingAcceleratioStructureRayTracingTestInstance(context, m_testParams);
				}

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

		case TEST_TYPE_USING_RAY_TRACING:
		{
			return new BindingAcceleratioStructureRayTracingRayTracingTestInstance(context, m_testParams);
		}

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

void BindingAccelerationStructureTestCase::initPrograms (SourceCollections& programCollection) const
{
	m_testParams.pipelineInitPrograms(programCollection, m_testParams);
}

static inline CheckSupportFunc getPipelineRayQueryCheckSupport (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 BindingAcceleratioStructureGraphicsTestInstance::checkSupport;

		case VK_SHADER_STAGE_COMPUTE_BIT:
			return BindingAcceleratioStructureComputeTestInstance::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 BindingAcceleratioStructureRayTracingTestInstance::checkSupport;

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

static inline CheckSupportFunc getPipelineRayTracingCheckSupport (const VkShaderStageFlagBits stage)
{
	DE_UNREF(stage);

	return BindingAcceleratioStructureRayTracingRayTracingTestInstance::checkSupport;
}

static inline InitProgramsFunc getPipelineRayQueryInitPrograms (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 BindingAcceleratioStructureGraphicsTestInstance::initPrograms;

		case VK_SHADER_STAGE_COMPUTE_BIT:
			return BindingAcceleratioStructureComputeTestInstance::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 BindingAcceleratioStructureRayTracingTestInstance::initPrograms;

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

static inline InitProgramsFunc getPipelineRayTracingInitPrograms (const VkShaderStageFlagBits stage)
{
	DE_UNREF(stage);

	return BindingAcceleratioStructureRayTracingRayTracingTestInstance::initPrograms;
}

static inline ShaderBodyTextFunc getShaderBodyTextFunc (const TestType testType)
{
	switch (testType)
	{
		case TEST_TYPE_USING_RAY_QUERY:		return getRayQueryShaderBodyText;
		case TEST_TYPE_USING_RAY_TRACING:	return getRayTracingShaderBodyText;
		default:							TCU_THROW(InternalError, "Unknown test type");
	}
}

}	// anonymous

tcu::TestCaseGroup* createDescriptorUpdateASTests (tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> group	(new tcu::TestCaseGroup(testCtx, "acceleration_structure", "Tests acceleration structure descriptor updates"));

	const struct TestTypes
	{
		TestType	testType;
		const char*	name;
	}
	testTypes[] =
	{
		{ TEST_TYPE_USING_RAY_QUERY,	"ray_query"		},
		{ TEST_TYPE_USING_RAY_TRACING,	"ray_tracing"	},
	};
	const struct UpdateMethods
	{
		const UpdateMethod	method;
		const char*			name;
		const char*			description;
	}
	updateMethods[] =
	{
		{ UPDATE_METHOD_NORMAL,				"regular",				"Use regular descriptor updates"		},
		{ UPDATE_METHOD_WITH_TEMPLATE,		"with_template",		"Use descriptor update templates"		},
		{ UPDATE_METHOD_WITH_PUSH,			"with_push",			"Use push descriptor updates"			},
		{ UPDATE_METHOD_WITH_PUSH_TEMPLATE,	"with_push_template",	"Use push descriptor update templates"	},
	};
	const struct PipelineStages
	{
		VkShaderStageFlagBits	stage;
		const char*				name;
		const bool				rayTracing;
	}
	pipelineStages[] =
	{
		{ VK_SHADER_STAGE_VERTEX_BIT,					"vert",	false	},
		{ VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,		"tesc",	false	},
		{ VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,	"tese",	false	},
		{ VK_SHADER_STAGE_GEOMETRY_BIT,					"geom",	false	},
		{ VK_SHADER_STAGE_FRAGMENT_BIT,					"frag",	false	},
		{ VK_SHADER_STAGE_COMPUTE_BIT,					"comp",	false	},
		{ VK_SHADER_STAGE_RAYGEN_BIT_KHR,				"rgen",	true	},
		{ VK_SHADER_STAGE_ANY_HIT_BIT_KHR,				"ahit",	false	},
		{ VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,			"chit",	true	},
		{ VK_SHADER_STAGE_MISS_BIT_KHR,					"miss",	true	},
		{ VK_SHADER_STAGE_INTERSECTION_BIT_KHR,			"sect",	false	},
		{ VK_SHADER_STAGE_CALLABLE_BIT_KHR,				"call",	false	},
	};

	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 updateMethodsNdx = 0; updateMethodsNdx < DE_LENGTH_OF_ARRAY(updateMethods); ++updateMethodsNdx)
		{
			de::MovePtr<tcu::TestCaseGroup>	updateMethodsGroup		(new tcu::TestCaseGroup(group->getTestContext(), updateMethods[updateMethodsNdx].name, updateMethods[updateMethodsNdx].description));
			const UpdateMethod				updateMethod			= updateMethods[updateMethodsNdx].method;

			for (size_t pipelineStageNdx = 0; pipelineStageNdx < DE_LENGTH_OF_ARRAY(pipelineStages); ++pipelineStageNdx)
			{
				const VkShaderStageFlagBits	stage					= pipelineStages[pipelineStageNdx].stage;
				const CheckSupportFunc		pipelineCheckSupport	= (testType == TEST_TYPE_USING_RAY_QUERY)
																	? getPipelineRayQueryCheckSupport(stage)
																	: getPipelineRayTracingCheckSupport(stage);
				const InitProgramsFunc		pipelineInitPrograms	= (testType == TEST_TYPE_USING_RAY_QUERY)
																	? getPipelineRayQueryInitPrograms(stage)
																	: getPipelineRayTracingInitPrograms(stage);

				if (testType == TEST_TYPE_USING_RAY_TRACING && !pipelineStages[pipelineStageNdx].rayTracing)
					continue;

				const TestParams	testParams	=
				{
					TEST_WIDTH,				//  deUint32				width;
					TEST_HEIGHT,			//  deUint32				height;
					imageDepth,				//  deUint32				depth;
					testType,				//  TestType				testType;
					updateMethod,			//  UpdateMethod			updateMethod;
					stage,					//  VkShaderStageFlagBits	stage;
					VK_FORMAT_R32_SINT,		//  VkFormat				format;
					pipelineCheckSupport,	//  CheckSupportFunc		pipelineCheckSupport;
					pipelineInitPrograms,	//  InitProgramsFunc		pipelineInitPrograms;
					shaderBodyTextFunc,		//  ShaderTestTextFunc		testConfigShaderBodyText;
				};

				updateMethodsGroup->addChild(new BindingAccelerationStructureTestCase(group->getTestContext(), pipelineStages[pipelineStageNdx].name, "", testParams));
			}

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

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

	return group.release();
}

}	// RayQuery
}	// vkt
