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

#include "vktRayTracingBarrierTests.hpp"
#include "vktTestCase.hpp"

#include "vkDefs.hpp"
#include "vkQueryUtil.hpp"
#include "vkRayTracingUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkBufferWithMemory.hpp"
#include "vkTypeUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vkImageWithMemory.hpp"
#include "vkBuilderUtil.hpp"
#include "vkCmdUtil.hpp"

#include "deUniquePtr.hpp"

#include <string>
#include <sstream>
#include <memory>
#include <numeric>
#include <vector>
#include <algorithm>

namespace vkt
{
namespace RayTracing
{

namespace
{

using namespace vk;

constexpr deUint32				kBufferElements	= 1024u;
constexpr deUint32				kBufferSize		= kBufferElements * static_cast<deUint32>(sizeof(tcu::UVec4));	// std140
constexpr deUint32				kBufferSize430	= kBufferElements * static_cast<deUint32>(sizeof(deUint32));	// std430
constexpr deUint32				kValuesOffset	= 2048u;
constexpr deUint32				kImageDim		= 32u;					// So that kImageDim*kImageDim == kBufferElements.
constexpr VkFormat				kImageFormat	= VK_FORMAT_R32_UINT;	// So that each pixel has the same size as a deUint32.
const auto						kImageExtent	= makeExtent3D(kImageDim, kImageDim, 1u);
const std::vector<tcu::Vec4>	kFullScreenQuad	=
{
	tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
	tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f),
	tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
	tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f),
	tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f),
	tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
};


enum class Stage
{
	HOST = 0,
	TRANSFER,
	RAYGEN,
	INTERSECT,
	ANY_HIT,
	CLOSEST_HIT,
	MISS,
	CALLABLE,
	COMPUTE,
	FRAGMENT,
};

VkImageLayout getOptimalReadLayout (Stage stage)
{
	VkImageLayout layout = VK_IMAGE_LAYOUT_UNDEFINED;

	switch (stage)
	{
	case Stage::HOST:
		break; // Images will not be read directly from the host.
	case Stage::TRANSFER:
		layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
		break;
	case Stage::RAYGEN:
	case Stage::INTERSECT:
	case Stage::ANY_HIT:
	case Stage::CLOSEST_HIT:
	case Stage::MISS:
	case Stage::CALLABLE:
	case Stage::COMPUTE:
	case Stage::FRAGMENT:
		layout = VK_IMAGE_LAYOUT_GENERAL;
		break;
	default:
		DE_ASSERT(false);
		break;
	}

	return layout;
}

VkPipelineStageFlagBits getPipelineStage (Stage stage)
{
	VkPipelineStageFlagBits bits = VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM;

	switch (stage)
	{
	case Stage::HOST:
		bits = VK_PIPELINE_STAGE_HOST_BIT;
		break;
	case Stage::TRANSFER:
		bits = VK_PIPELINE_STAGE_TRANSFER_BIT;
		break;
	case Stage::RAYGEN:
	case Stage::INTERSECT:
	case Stage::ANY_HIT:
	case Stage::CLOSEST_HIT:
	case Stage::MISS:
	case Stage::CALLABLE:
		bits = VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR;
		break;
	case Stage::COMPUTE:
		bits = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
		break;
	case Stage::FRAGMENT:
		bits = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
		break;
	default:
		DE_ASSERT(false);
		break;
	}

	return bits;
}

VkAccessFlagBits getWriterAccessFlag (Stage stage)
{
	VkAccessFlagBits bits = VK_ACCESS_FLAG_BITS_MAX_ENUM;

	switch (stage)
	{
	case Stage::HOST:
		bits = VK_ACCESS_HOST_WRITE_BIT;
		break;
	case Stage::TRANSFER:
		bits = VK_ACCESS_TRANSFER_WRITE_BIT;
		break;
	case Stage::RAYGEN:
	case Stage::INTERSECT:
	case Stage::ANY_HIT:
	case Stage::CLOSEST_HIT:
	case Stage::MISS:
	case Stage::CALLABLE:
	case Stage::COMPUTE:
	case Stage::FRAGMENT:
		bits = VK_ACCESS_SHADER_WRITE_BIT;
		break;
	default:
		DE_ASSERT(false);
		break;
	}

	return bits;
}

