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

#include "vktPostmortemTests.hpp"
#include "vktPostmortemShaderTimeoutTests.hpp"
#include "vktTestGroupUtil.hpp"
#include "vktTestCase.hpp"
#include "vkBarrierUtil.hpp"
#include "vkBufferWithMemory.hpp"
#include "vkBuilderUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkDefs.hpp"
#include "vkObjUtil.hpp"
#include "vkTypeUtil.hpp"
#include "deUniquePtr.hpp"
#include "tcuCommandLine.hpp"
#include "vktCustomInstancesDevices.hpp"
#include "vktPostmortemUtil.hpp"

using namespace vk;

namespace vkt
{
namespace postmortem
{
namespace
{

class ShaderTimeoutCase : public vkt::TestCase
{
public:
	ShaderTimeoutCase(tcu::TestContext& testCtx, const std::string& name, deUint32 iterations) : TestCase(testCtx, name, "Long-running compute shader"), m_iterations(iterations) {}

	TestInstance* createInstance(Context& context) const override;
	void initPrograms(vk::SourceCollections& programCollection) const override;

private:
	deUint32 m_iterations;
};

class ShaderTimeoutInstance : public PostmortemTestInstance
{
public:
	ShaderTimeoutInstance(Context& context, deUint32 iterations);

	tcu::TestStatus		iterate(void) override;

private:
	deUint32			m_iterations;
};


Move<VkPipeline> makeComputePipeline(const DeviceInterface&					vk,
									 const VkDevice							device,
									 const VkPipelineLayout					pipelineLayout,
									 const VkPipelineCreateFlags			pipelineFlags,
									 const VkShaderModule					shaderModule,
									 const VkPipelineShaderStageCreateFlags	shaderFlags)
{
	const VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
	{
		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
		DE_NULL,												// const void*							pNext;
		shaderFlags,											// VkPipelineShaderStageCreateFlags		flags;
		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
		shaderModule,											// VkShaderModule						module;
		"main",													// const char*							pName;
		DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
	};
	const VkComputePipelineCreateInfo pipelineCreateInfo =
	{
		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
		DE_NULL,											// const void*						pNext;
		pipelineFlags,										// VkPipelineCreateFlags			flags;
		pipelineShaderStageParams,							// VkPipelineShaderStageCreateInfo	stage;
		pipelineLayout,										// VkPipelineLayout					layout;
		DE_NULL,											// VkPipeline						basePipelineHandle;
		0,													// deInt32							basePipelineIndex;
	};
	return createComputePipeline(vk, device, DE_NULL, &pipelineCreateInfo);
}

Move<VkPipeline> makeComputePipeline(const DeviceInterface&		vk,
									 const VkDevice				device,
									 const VkPipelineLayout		pipelineLayout,
									 const VkShaderModule		shaderModule)
{
	return makeComputePipeline(vk, device, pipelineLayout, static_cast<VkPipelineCreateFlags>(0u), shaderModule, static_cast<VkPipelineShaderStageCreateFlags>(0u));
}

ShaderTimeoutInstance::ShaderTimeoutInstance(Context& context, deUint32 iterations)
	: PostmortemTestInstance(context), m_iterations(iterations)
{

}

TestInstance* ShaderTimeoutCase::createInstance(Context& context) const
{
	return new ShaderTimeoutInstance(context, m_iterations);
}

void ShaderTimeoutCase::initPrograms(vk::SourceCollections& programCollection) const
{
	std::ostringstream src;
	src << "#version 320 es\n"
		<< "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1)\n"
		<< "layout(binding = 0) uniform Params {\n"
		<< "  int x;\n"
		<< "  int y;\n"
		<< "} bounds;\n"
		<< "layout(std430, binding = 1) buffer  Output {\n"
		<< "  uint values[];\n"
		<< "} sb_out;\n"
		<< "\n"
		<< "void main()\n"
		<< "{\n"
		<< "  uint localSize = gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_WorkGroupSize.z;\n"
		<< "  uint globalNdx = gl_NumWorkGroups.x * gl_NumWorkGroups.y * gl_WorkGroupID.z + gl_NumWorkGroups.x * gl_WorkGroupID.y + gl_WorkGroupID.x;\n"
		<< "  uint globalOffs = localSize * globalNdx;\n"
		<< "  uint localOffs = gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_LocalInvocationID.z + gl_WorkGroupSize.x * gl_LocalInvocationID.y + gl_LocalInvocationID.x;\n"
		<< "  uint sum = uint(0);\n"
		<< "  for (int y = 0; y < bounds.y; ++y) {\n"
		<< "    for (int x = 0; x < bounds.x; ++x) {\n"
		<< "	  sb_out.values[globalOffs + localOffs] = sb_out.values[globalOffs + localOffs] + uint(1);\n"
		<< "      memoryBarrierBuffer();\n"
		<< "      barrier();\n"
		<< "    }\n"
		<< "  }\n"
		<< "}\n";

	programCollection.glslSources.add("comp") << glu::ComputeSource(src.str());
}

tcu::TestStatus	ShaderTimeoutInstance::iterate(void)
{
	const VkDevice			device				= *m_logicalDevice;
	const DeviceInterface&	vk					= m_deviceDriver;
	const VkQueue			queue				= m_queue;
	const deUint32			queueFamilyIndex	= m_queueFamilyIndex;
	Allocator&				allocator			= m_allocator;

	const int workSize = 1024;
	const VkDeviceSize storageSizeInBytes = sizeof(deUint32) * workSize;
	const VkDeviceSize uniformSizeInBytes = sizeof(deUint32) * 2;

	// Create storage and uniform buffers
	BufferWithMemory storageBuffer(vk, device, allocator,
		makeBufferCreateInfo(storageSizeInBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
		MemoryRequirement::HostVisible);
	BufferWithMemory uniformBuffer(vk, device, allocator,
		makeBufferCreateInfo(uniformSizeInBytes, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),
		MemoryRequirement::HostVisible);

	// Fill storage buffer with sequentially increasing values
	{
		const Allocation& storageBufferAllocation = storageBuffer.getAllocation();
		deUint32* storageBufferPtr = static_cast<deUint32*>(storageBufferAllocation.getHostPtr());
		for (int i = 0; i < workSize; ++i)
			storageBufferPtr[i] = i;

		flushAlloc(vk, device, storageBufferAllocation);
	}

	// Set uniforms for shader loop bounds to m_iterations
	{
		const Allocation& uniformBufferAllocation = uniformBuffer.getAllocation();
		deUint32* uniformBufferPtr = static_cast<deUint32*>(uniformBufferAllocation.getHostPtr());
		uniformBufferPtr[0] = m_iterations;
		uniformBufferPtr[1] = m_iterations;

		flushAlloc(vk, device, uniformBufferAllocation);
	}

	const Unique<VkDescriptorSetLayout> descriptorSetLayout(
		DescriptorSetLayoutBuilder()
		.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
		.build(vk, device));

	const Unique<VkDescriptorPool> descriptorPool(
		DescriptorPoolBuilder()
		.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
		.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));

	const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));

