/*------------------------------------------------------------------------
 * 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 unusedPayload;\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 unusedPayload;\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 vec3 unusedPayload;\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 unusedCallableData;"
				<< "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 unusedCallableData;\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 unusedPayload;\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 unusedPayload;\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 vec3 unusedPayload;\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 unusedCallableData;"
				<< "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 unusedCallableData;\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