VkAccessFlagBits getReaderAccessFlag (Stage stage, VkDescriptorType resourceType)
{
	VkAccessFlagBits bits = VK_ACCESS_FLAG_BITS_MAX_ENUM;

	switch (stage)
	{
	case Stage::HOST:
		bits = VK_ACCESS_HOST_READ_BIT;
		break;
	case Stage::TRANSFER:
		bits = VK_ACCESS_TRANSFER_READ_BIT;
		break;
	case Stage::RAYGEN:
	case Stage::INTERSECT:
	case Stage::ANY_HIT:
	case Stage::CLOSEST_HIT:
	case Stage::MISS:
	case Stage::CALLABLE:
	case Stage::COMPUTE:
	case Stage::FRAGMENT:
		bits = ((resourceType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ? VK_ACCESS_UNIFORM_READ_BIT : VK_ACCESS_SHADER_READ_BIT);
		break;
	default:
		DE_ASSERT(false);
		break;
	}

	return bits;
}

// Translate a stage to the corresponding single stage flag.
VkShaderStageFlagBits getShaderStageFlagBits (Stage stage)
{
	VkShaderStageFlagBits bits = VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM;

	switch (stage)
	{
	case Stage::RAYGEN:			bits = VK_SHADER_STAGE_RAYGEN_BIT_KHR;			break;
	case Stage::INTERSECT:		bits = VK_SHADER_STAGE_INTERSECTION_BIT_KHR;	break;
	case Stage::ANY_HIT:		bits = VK_SHADER_STAGE_ANY_HIT_BIT_KHR;			break;
	case Stage::CLOSEST_HIT:	bits = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR;		break;
	case Stage::MISS:			bits = VK_SHADER_STAGE_MISS_BIT_KHR;			break;
	case Stage::CALLABLE:		bits = VK_SHADER_STAGE_CALLABLE_BIT_KHR;		break;
	case Stage::COMPUTE:		bits = VK_SHADER_STAGE_COMPUTE_BIT;				break;
	case Stage::FRAGMENT:		bits = VK_SHADER_STAGE_FRAGMENT_BIT;			break;
	default:					DE_ASSERT(false);								break;
	}

	return bits;
}

// Gets shader stage flags that will be used when choosing a given stage.
VkShaderStageFlags getStageFlags (Stage stage)
{
	VkShaderStageFlags flags = 0u;

	switch (stage)
	{
	case Stage::HOST:			break;
	case Stage::TRANSFER:		break;
	case Stage::RAYGEN:			flags |= (VK_SHADER_STAGE_RAYGEN_BIT_KHR);											break;
	case Stage::INTERSECT:		flags |= (VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_INTERSECTION_BIT_KHR);	break;
	case Stage::ANY_HIT:		flags |= (VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR);		break;
	case Stage::CLOSEST_HIT:	flags |= (VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR);	break;
	case Stage::MISS:			flags |= (VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR);			break;
	case Stage::CALLABLE:		flags |= (VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_CALLABLE_BIT_KHR);		break;
	case Stage::COMPUTE:		flags |= (VK_SHADER_STAGE_COMPUTE_BIT);												break;
	case Stage::FRAGMENT:		flags |= (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);				break;
	default:					DE_ASSERT(false);																	break;
	}

	return flags;
}

bool isRayTracingStage (Stage stage)
{
	bool isRT = false;

	switch (stage)
	{
	case Stage::HOST:
	case Stage::TRANSFER:
	case Stage::COMPUTE:
	case Stage::FRAGMENT:
		break;

	case Stage::RAYGEN:
	case Stage::INTERSECT:
	case Stage::ANY_HIT:
	case Stage::CLOSEST_HIT:
	case Stage::MISS:
	case Stage::CALLABLE:
		isRT = true;
		break;

	default:
		DE_ASSERT(false);
		break;
	}

	return isRT;
}

enum class BarrierType
{
	GENERAL		= 0,
	SPECIFIC	= 1,
};

struct TestParams
{
	VkDescriptorType	resourceType;
	Stage				writerStage;
	Stage				readerStage;
	BarrierType			barrierType;

	TestParams (VkDescriptorType resourceType_, Stage writerStage_, Stage readerStage_, BarrierType barrierType_)
		: resourceType	(resourceType_)
		, writerStage	(writerStage_)
		, readerStage	(readerStage_)
		, barrierType	(barrierType_)
	{
		DE_ASSERT(resourceType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
				  resourceType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER ||
				  resourceType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
	}
};

bool resourceNeedsHostVisibleMemory (const TestParams& params)
{
	return (params.writerStage == Stage::HOST || params.readerStage == Stage::HOST);
}

bool needsAccelerationStructure (Stage stage)
{
	bool needed;

	switch (stage)
	{
	case Stage::INTERSECT:
	case Stage::ANY_HIT:
	case Stage::CLOSEST_HIT:
	case Stage::MISS:
	case Stage::CALLABLE:
		needed = true;
		break;
	default:
		needed = false;
		break;
	}

	return needed;
}

// The general idea is having a resource like a buffer or image that is generated from a given pipeline stage (including host,
// transfer and all ray shader stages) and read from another stage, using a barrier to synchronize access to the resource. Read
// values are copied to an output host-visible buffer for verification.

class BarrierTestCase : public vkt::TestCase
{
public:
							BarrierTestCase		(tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& testParams);
	virtual					~BarrierTestCase	(void) {}

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

private:
	TestParams				m_params;
};

class BarrierTestInstance : public vkt::TestInstance
{
public:
								BarrierTestInstance		(Context& context, const TestParams& testParams);
	virtual						~BarrierTestInstance	(void) {}

	virtual tcu::TestStatus		iterate					(void);

private:
	TestParams					m_params;
};

BarrierTestCase::BarrierTestCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& testParams)
	: vkt::TestCase	(testCtx, name, description)
	, m_params		(testParams)
{
}

void BarrierTestCase::initPrograms (SourceCollections& programCollection) const
{
	const auto&					wstage					= m_params.writerStage;
	const auto&					rstage					= m_params.readerStage;
	const bool					readNeedAS				= needsAccelerationStructure(rstage);
	const deUint32				readerVerifierBinding	= (readNeedAS ? 2u : 1u); // 0 is the barrier resource, 1 may be the AS.
	const ShaderBuildOptions	buildOptions			(programCollection.usedVulkanVersion, SPIRV_VERSION_1_4, 0u, true);
	const std::string			valStatement			= "  const uint  val  = id1d + " + de::toString(kValuesOffset) + ";\n";
	const std::string			readerSaveStatement		= "  verificationBuffer.data[id1d] = val;\n";

	// Common for all ray tracing shaders.
	std::stringstream rayTracingIdsStream;
	rayTracingIdsStream
		<< "  const uint  id1d = gl_LaunchIDEXT.y * " << kImageDim << " + gl_LaunchIDEXT.x;\n"
		<< "  const ivec2 id2d = ivec2(gl_LaunchIDEXT.xy);\n"
		;
	const std::string rayTracingIds = rayTracingIdsStream.str();

	// Common for all compute shaders.
	std::stringstream computeIdsStream;
	computeIdsStream
		<< "  const uint  id1d = gl_GlobalInvocationID.y * " << kImageDim << " + gl_GlobalInvocationID.x;\n"
		<< "  const ivec2 id2d = ivec2(gl_GlobalInvocationID.xy);\n"
		;
	const std::string computeIds = computeIdsStream.str();

	// Common for all fragment shaders.
	std::stringstream fragIdsStream;
	fragIdsStream
		<< "  const uint  id1d = uint(gl_FragCoord.y) * " << kImageDim << " + uint(gl_FragCoord.x);\n"
		<< "  const ivec2 id2d = ivec2(gl_FragCoord.xy);\n"
		;
	const std::string fragIds = fragIdsStream.str();

	// Statements to declare the resource in the writer and reader sides, as well as writing to and reading from it.
	std::stringstream writerResourceDecl;
	std::stringstream readerResourceDecl;
	std::stringstream writeStatement;
	std::stringstream readStatement;

	switch (m_params.resourceType)
	{
	case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
		writerResourceDecl << "layout(set = 0, binding = 0, std140) uniform ubodef { uint data[" << kBufferElements << "]; } ubo;\n";
		readerResourceDecl << "layout(set = 0, binding = 0, std140) uniform ubodef { uint data[" << kBufferElements << "]; } ubo;\n";
		// No writes can happen from shaders in this case.
		readStatement << "  const uint  val  = ubo.data[id1d];\n";
		break;
	case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
		writerResourceDecl << "layout(set = 0, binding = 0, std140) buffer ssbodef { uint data[" << kBufferElements << "]; } ssbo;\n";
		readerResourceDecl << "layout(set = 0, binding = 0, std140) buffer ssbodef { uint data[" << kBufferElements << "]; } ssbo;\n";
		writeStatement << "  ssbo.data[id1d] = val;\n";
		readStatement << "  const uint  val  = ssbo.data[id1d];\n";
		break;
	case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
		writerResourceDecl << "layout(r32ui, set = 0, binding = 0) uniform uimage2D simage;\n";
		readerResourceDecl << "layout(r32ui, set = 0, binding = 0) uniform uimage2D simage;\n";
		writeStatement << "  imageStore(simage, id2d, uvec4(val, 0, 0, 0));\n";
		readStatement << "  const uint  val  = imageLoad(simage, id2d).x;\n";
		break;
	default:
		DE_ASSERT(false);
		break;
	}

	// This extra buffer will be used to copy values from the resource as obtained by the reader and will later be verified on the host.
	std::stringstream readerVerifierDeclStream;
	readerVerifierDeclStream << "layout(set = 0, binding = " << readerVerifierBinding << ") buffer vssbodef { uint data[" << kBufferElements << "]; } verificationBuffer;\n";
	const std::string readerVerifierDecl = readerVerifierDeclStream.str();

	// These are always used together in writer shaders.
	const std::string writerCalcAndWrite = valStatement + writeStatement.str();

	// Add shaders that will be used to write to the resource.
	if (wstage == Stage::HOST || wstage == Stage::TRANSFER)
		; // Nothing to do here.
	else if (wstage == Stage::RAYGEN)
	{
		std::stringstream rgen;
		rgen
			<< "#version 460 core\n"
			<< "#extension GL_EXT_ray_tracing : require\n"
			<< writerResourceDecl.str()
			<< "void main()\n"
			<< "{\n"
			<< rayTracingIds
			<< writerCalcAndWrite
			<< "}\n"
			;
		programCollection.glslSources.add("writer_rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions;
	}
	else if (wstage == Stage::INTERSECT)
	{
		programCollection.glslSources.add("writer_aux_rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;

		std::stringstream isect;
		isect
			<< "#version 460 core\n"
			<< "#extension GL_EXT_ray_tracing : require\n"
			<< "hitAttributeEXT vec3 hitAttribute;\n"
			<< writerResourceDecl.str()
			<< "void main()\n"
			<< "{\n"
			<< rayTracingIds
			<< writerCalcAndWrite
			<< "  hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n"
			<< "  reportIntersectionEXT(1.0f, 0);\n"
			<< "}\n";
			;
		programCollection.glslSources.add("writer_isect") << glu::IntersectionSource(updateRayTracingGLSL(isect.str())) << buildOptions;
	}
	else if (wstage == Stage::ANY_HIT)
	{
		programCollection.glslSources.add("writer_aux_rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;

		std::stringstream ahit;
		ahit
			<< "#version 460 core\n"
			<< "#extension GL_EXT_ray_tracing : require\n"
			<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
			<< "hitAttributeEXT vec3 attribs;\n"
			<< writerResourceDecl.str()
			<< "void main()\n"
			<< "{\n"
			<< rayTracingIds
			<< writerCalcAndWrite
			<< "}\n";
			;
		programCollection.glslSources.add("writer_ahit") << glu::AnyHitSource(updateRayTracingGLSL(ahit.str())) << buildOptions;
	}
	else if (wstage == Stage::CLOSEST_HIT)
	{
		programCollection.glslSources.add("writer_aux_rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;

		std::stringstream chit;
		chit
			<< "#version 460 core\n"
			<< "#extension GL_EXT_ray_tracing : require\n"
			<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
			<< "hitAttributeEXT vec3 attribs;\n"
			<< writerResourceDecl.str()
			<< "void main()\n"
			<< "{\n"
			<< rayTracingIds
			<< writerCalcAndWrite
			<< "}\n";
			;
		programCollection.glslSources.add("writer_chit") << glu::ClosestHitSource(updateRayTracingGLSL(chit.str())) << buildOptions;
	}
	else if (wstage == Stage::MISS)
	{
		programCollection.glslSources.add("writer_aux_rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;

		std::stringstream miss;
		miss
			<< "#version 460 core\n"
			<< "#extension GL_EXT_ray_tracing : require\n"
			<< "layout(location = 0) rayPayloadInEXT dummyPayload { vec4 dummy; };\n"
			<< writerResourceDecl.str()
			<< "void main()\n"
			<< "{\n"
			<< rayTracingIds
			<< writerCalcAndWrite
			<< "}\n";
			;
		programCollection.glslSources.add("writer_miss") << glu::MissSource(updateRayTracingGLSL(miss.str())) << buildOptions;
	}
	else if (wstage == Stage::CALLABLE)
	{
		{
			std::stringstream rgen;
			rgen
				<< "#version 460 core\n"
				<< "#extension GL_EXT_ray_tracing : require\n"
				<< "layout(location = 0) callableDataEXT float dummy;"
				<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
				<< "\n"
				<< "void main()\n"
				<< "{\n"
				<< "  executeCallableEXT(0, 0);\n"
				<< "}\n"
				;
			programCollection.glslSources.add("writer_aux_rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions;
		}

		std::stringstream callable;
		callable
			<< "#version 460 core\n"
			<< "#extension GL_EXT_ray_tracing : require\n"
			<< "layout(location = 0) callableDataInEXT float dummy;\n"
			<< writerResourceDecl.str()
			<< "void main()\n"
			<< "{\n"
			<< rayTracingIds
			<< writerCalcAndWrite
			<< "}\n";
			;
		programCollection.glslSources.add("writer_callable") << glu::CallableSource(updateRayTracingGLSL(callable.str())) << buildOptions;
	}
	else if (wstage == Stage::COMPUTE)
	{
		std::stringstream compute;
		compute
			<< "#version 460 core\n"
			<< writerResourceDecl.str()
			<< "void main()\n"
			<< "{\n"
			<< computeIds
			<< writerCalcAndWrite
			<< "}\n"
			;
		programCollection.glslSources.add("writer_comp") << glu::ComputeSource(compute.str());
	}
	else if (wstage == Stage::FRAGMENT)
	{
		{
			std::stringstream vert;
			vert
				<< "#version 460 core\n"
				<< "layout(location = 0) in highp vec4 position;\n"
				<< "void main()\n"
				<< "{\n"
				<< "  gl_Position = position;\n"
				<< "}\n"
				;
			programCollection.glslSources.add("writer_aux_vert") << glu::VertexSource(vert.str());
		}

		std::stringstream frag;
		frag
			<< "#version 460 core\n"
			<< writerResourceDecl.str()
			<< "void main()\n"
			<< "{\n"
			<< fragIds
			<< writerCalcAndWrite
			<< "}\n"
			;
		programCollection.glslSources.add("writer_frag") << glu::FragmentSource(frag.str());
	}
	else
	{
		DE_ASSERT(false);
	}

	// These are always used together by reader shaders.
	const std::string readerAllDecls	= readerResourceDecl.str() + readerVerifierDecl;
	const std::string readerReadAndSave	= readStatement.str() + readerSaveStatement;

	// Add shaders that will be used to read from the resource.
	if (rstage == Stage::HOST || rstage == Stage::TRANSFER)
		; // Nothing to do here.
	else if (rstage == Stage::RAYGEN)
	{
		std::stringstream rgen;
		rgen
			<< "#version 460 core\n"
			<< "#extension GL_EXT_ray_tracing : require\n"
			<< readerAllDecls
			<< "void main()\n"
			<< "{\n"
			<< rayTracingIds
			<< readerReadAndSave
			<< "}\n"
			;
		programCollection.glslSources.add("reader_rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions;
	}
	else if (rstage == Stage::INTERSECT)
	{
		programCollection.glslSources.add("reader_aux_rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;

		std::stringstream isect;
		isect
			<< "#version 460 core\n"
			<< "#extension GL_EXT_ray_tracing : require\n"
			<< "hitAttributeEXT vec3 hitAttribute;\n"
			<< readerAllDecls
			<< "void main()\n"
			<< "{\n"
			<< rayTracingIds
			<< readerReadAndSave
			<< "  hitAttribute = vec3(0.0f, 0.0f, 0.0f);\n"
			<< "  reportIntersectionEXT(1.0f, 0);\n"
			<< "}\n";
			;
		programCollection.glslSources.add("reader_isect") << glu::IntersectionSource(updateRayTracingGLSL(isect.str())) << buildOptions;
	}
	else if (rstage == Stage::ANY_HIT)
	{
		programCollection.glslSources.add("reader_aux_rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;

		std::stringstream ahit;
		ahit
			<< "#version 460 core\n"
			<< "#extension GL_EXT_ray_tracing : require\n"
			<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
			<< "hitAttributeEXT vec3 attribs;\n"
			<< readerAllDecls
			<< "void main()\n"
			<< "{\n"
			<< rayTracingIds
			<< readerReadAndSave
			<< "}\n";
			;
		programCollection.glslSources.add("reader_ahit") << glu::AnyHitSource(updateRayTracingGLSL(ahit.str())) << buildOptions;
	}
	else if (rstage == Stage::CLOSEST_HIT)
	{
		programCollection.glslSources.add("reader_aux_rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;

		std::stringstream chit;
		chit
			<< "#version 460 core\n"
			<< "#extension GL_EXT_ray_tracing : require\n"
			<< "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n"
			<< "hitAttributeEXT vec3 attribs;\n"
			<< readerAllDecls
			<< "void main()\n"
			<< "{\n"
			<< rayTracingIds
			<< readerReadAndSave
			<< "}\n";
			;
		programCollection.glslSources.add("reader_chit") << glu::ClosestHitSource(updateRayTracingGLSL(chit.str())) << buildOptions;
	}
	else if (rstage == Stage::MISS)
	{
		programCollection.glslSources.add("reader_aux_rgen") << glu::RaygenSource(updateRayTracingGLSL(getCommonRayGenerationShader())) << buildOptions;

		std::stringstream miss;
		miss
			<< "#version 460 core\n"
			<< "#extension GL_EXT_ray_tracing : require\n"
			<< "layout(location = 0) rayPayloadInEXT dummyPayload { vec4 dummy; };\n"
			<< readerAllDecls
			<< "void main()\n"
			<< "{\n"
			<< rayTracingIds
			<< readerReadAndSave
			<< "}\n";
			;
		programCollection.glslSources.add("reader_miss") << glu::MissSource(updateRayTracingGLSL(miss.str())) << buildOptions;
	}
	else if (rstage == Stage::CALLABLE)
	{
		{
			std::stringstream rgen;
			rgen
				<< "#version 460 core\n"
				<< "#extension GL_EXT_ray_tracing : require\n"
				<< "layout(location = 0) callableDataEXT float dummy;"
				<< "layout(set = 0, binding = 1) uniform accelerationStructureEXT topLevelAS;\n"
				<< "\n"
				<< "void main()\n"
				<< "{\n"
				<< "  executeCallableEXT(0, 0);\n"
				<< "}\n"
				;
			programCollection.glslSources.add("reader_aux_rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions;
		}

		std::stringstream callable;
		callable
			<< "#version 460 core\n"
			<< "#extension GL_EXT_ray_tracing : require\n"
			<< "layout(location = 0) callableDataInEXT float dummy;\n"
			<< readerAllDecls
			<< "void main()\n"
			<< "{\n"
			<< rayTracingIds
			<< readerReadAndSave
			<< "}\n";
			;
		programCollection.glslSources.add("reader_callable") << glu::CallableSource(updateRayTracingGLSL(callable.str())) << buildOptions;
	}
	else if (rstage == Stage::COMPUTE)
	{
		std::stringstream compute;
		compute
			<< "#version 460 core\n"
			<< readerAllDecls
			<< "void main()\n"
			<< "{\n"
			<< computeIds
			<< readerReadAndSave
			<< "}\n"
			;
		programCollection.glslSources.add("reader_comp") << glu::ComputeSource(compute.str());
	}
	else if (rstage == Stage::FRAGMENT)
	{
		{
			std::stringstream vert;
			vert
				<< "#version 460 core\n"
				<< "layout(location = 0) in highp vec4 position;\n"
				<< "void main()\n"
				<< "{\n"
				<< "  gl_Position = position;\n"
				<< "}\n"
				;
			programCollection.glslSources.add("reader_aux_vert") << glu::VertexSource(vert.str());
		}

		std::stringstream frag;
		frag
			<< "#version 460 core\n"
			<< readerAllDecls
			<< "void main()\n"
			<< "{\n"
			<< fragIds
			<< readerReadAndSave
			<< "}\n"
			;
		programCollection.glslSources.add("reader_frag") << glu::FragmentSource(frag.str());
	}
	else
	{
		DE_ASSERT(false);
	}
}

TestInstance* BarrierTestCase::createInstance (Context& context) const
{
	return new BarrierTestInstance(context, m_params);
}

void BarrierTestCase::checkSupport (Context& context) const
{
	if (m_params.writerStage == Stage::FRAGMENT)
	{
		const auto& features = context.getDeviceFeatures();

		if (!features.fragmentStoresAndAtomics)
			TCU_THROW(NotSupportedError, "Fragment shader does not support stores");
	}

	if (isRayTracingStage(m_params.readerStage) || isRayTracingStage(m_params.writerStage))
	{
		context.requireDeviceFunctionality("VK_KHR_acceleration_structure");
		context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline");

		const auto& rtFeatures = context.getRayTracingPipelineFeatures();
		if (!rtFeatures.rayTracingPipeline)
			TCU_THROW(NotSupportedError, "Ray Tracing pipelines not supported");

		const auto& asFeatures = context.getAccelerationStructureFeatures();
		if (!asFeatures.accelerationStructure)
			TCU_FAIL("VK_KHR_acceleration_structure supported without accelerationStructure support");
	}
}

BarrierTestInstance::BarrierTestInstance (Context& context, const TestParams& testParams)
	: vkt::TestInstance	(context)
	, m_params			(testParams)
{
}

// Creates a buffer with kBufferElements elements of type deUint32 and std140 padding.
std::unique_ptr<BufferWithMemory> makeStd140Buffer (const DeviceInterface& vkd, VkDevice device, Allocator& alloc, VkBufferUsageFlags flags, MemoryRequirement memReq)
{
	std::unique_ptr<BufferWithMemory> buffer;

	const auto bufferCreateInfo = makeBufferCreateInfo(static_cast<VkDeviceSize>(kBufferSize), flags);
	buffer.reset(new BufferWithMemory(vkd, device, alloc, bufferCreateInfo, memReq));

	return buffer;
}

// Fill buffer with data using std140 padding rules.
void fillStd140Buffer (const DeviceInterface& vkd, VkDevice device, const BufferWithMemory& buffer)
{
	// Buffer host ptr.
	auto& bufferAlloc	= buffer.getAllocation();
	auto* bufferPtr		= bufferAlloc.getHostPtr();

	// Fill buffer with data. This uses the same strategy as the writer shaders.
	std::vector<tcu::UVec4> bufferData(kBufferElements, tcu::UVec4(kValuesOffset, 0u, 0u, 0u));
	for (size_t i = 0; i < bufferData.size(); ++i)
		bufferData[i].x() += static_cast<deUint32>(i);
	deMemcpy(bufferPtr, bufferData.data(), static_cast<size_t>(kBufferSize));
	flushAlloc(vkd, device, bufferAlloc);
}

// Fill buffer with data using std430 padding rules (compact integers).
void fillStd430Buffer (const DeviceInterface& vkd, VkDevice device, const BufferWithMemory& buffer)
{
	// Buffer host ptr.
	auto& bufferAlloc	= buffer.getAllocation();
	auto* bufferPtr		= bufferAlloc.getHostPtr();

	// Fill buffer with data. This uses the same strategy as the writer shaders.
	std::vector<deUint32> bufferData(kBufferElements);
	std::iota(begin(bufferData), end(bufferData), kValuesOffset);
	deMemcpy(bufferPtr, bufferData.data(), static_cast<size_t>(kBufferSize430));
	flushAlloc(vkd, device, bufferAlloc);
}

// Creates a host-visible std430 buffer with kBufferElements elements of type deUint32. If requested, fill buffer with values
// starting at kValuesOffset.
std::unique_ptr<BufferWithMemory> makeStd430BufferImpl (const DeviceInterface& vkd, VkDevice device, Allocator& alloc, VkBufferUsageFlags flags, bool fill)
{
	std::unique_ptr<BufferWithMemory> buffer;

	const auto bufferCreateInfo = makeBufferCreateInfo(static_cast<VkDeviceSize>(kBufferSize430), flags);
	buffer.reset(new BufferWithMemory(vkd, device, alloc, bufferCreateInfo, MemoryRequirement::HostVisible));

	if (fill)
		fillStd430Buffer(vkd, device, *buffer);

	return buffer;
}

std::unique_ptr<BufferWithMemory> makeStd430Buffer (const DeviceInterface& vkd, VkDevice device, Allocator& alloc, VkBufferUsageFlags flags)
{
	return makeStd430BufferImpl(vkd, device, alloc, flags, false);
}

std::unique_ptr<BufferWithMemory> makeStd430BufferFilled (const DeviceInterface& vkd, VkDevice device, Allocator& alloc, VkBufferUsageFlags flags)
{
	return makeStd430BufferImpl(vkd, device, alloc, flags, true);
}

// Helper struct to group data related to the writer or reader stages.
// Not every member will be used at the same time.
struct StageData
{
	Move<VkDescriptorSetLayout>						descriptorSetLayout;
	Move<VkPipelineLayout>							pipelineLayout;

	Move<VkDescriptorPool>							descriptorPool;
	Move<VkDescriptorSet>							descriptorSet;

	Move<VkPipeline>								pipeline;
	Move<VkRenderPass>								renderPass;
	Move<VkFramebuffer>								framebuffer;
	std::unique_ptr<BufferWithMemory>				vertexBuffer;

	de::MovePtr<BottomLevelAccelerationStructure>	bottomLevelAccelerationStructure;
	de::MovePtr<TopLevelAccelerationStructure>		topLevelAccelerationStructure;

	de::MovePtr<BufferWithMemory>					raygenShaderBindingTable;
	de::MovePtr<BufferWithMemory>					missShaderBindingTable;
	de::MovePtr<BufferWithMemory>					hitShaderBindingTable;
	de::MovePtr<BufferWithMemory>					callableShaderBindingTable;

	VkStridedDeviceAddressRegionKHR					raygenShaderBindingTableRegion;
	VkStridedDeviceAddressRegionKHR					missShaderBindingTableRegion;
	VkStridedDeviceAddressRegionKHR					hitShaderBindingTableRegion;
	VkStridedDeviceAddressRegionKHR					callableShaderBindingTableRegion;

	StageData ()
		: descriptorSetLayout				()
		, pipelineLayout					()
		, descriptorPool					()
		, descriptorSet						()
		, pipeline							()
		, renderPass						()
		, framebuffer						()
		, vertexBuffer						()
		, bottomLevelAccelerationStructure	()
		, topLevelAccelerationStructure		()
		, raygenShaderBindingTable			()
		, missShaderBindingTable			()
		, hitShaderBindingTable				()
		, callableShaderBindingTable		()
		, raygenShaderBindingTableRegion	(makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0))
		, missShaderBindingTableRegion		(makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0))
		, hitShaderBindingTableRegion		(makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0))
		, callableShaderBindingTableRegion	(makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0))
	{
	}

	// Make sure we don't mistakenly pass one of these by value.
	StageData (const StageData&)	= delete;
	StageData (StageData&&)			= delete;
};

// Auxiliar function to update the descriptor set for the writer or reader stages.
void updateDescriptorSet (const DeviceInterface& vkd, VkDevice device, VkCommandBuffer cmdBuffer, Allocator& alloc, VkDescriptorType resourceType, Stage stage, StageData& stageData, BufferWithMemory* resourceBuffer, VkImageView resourceImgView, VkImageLayout layout, bool asNeeded, BufferWithMemory* verificationBuffer)
{
	DescriptorSetUpdateBuilder						updateBuilder;
	VkWriteDescriptorSetAccelerationStructureKHR	writeASInfo;

	if (resourceType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || resourceType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
	{
		const auto descriptorBufferInfo = makeDescriptorBufferInfo(resourceBuffer->get(), 0ull, VK_WHOLE_SIZE);
		updateBuilder.writeSingle(stageData.descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), resourceType, &descriptorBufferInfo);
	}
	else if (resourceType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
	{
		const auto descriptorImageInfo = makeDescriptorImageInfo(DE_NULL, resourceImgView, layout);
		updateBuilder.writeSingle(stageData.descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), resourceType, &descriptorImageInfo);
	}
	else
	{
		DE_ASSERT(false);
	}

	// Create top and bottom level acceleration structures if needed.
	if (asNeeded)
	{
		stageData.bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure();
		stageData.bottomLevelAccelerationStructure->setDefaultGeometryData(getShaderStageFlagBits(stage));
		stageData.bottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, alloc);

		stageData.topLevelAccelerationStructure = makeTopLevelAccelerationStructure();
		stageData.topLevelAccelerationStructure->setInstanceCount(1);
		stageData.topLevelAccelerationStructure->addInstance(de::SharedPtr<BottomLevelAccelerationStructure>(stageData.bottomLevelAccelerationStructure.release()));
		stageData.topLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, alloc);

		writeASInfo.sType						= VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR;
		writeASInfo.pNext						= nullptr;
		writeASInfo.accelerationStructureCount	= 1u;
		writeASInfo.pAccelerationStructures		= stageData.topLevelAccelerationStructure.get()->getPtr();

		updateBuilder.writeSingle(stageData.descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &writeASInfo);
	}

	if (verificationBuffer)
	{
		const deUint32	bindingNumber			= (asNeeded ? 2u : 1u);
		const auto		descriptorBufferInfo	= makeDescriptorBufferInfo(verificationBuffer->get(), 0ull, VK_WHOLE_SIZE);

		updateBuilder.writeSingle(stageData.descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(bindingNumber), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo);
	}

	updateBuilder.update(vkd, device);
}

// Auxiliar function to create the writer or reader compute pipeline
void createComputePipeline (const DeviceInterface& vkd, VkDevice device, Context& context, const char* shaderName, StageData& stageData)
{
	const auto shaderModule = createShaderModule(vkd, device, context.getBinaryCollection().get(shaderName), 0u);

	const VkPipelineShaderStageCreateInfo stageInfo =
	{
		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	//	VkStructureType						sType;
		nullptr,												//	const void*							pNext;
		0u,														//	VkPipelineShaderStageCreateFlags	flags;
		VK_SHADER_STAGE_COMPUTE_BIT,							//	VkShaderStageFlagBits				stage;
		shaderModule.get(),										//	VkShaderModule						module;
		"main",													//	const char*							pName;
		nullptr,												//	const VkSpecializationInfo*			pSpecializationInfo;
	};

	const VkComputePipelineCreateInfo createInfo =
	{
		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,	//	VkStructureType					sType;
		nullptr,										//	const void*						pNext;
		0u,												//	VkPipelineCreateFlags			flags;
		stageInfo,										//	VkPipelineShaderStageCreateInfo	stage;
		stageData.pipelineLayout.get(),					//	VkPipelineLayout				layout;
		DE_NULL,										//	VkPipeline						basePipelineHandle;
		0,												//	deInt32							basePipelineIndex;
	};

	// Compute pipeline.
	stageData.pipeline = createComputePipeline(vkd, device, DE_NULL, &createInfo);
}

// Auxiliar function to record commands using the compute pipeline.
void useComputePipeline (const DeviceInterface& vkd, VkCommandBuffer cmdBuffer, StageData& stageData)
{
	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, stageData.pipeline.get());
	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, stageData.pipelineLayout.get(), 0u, 1u, &stageData.descriptorSet.get(), 0u, nullptr);
	vkd.cmdDispatch(cmdBuffer, kImageDim, kImageDim, 1u);
}

// Auxiliar function to create graphics pipeline objects for writer or reader stages.
void createGraphicsPipelineObjects (const DeviceInterface& vkd, VkDevice device, Allocator& alloc, Context& context, const char* vertShaderName, const char* fragShaderName, StageData& stageData)
{
	const auto vertShader = createShaderModule(vkd, device, context.getBinaryCollection().get(vertShaderName), 0u);
	const auto fragShader = createShaderModule(vkd, device, context.getBinaryCollection().get(fragShaderName), 0u);

	// Render pass.
	const auto subpassDescription = makeSubpassDescription(0u, VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, nullptr, 0u, nullptr, nullptr, nullptr, 0u, nullptr);
	const VkRenderPassCreateInfo renderPassInfo =
	{
		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,	//	VkStructureType					sType;
		nullptr,									//	const void*						pNext;
		0u,											//	VkRenderPassCreateFlags			flags;
		0u,											//	deUint32						attachmentCount;
		nullptr,									//	const VkAttachmentDescription*	pAttachments;
		1u,											//	deUint32						subpassCount;
		&subpassDescription,						//	const VkSubpassDescription*		pSubpasses;
		0u,											//	deUint32						dependencyCount;
		nullptr,									//	const VkSubpassDependency*		pDependencies;
	};
	stageData.renderPass = createRenderPass(vkd, device, &renderPassInfo);

	// Viewport.
	const auto viewport = makeViewport(kImageExtent);
	const std::vector<VkViewport> viewports(1u, viewport);

	// Scissor.
	const auto scissor = makeRect2D(kImageExtent);
	const std::vector<VkRect2D> scissors(1u, scissor);

	// Pipeline.
	stageData.pipeline = makeGraphicsPipeline(vkd, device, stageData.pipelineLayout.get(), vertShader.get(), DE_NULL, DE_NULL, DE_NULL, fragShader.get(), stageData.renderPass.get(), viewports, scissors);

	// Framebuffer.
	stageData.framebuffer = makeFramebuffer(vkd, device, stageData.renderPass.get(), 0u, nullptr, kImageDim, kImageDim);

	// Vertex buffer with full-screen quad.
	const auto			vertexBufferSize	= static_cast<VkDeviceSize>(kFullScreenQuad.size() * sizeof(decltype(kFullScreenQuad)::value_type));
	const auto			vertexBufferInfo	= makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);

	stageData.vertexBuffer.reset(new BufferWithMemory(vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible));
	const auto&			vertexBufferAlloc	= stageData.vertexBuffer->getAllocation();

	deMemcpy(vertexBufferAlloc.getHostPtr(), kFullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
	flushAlloc(vkd, device, vertexBufferAlloc);
}

// Auxiliar function to record commands using the graphics pipeline.
void useGraphicsPipeline (const DeviceInterface& vkd, VkCommandBuffer cmdBuffer, StageData& stageData)
{
	const VkDeviceSize	vertexBufferOffset	= 0ull;
	const auto			scissor				= makeRect2D(kImageExtent);

	beginRenderPass(vkd, cmdBuffer, stageData.renderPass.get(), stageData.framebuffer.get(), scissor);
	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, stageData.pipeline.get());
	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, stageData.pipelineLayout.get(), 0u, 1u, &stageData.descriptorSet.get(), 0u, nullptr);
	vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &stageData.vertexBuffer->get(), &vertexBufferOffset);
	vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(kFullScreenQuad.size()), 1u, 0u, 0u);
	endRenderPass(vkd, cmdBuffer);
}