	const VkDescriptorBufferInfo uniformDescriptorInfo = makeDescriptorBufferInfo(*uniformBuffer, 0ull, uniformSizeInBytes);
	const VkDescriptorBufferInfo storageDescriptorInfo = makeDescriptorBufferInfo(*storageBuffer, 0ull, storageSizeInBytes);
	DescriptorSetUpdateBuilder()
		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &uniformDescriptorInfo)
		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &storageDescriptorInfo)
		.update(vk, device);

	// Create pipelines
	const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0u));
	const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, *descriptorSetLayout));
	const Unique<VkPipeline> pipeline(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));

	const VkBufferMemoryBarrier hostWriteBarriers[2] =
	{
		makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, *storageBuffer, 0ull, storageSizeInBytes),
		makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_UNIFORM_READ_BIT, *uniformBuffer, 0ull, uniformSizeInBytes)
	};
	const VkBufferMemoryBarrier computeFinishBarrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *storageBuffer, 0ull, storageSizeInBytes);

	// Create command buffer and launch dispatch,
	const Unique<VkCommandPool> cmdPool(makeCommandPool(vk, device, queueFamilyIndex));
	const Unique<VkCommandBuffer> cmdBuffer(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));

	beginCommandBuffer(vk, *cmdBuffer);
	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
	vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 2u, hostWriteBarriers, 0, (const VkImageMemoryBarrier*)DE_NULL);
	vk.cmdDispatch(*cmdBuffer, workSize, 1, 1);
	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*) DE_NULL, 1u, &computeFinishBarrier, 0, (const VkImageMemoryBarrier*) DE_NULL);
	endCommandBuffer(vk, *cmdBuffer);

	submitCommandsAndWait(vk, device, queue, *cmdBuffer);

	// Verify output
	const Allocation& storageAllocation = storageBuffer.getAllocation();
	invalidateAlloc(vk, device, storageAllocation);

	const deUint32* bufferPtr = static_cast<deUint32*>(storageAllocation.getHostPtr());
	for (int i = 0; i < workSize; ++i)
	{
		const deUint32	res = bufferPtr[i];
		const deUint32	ref = i + m_iterations * m_iterations;
		if (res != ref)
		{
			std::ostringstream msg;
			msg << "Comparison failed for sb_out.values[" << i << "] ref:" << ref << " res:" << res;
			return tcu::TestStatus::fail(msg.str());
		}
	}

	return tcu::TestStatus::pass("Test succeeded without device loss");
}

}

tcu::TestCaseGroup* createShaderTimeoutTests(tcu::TestContext& testCtx)
{
	de::MovePtr<tcu::TestCaseGroup> timeoutGroup(new tcu::TestCaseGroup(testCtx, "shader_timeout", "Shader timeout tests."));
	for (int i = 0; i < 16; ++i)
	{
		deUint32 iterations = 0x1u << i;
		std::stringstream name;
		name << "compute_" << iterations << "x" << iterations;
		timeoutGroup->addChild(new ShaderTimeoutCase(testCtx, name.str(), iterations));
	}

	return timeoutGroup.release();
}

} // postmortem
} // vkt