// Auxiliar function to create ray tracing pipelines for the writer or reader stages.
void createRayTracingPipelineData (const DeviceInterface& vkd, VkDevice device, Allocator& alloc, Context& context,
								   Stage stage, StageData& stageData, deUint32 shaderGroupHandleSize, deUint32 shaderGroupBaseAlignment,
								   const char* rgenAuxName, const char* rgenName, const char* isectName, const char* ahitName, const char* chitName, const char* missName, const char* callableName)
{
	// Ray tracing stage
	DE_ASSERT(isRayTracingStage(stage));

	if (stage == Stage::RAYGEN)
	{
		const auto rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();

		rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, context.getBinaryCollection().get(rgenName), 0), 0);

		stageData.pipeline = rayTracingPipeline->createPipeline(vkd, device, stageData.pipelineLayout.get());

		stageData.raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, stageData.pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
		stageData.raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, stageData.raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
	}
	else if (stage == Stage::INTERSECT)
	{
		const auto rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();

		rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR,		createShaderModule(vkd, device, context.getBinaryCollection().get(rgenAuxName), 0), 0);
		rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR,	createShaderModule(vkd, device, context.getBinaryCollection().get(isectName), 0), 1);

		stageData.pipeline = rayTracingPipeline->createPipeline(vkd, device, stageData.pipelineLayout.get());

		stageData.raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, stageData.pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
		stageData.raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, stageData.raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);

		stageData.hitShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, stageData.pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
		stageData.hitShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, stageData.hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
	}
	else if (stage == Stage::ANY_HIT)
	{
		const auto rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();

		rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR,		createShaderModule(vkd, device, context.getBinaryCollection().get(rgenAuxName), 0), 0);
		rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR,		createShaderModule(vkd, device, context.getBinaryCollection().get(ahitName), 0), 1);

		stageData.pipeline = rayTracingPipeline->createPipeline(vkd, device, stageData.pipelineLayout.get());

		stageData.raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, stageData.pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
		stageData.raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, stageData.raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);

		stageData.hitShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, stageData.pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
		stageData.hitShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, stageData.hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
	}
	else if (stage == Stage::CLOSEST_HIT)
	{
		const auto rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();

		rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR,		createShaderModule(vkd, device, context.getBinaryCollection().get(rgenAuxName), 0), 0);
		rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR,	createShaderModule(vkd, device, context.getBinaryCollection().get(chitName), 0), 1);

		stageData.pipeline = rayTracingPipeline->createPipeline(vkd, device, stageData.pipelineLayout.get());

		stageData.raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, stageData.pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
		stageData.raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, stageData.raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);

		stageData.hitShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, stageData.pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
		stageData.hitShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, stageData.hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
	}
	else if (stage == Stage::MISS)
	{
		const auto rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();

		rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR,	createShaderModule(vkd, device, context.getBinaryCollection().get(rgenAuxName), 0), 0);
		rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR,		createShaderModule(vkd, device, context.getBinaryCollection().get(missName), 0), 1);

		stageData.pipeline = rayTracingPipeline->createPipeline(vkd, device, stageData.pipelineLayout.get());

		stageData.raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, stageData.pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
		stageData.raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, stageData.raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);

		stageData.missShaderBindingTable		= rayTracingPipeline->createShaderBindingTable(vkd, device, stageData.pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
		stageData.missShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, stageData.missShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
	}
	else if (stage == Stage::CALLABLE)
	{
		const auto rayTracingPipeline = de::newMovePtr<RayTracingPipeline>();

		rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR,	createShaderModule(vkd, device, context.getBinaryCollection().get(rgenAuxName), 0), 0);
		rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR,	createShaderModule(vkd, device, context.getBinaryCollection().get(callableName), 0), 1);

		stageData.pipeline = rayTracingPipeline->createPipeline(vkd, device, stageData.pipelineLayout.get());

		stageData.raygenShaderBindingTable			= rayTracingPipeline->createShaderBindingTable(vkd, device, stageData.pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1);
		stageData.raygenShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, stageData.raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);

		stageData.callableShaderBindingTable		= rayTracingPipeline->createShaderBindingTable(vkd, device, stageData.pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1);
		stageData.callableShaderBindingTableRegion	= makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, stageData.callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize);
	}
	else
	{
		DE_ASSERT(false);
	}
}

// Auxiliar function to record commands using the ray tracing pipeline for the writer or reader stages.
void useRayTracingPipeline (const DeviceInterface& vkd, VkCommandBuffer cmdBuffer, StageData& stageData)
{
	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, stageData.pipeline.get());
	vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, stageData.pipelineLayout.get(), 0u, 1u, &stageData.descriptorSet.get(), 0u, nullptr);
	vkd.cmdTraceRaysKHR(cmdBuffer, &stageData.raygenShaderBindingTableRegion, &stageData.missShaderBindingTableRegion, &stageData.hitShaderBindingTableRegion, &stageData.callableShaderBindingTableRegion, kImageDim, kImageDim, 1u);
}

tcu::TestStatus BarrierTestInstance::iterate (void)
{
	const auto& vki						= m_context.getInstanceInterface();
	const auto	physicalDevice			= m_context.getPhysicalDevice();
	const auto&	vkd						= m_context.getDeviceInterface();
	const auto	device					= m_context.getDevice();
	const auto	queue					= m_context.getUniversalQueue();
	const auto	familyIndex				= m_context.getUniversalQueueFamilyIndex();
	auto&		alloc					= m_context.getDefaultAllocator();
	const auto	imageSubresourceLayers	= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
	const bool	rtInUse					= (isRayTracingStage(m_params.readerStage) || isRayTracingStage(m_params.writerStage));

	// Stage data for the writer and reader stages.
	StageData writerStageData;
	StageData readerStageData;

	// Get some ray tracing properties.
	deUint32 shaderGroupHandleSize		= 0u;
	deUint32 shaderGroupBaseAlignment	= 1u;
	if (rtInUse)
	{
		const auto rayTracingPropertiesKHR	= makeRayTracingProperties(vki, physicalDevice);
		shaderGroupHandleSize				= rayTracingPropertiesKHR->getShaderGroupHandleSize();
		shaderGroupBaseAlignment			= rayTracingPropertiesKHR->getShaderGroupBaseAlignment();
	}

	// Shader stages involved.
	const auto writerStages		= getStageFlags(m_params.writerStage);
	const auto readerStages		= getStageFlags(m_params.readerStage);
	const auto allStages		= (writerStages | readerStages);
	const bool writerNeedsAS	= needsAccelerationStructure(m_params.writerStage);
	const bool readerNeedsAS	= needsAccelerationStructure(m_params.readerStage);

	// Command buffer.
	const auto cmdPool		= makeCommandPool(vkd, device, familyIndex);
	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
	const auto cmdBuffer	= cmdBufferPtr.get();

	beginCommandBuffer(vkd, cmdBuffer);

	std::unique_ptr<ImageWithMemory>	resourceImg;
	Move<VkImageView>					resourceImgView;
	VkImageLayout						resourceImgLayout			= VK_IMAGE_LAYOUT_UNDEFINED;
	const auto							resourceImgSubresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
	std::unique_ptr<BufferWithMemory>	stagingBuffer;
	std::unique_ptr<BufferWithMemory>	resourceBuffer;
	std::unique_ptr<BufferWithMemory>	verificationBuffer;
	const VkBufferUsageFlags			stagingBufferFlags			= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;

	// Create verification buffer for later use.
	{
		VkBufferUsageFlags verificationBufferFlags = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
		if (m_params.readerStage == Stage::TRANSFER)
			verificationBufferFlags |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;

		verificationBuffer = makeStd430Buffer(vkd, device, alloc, verificationBufferFlags);
	}

	// Create resource buffer or resource image.
	if (m_params.resourceType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || m_params.resourceType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
	{
		if (m_params.resourceType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
			DE_ASSERT(m_params.writerStage == Stage::HOST || m_params.writerStage == Stage::TRANSFER);

		VkBufferUsageFlags bufferFlags	= ((m_params.resourceType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
										? VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
										: VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);

		if (m_params.writerStage == Stage::TRANSFER)
			bufferFlags |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;

		if (m_params.readerStage == Stage::TRANSFER)
			bufferFlags |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;

		MemoryRequirement bufferMemReq = (resourceNeedsHostVisibleMemory(m_params) ? MemoryRequirement::HostVisible : MemoryRequirement::Any);
		resourceBuffer = makeStd140Buffer(vkd, device, alloc, bufferFlags, bufferMemReq);
	}
	else if (m_params.resourceType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
	{
		DE_ASSERT(m_params.writerStage != Stage::HOST);

		VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_STORAGE_BIT;

		if (m_params.writerStage == Stage::TRANSFER)
			imageUsage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;

		if (m_params.readerStage == Stage::TRANSFER)
			imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;

		const VkImageCreateInfo resourceImageInfo =
		{
			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
			nullptr,								//	const void*				pNext;
			0u,										//	VkImageCreateFlags		flags;
			VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
			kImageFormat,							//	VkFormat				format;
			kImageExtent,							//	VkExtent3D				extent;
			1u,										//	deUint32				mipLevels;
			1u,										//	deUint32				arrayLayers;
			VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
			VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
			imageUsage,								//	VkImageUsageFlags		usage;
			VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
			0u,										//	deUint32				queueFamilyIndexCount;
			nullptr,								//	const deUint32*			pQueueFamilyIndices;
			VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
		};
		resourceImg.reset(new ImageWithMemory(vkd, device, alloc, resourceImageInfo, MemoryRequirement::Any));
		resourceImgLayout = VK_IMAGE_LAYOUT_UNDEFINED;

		// Image view.
		resourceImgView = makeImageView(vkd, device, resourceImg->get(), VK_IMAGE_VIEW_TYPE_2D, kImageFormat, resourceImgSubresourceRange);
	}
	else
	{
		DE_ASSERT(false);
	}

	// Populate resource from the writer stage.
	if (m_params.writerStage == Stage::HOST)
	{
		DE_ASSERT(m_params.resourceType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER || m_params.resourceType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);

		// Fill buffer data from the host.
		fillStd140Buffer(vkd, device, *resourceBuffer);
	}
	else if (m_params.writerStage == Stage::TRANSFER)
	{
		// Similar to the previous one, but using a staging buffer.
		if (m_params.resourceType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || m_params.resourceType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
		{
			// Create and fill staging buffer.
			stagingBuffer = makeStd140Buffer(vkd, device, alloc, stagingBufferFlags, MemoryRequirement::HostVisible);
			fillStd140Buffer(vkd, device, *stagingBuffer);

			// Fill resource buffer using a transfer operation.
			const auto region	= makeBufferCopy(0u, 0u, static_cast<VkDeviceSize>(kBufferSize));
			const auto barrier	= makeMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
			vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);
			vkd.cmdCopyBuffer(cmdBuffer, stagingBuffer->get(), resourceBuffer->get(), 1u, &region);
		}
		else if (m_params.resourceType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
		{
			// Prepare staging buffer with packed pixels.
			stagingBuffer = makeStd430BufferFilled(vkd, device, alloc, stagingBufferFlags);

			// Barrier for the staging buffer.
			const auto stagingBufferBarrier = makeMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
			vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1u, &stagingBufferBarrier, 0u, nullptr, 0u, nullptr);

			// Transition image to the proper layout.
			const auto expectedLayout = ((m_params.barrierType == BarrierType::SPECIFIC) ? VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL);
			if (expectedLayout != resourceImgLayout)
			{
				const auto imgBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, resourceImgLayout, expectedLayout, resourceImg->get(), resourceImgSubresourceRange);
				vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &imgBarrier);
				resourceImgLayout = expectedLayout;
			}

			// Copy buffer to image.
			const auto bufferImageCopy = makeBufferImageCopy(kImageExtent, imageSubresourceLayers);
			vkd.cmdCopyBufferToImage(cmdBuffer, stagingBuffer->get(), resourceImg->get(), resourceImgLayout, 1u, &bufferImageCopy);
		}
		else
		{
			DE_ASSERT(false);
		}
	}
	else
	{
		// Other cases use pipelines and a shader to fill the resource.

		// Descriptor set layout.
		DescriptorSetLayoutBuilder dslBuilder;
		dslBuilder.addBinding(m_params.resourceType, 1u, allStages, nullptr);	// The resource is used in the writer and reader stages.
		if (writerNeedsAS)
			dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1u, writerStages, nullptr);
		writerStageData.descriptorSetLayout = dslBuilder.build(vkd, device);

		// Pipeline layout.
		writerStageData.pipelineLayout = makePipelineLayout(vkd, device, writerStageData.descriptorSetLayout.get());

		// Descriptor pool and set.
		DescriptorPoolBuilder poolBuilder;
		poolBuilder.addType(m_params.resourceType);
		if (writerNeedsAS)
			poolBuilder.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR);
		writerStageData.descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
		writerStageData.descriptorSet = makeDescriptorSet(vkd, device, writerStageData.descriptorPool.get(), writerStageData.descriptorSetLayout.get());

		// Update descriptor set.
		updateDescriptorSet(vkd, device, cmdBuffer, alloc, m_params.resourceType, m_params.writerStage, writerStageData, resourceBuffer.get(), resourceImgView.get(), VK_IMAGE_LAYOUT_GENERAL, writerNeedsAS, nullptr);

		if (m_params.writerStage == Stage::COMPUTE)
		{
			createComputePipeline(vkd, device, m_context, "writer_comp", writerStageData);

			if (m_params.resourceType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
			{
				// Make sure the image is in the proper layout for shader writes.
				const auto expectedLayout = VK_IMAGE_LAYOUT_GENERAL;
				if (expectedLayout != resourceImgLayout)
				{
					const auto imgBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT, resourceImgLayout, expectedLayout, resourceImg->get(), resourceImgSubresourceRange);
					vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &imgBarrier);
					resourceImgLayout = expectedLayout;
				}
			}

			// Generate the resource using the pipeline.
			useComputePipeline(vkd, cmdBuffer, writerStageData);
		}
		else if (m_params.writerStage == Stage::FRAGMENT)
		{
			createGraphicsPipelineObjects(vkd, device, alloc, m_context, "writer_aux_vert", "writer_frag", writerStageData);

			if (m_params.resourceType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
			{
				// Make sure the image is in the proper layout for shader writes.
				const auto expectedLayout = VK_IMAGE_LAYOUT_GENERAL;
				if (expectedLayout != resourceImgLayout)
				{
					const auto imgBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT, resourceImgLayout, expectedLayout, resourceImg->get(), resourceImgSubresourceRange);
					vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &imgBarrier);
					resourceImgLayout = expectedLayout;
				}
			}

			useGraphicsPipeline(vkd, cmdBuffer, writerStageData);
		}
		else
		{
			createRayTracingPipelineData(vkd, device, alloc, m_context, m_params.writerStage, writerStageData, shaderGroupHandleSize, shaderGroupBaseAlignment,
										 "writer_aux_rgen", "writer_rgen", "writer_isect", "writer_ahit", "writer_chit", "writer_miss", "writer_callable");

			if (m_params.resourceType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
			{
				// Make sure the image is in the proper layout for shader writes.
				const auto expectedLayout = VK_IMAGE_LAYOUT_GENERAL;
				if (expectedLayout != resourceImgLayout)
				{
					const auto imgBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_WRITE_BIT, resourceImgLayout, expectedLayout, resourceImg->get(), resourceImgSubresourceRange);
					vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, 0u, 0u, nullptr, 0u, nullptr, 1u, &imgBarrier);
					resourceImgLayout = expectedLayout;
				}
			}

			useRayTracingPipeline(vkd, cmdBuffer, writerStageData);
		}
	}

	// Main barrier to synchronize the writer stage to the reader stage.
	const auto writerPipelineStage	= getPipelineStage(m_params.writerStage);
	const auto readerPipelineStage	= getPipelineStage(m_params.readerStage);
	const auto writerAccessFlag		= getWriterAccessFlag(m_params.writerStage);
	const auto readerAccessFlag		= getReaderAccessFlag(m_params.readerStage, m_params.resourceType);

	if (m_params.barrierType == BarrierType::GENERAL)
	{
		const auto memoryBarrier = makeMemoryBarrier(writerAccessFlag, readerAccessFlag);
		vkd.cmdPipelineBarrier(cmdBuffer, writerPipelineStage, readerPipelineStage, 0u, 1u, &memoryBarrier, 0u, nullptr, 0u, nullptr);
		// Note the image will remain in the general layout in this case.
		if (m_params.resourceType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
			DE_ASSERT(resourceImgLayout == VK_IMAGE_LAYOUT_GENERAL);
	}
	else if (m_params.barrierType == BarrierType::SPECIFIC)
	{
		if (m_params.resourceType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || m_params.resourceType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
		{
			const auto bufferBarrier = makeBufferMemoryBarrier(writerAccessFlag, readerAccessFlag, resourceBuffer->get(), 0ull, VK_WHOLE_SIZE);
			vkd.cmdPipelineBarrier(cmdBuffer, writerPipelineStage, readerPipelineStage, 0u, 0u, nullptr, 1u, &bufferBarrier, 0u, nullptr);
		}
		else if (m_params.resourceType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
		{
			// We'll switch the image layout from the current layout to the one the reader expects.
			const auto newLayout	= getOptimalReadLayout(m_params.readerStage);
			const auto imageBarrier	= makeImageMemoryBarrier(writerAccessFlag, readerAccessFlag, resourceImgLayout, newLayout, resourceImg->get(), resourceImgSubresourceRange);

			vkd.cmdPipelineBarrier(cmdBuffer, writerPipelineStage, readerPipelineStage, 0u, 0u, nullptr, 0u, nullptr, 1u, &imageBarrier);
			resourceImgLayout = newLayout;
		}
		else
		{
			DE_ASSERT(false);
		}
	}
	else
	{
		DE_ASSERT(false);
	}

	// Read resource from the reader stage copying it to the verification buffer.
	if (m_params.readerStage == Stage::HOST)
	{
		// This needs to wait until we have submitted the command buffer. See below.
	}
	else if (m_params.readerStage == Stage::TRANSFER)
	{
		if (m_params.resourceType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || m_params.resourceType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
		{
			// This is a bit tricky because the resource buffer is in std140 format and the verification buffer is in std430 format.
			std::vector<VkBufferCopy> regions;
			regions.reserve(kBufferElements);
			for (deUint32 i = 0; i < kBufferElements; ++i)
			{
				const VkBufferCopy region =
				{
					static_cast<VkDeviceSize>(i * sizeof(tcu::UVec4)),	//	VkDeviceSize	srcOffset;
					static_cast<VkDeviceSize>(i * sizeof(deUint32)),	//	VkDeviceSize	dstOffset;
					static_cast<VkDeviceSize>(sizeof(deUint32)),		//	VkDeviceSize	size;
				};
				regions.push_back(region);
			}
			vkd.cmdCopyBuffer(cmdBuffer, resourceBuffer->get(), verificationBuffer->get(), static_cast<deUint32>(regions.size()), regions.data());
		}
		else if (m_params.resourceType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
		{
			const auto bufferImageCopyRegion = makeBufferImageCopy(kImageExtent, imageSubresourceLayers);
			vkd.cmdCopyImageToBuffer(cmdBuffer, resourceImg->get(), resourceImgLayout, verificationBuffer->get(), 1u, &bufferImageCopyRegion);
		}
		else
		{
			DE_ASSERT(false);
		}
	}
	else
	{
		// All other stages use shaders to read the resource into the verification buffer.

		// Descriptor set layout.
		DescriptorSetLayoutBuilder dslBuilder;
		dslBuilder.addBinding(m_params.resourceType, 1u, allStages, nullptr);					// Resource accessed in writers and readers.
		if (readerNeedsAS)
			dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1u, readerStages, nullptr);
		dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, readerStages, nullptr);	// Verification buffer.
		readerStageData.descriptorSetLayout = dslBuilder.build(vkd, device);

		// Pipeline layout.
		readerStageData.pipelineLayout = makePipelineLayout(vkd, device, readerStageData.descriptorSetLayout.get());

		// Descriptor pool and set.
		DescriptorPoolBuilder poolBuilder;
		poolBuilder.addType(m_params.resourceType);
		if (readerNeedsAS)
			poolBuilder.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR);
		poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
		readerStageData.descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
		readerStageData.descriptorSet = makeDescriptorSet(vkd, device, readerStageData.descriptorPool.get(), readerStageData.descriptorSetLayout.get());

		// Update descriptor set.
		updateDescriptorSet(vkd, device, cmdBuffer, alloc, m_params.resourceType, m_params.readerStage, readerStageData, resourceBuffer.get(), resourceImgView.get(), resourceImgLayout, readerNeedsAS, verificationBuffer.get());

		if (m_params.readerStage == Stage::COMPUTE)
		{
			createComputePipeline(vkd, device, m_context, "reader_comp", readerStageData);
			useComputePipeline(vkd, cmdBuffer, readerStageData);
		}
		else if (m_params.readerStage == Stage::FRAGMENT)
		{
			createGraphicsPipelineObjects(vkd, device, alloc, m_context, "reader_aux_vert", "reader_frag", readerStageData);
			useGraphicsPipeline(vkd, cmdBuffer, readerStageData);
		}
		else
		{
			createRayTracingPipelineData(vkd, device, alloc, m_context, m_params.readerStage, readerStageData, shaderGroupHandleSize, shaderGroupBaseAlignment,
										 "reader_aux_rgen", "reader_rgen", "reader_isect", "reader_ahit", "reader_chit", "reader_miss", "reader_callable");
			useRayTracingPipeline(vkd, cmdBuffer, readerStageData);
		}
	}

	// Sync verification buffer.
	{
		const auto readerVerificationFlags	= getWriterAccessFlag(m_params.readerStage);
		const auto barrier					= makeBufferMemoryBarrier(readerVerificationFlags, VK_ACCESS_HOST_READ_BIT, verificationBuffer->get(), 0ull, VK_WHOLE_SIZE);
		vkd.cmdPipelineBarrier(cmdBuffer, readerPipelineStage, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &barrier, 0u, nullptr);
	}

	// Submit all recorded commands.
	endCommandBuffer(vkd, cmdBuffer);
	submitCommandsAndWait(vkd, device, queue, cmdBuffer);

	invalidateAlloc(vkd, device, verificationBuffer->getAllocation());

	// If the reader stage is the host, we have to wait until the commands have been submitted and the work has been done.
	if (m_params.readerStage == Stage::HOST)
	{
		DE_ASSERT(m_params.resourceType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER || m_params.resourceType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);

		auto& resourceBufferAlloc = resourceBuffer->getAllocation();
		auto* resourceBufferPtr = resourceBufferAlloc.getHostPtr();

		std::vector<tcu::UVec4> resourceData(kBufferElements);
		invalidateAlloc(vkd, device, resourceBufferAlloc);
		deMemcpy(resourceData.data(), resourceBufferPtr, static_cast<size_t>(kBufferElements) * sizeof(tcu::UVec4));

		// Convert from std140 to std430 on the host.
		std::vector<deUint32> verificationData(kBufferElements);
		std::transform(begin(resourceData), end(resourceData), begin(verificationData),
			[](const tcu::UVec4 &v) -> deUint32 { return v.x(); });

		auto& verificationBufferAlloc = verificationBuffer->getAllocation();
		auto* verificationBufferPtr = verificationBufferAlloc.getHostPtr();
		deMemcpy(verificationBufferPtr, verificationData.data(), static_cast<size_t>(kBufferElements) * sizeof(deUint32));
		flushAlloc(vkd, device, verificationBufferAlloc);
	}

	// Check verification buffer on the host.
	{
		auto& verificationAlloc = verificationBuffer->getAllocation();
		auto* verificationPtr = verificationAlloc.getHostPtr();
		std::vector<deUint32> verificationData(kBufferElements);
		deMemcpy(verificationData.data(), verificationPtr, static_cast<size_t>(kBufferElements) * sizeof(deUint32));

		for (size_t i = 0; i < verificationData.size(); ++i)
		{
			const auto&	value		= verificationData[i];
			const auto	expected	= kValuesOffset + i;

			if (value != expected)
			{
				std::ostringstream msg;
				msg << "Unexpected value found at position " << i << ": found " << value << " and expected " << expected;
				return tcu::TestStatus::fail(msg.str());
			}
		}
	}

	return tcu::TestStatus::pass("Pass");
}

} // anonymous.

tcu::TestCaseGroup*	createBarrierTests(tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "barrier", "Tests involving pipeline barriers and ray tracing"));

	const struct
	{
		VkDescriptorType	type;
		const char*			name;
	} resourceTypes[] =
	{
		{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,	"ubo"	},
		{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,	"ssbo"	},
		{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,		"simg"	},
	};

	const struct
	{
		Stage		stage;
		const char*	name;
	} stageList[] =
	{
		{ Stage::HOST,			"host"	},
		{ Stage::TRANSFER,		"xfer"	},
		{ Stage::RAYGEN,		"rgen"	},
		{ Stage::INTERSECT,		"isec"	},
		{ Stage::ANY_HIT,		"ahit"	},
		{ Stage::CLOSEST_HIT,	"chit"	},
		{ Stage::MISS,			"miss"	},
		{ Stage::CALLABLE,		"call"	},
		{ Stage::COMPUTE,		"comp"	},
		{ Stage::FRAGMENT,		"frag"	},
	};

	const struct
	{
		BarrierType	barrierType;
		const char*	name;
	} barrierTypes[] =
	{
		{ BarrierType::GENERAL,		"memory_barrier"	},
		{ BarrierType::SPECIFIC,	"specific_barrier"	},
	};

	for (int resourceTypeIdx = 0; resourceTypeIdx < DE_LENGTH_OF_ARRAY(resourceTypes); ++resourceTypeIdx)
	{
		de::MovePtr<tcu::TestCaseGroup> resourceTypeGroup(new tcu::TestCaseGroup(testCtx, resourceTypes[resourceTypeIdx].name, ""));

		for (int barrierTypeIdx = 0; barrierTypeIdx < DE_LENGTH_OF_ARRAY(barrierTypes); ++barrierTypeIdx)
		{
			de::MovePtr<tcu::TestCaseGroup> barrierTypeGroup(new tcu::TestCaseGroup(testCtx, barrierTypes[barrierTypeIdx].name, ""));

			for (int writerStageIdx = 0; writerStageIdx < DE_LENGTH_OF_ARRAY(stageList); ++writerStageIdx)
			for (int readerStageIdx = 0; readerStageIdx < DE_LENGTH_OF_ARRAY(stageList); ++readerStageIdx)
			{
				const auto resourceType	= resourceTypes[resourceTypeIdx].type;
				const auto barrierType	= barrierTypes[barrierTypeIdx].barrierType;
				const auto readerStage	= stageList[readerStageIdx].stage;
				const auto writerStage	= stageList[writerStageIdx].stage;

				// Skip tests that do not involve ray tracing.
				if (!isRayTracingStage(readerStage) && !isRayTracingStage(writerStage))
					continue;

				// Skip tests which require host acess to images.
				if (resourceType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE && (writerStage == Stage::HOST || readerStage == Stage::HOST))
					continue;

				// Skip tests that would require writes from shaders to an UBO.
				if (resourceType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER && writerStage != Stage::HOST && writerStage != Stage::TRANSFER)
					continue;

				const std::string testName = std::string("from_") + stageList[writerStageIdx].name + "_to_" + stageList[readerStageIdx].name;
				barrierTypeGroup->addChild(new BarrierTestCase(testCtx, testName, "", TestParams(resourceType, writerStage, readerStage, barrierType)));
			}
			resourceTypeGroup->addChild(barrierTypeGroup.release());
		}
		group->addChild(resourceTypeGroup.release());
	}
	return group.release();
}

} // RayTracing
} // vkt
