/*-------------------------------------------------------------------------
 * Vulkan Conformance Tests
 * ------------------------
 *
 * Copyright (c) 2017 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 SPIR-V Loop Control for DependencyLength qualifier tests
 *//*--------------------------------------------------------------------*/

#include "vkApiVersion.hpp"

#include "vktSpvAsmLoopDepLenTests.hpp"
#include "vktTestCase.hpp"
#include "vktSpvAsmComputeShaderCase.hpp"

#include "deRandom.hpp"

namespace vkt
{
namespace SpirVAssembly
{

using namespace vk;
using std::map;
using std::string;
using std::vector;

// Assembly code used for testing loop control with dependencies is based on GLSL source code:
// #version 430
//
// layout(std140, set = 0, binding = 0) readonly buffer Input {
//   float elements[];
// } input_data;
// layout(std140, set = 0, binding = 1) writeonly buffer Output {
//   float elements[];
// } output_data;
//
// void main() {
//   const uint n = 12;
//   float c[n];
//   uint x = gl_GlobalInvocationID.x;
//
//   for (uint i = 0; i < 6; ++i)
//     c[i] = float(i) * input_data.elements[x];
//
//   for (uint i = 6; i < n; ++i)
//     c[i] = c[i - 4] + c[i - 5] + c[i - 6];
//
//   output_data.elements[x] = c[n - 1];
// }
static void getComputeSourceCode (std::string& computeSourceCode)
{
	computeSourceCode =
		string(getComputeAsmShaderPreamble()) +

		"OpSource GLSL 430\n"
		"OpName %main \"main\"\n"
		"OpName %id \"gl_GlobalInvocationID\"\n"

		"OpDecorate %id BuiltIn GlobalInvocationId\n"

		+ string(getComputeAsmInputOutputBufferTraits()) + string(getComputeAsmCommonTypes()) + string(getComputeAsmInputOutputBuffer()) +

		"%u32ptr        = OpTypePointer Function %u32\n"

		"%id            = OpVariable %uvec3ptr Input\n"
		"%zero          = OpConstant %i32 0\n"
		"%uzero         = OpConstant %u32 0\n"
		"%one           = OpConstant %i32 1\n"

		"%four          = OpConstant %u32 4\n"
		"%five          = OpConstant %u32 5\n"
		"%six           = OpConstant %u32 6\n"
		"%elleven       = OpConstant %u32 11\n"
		"%twelve        = OpConstant %u32 12\n"

		"%f32arr12_t    = OpTypeArray %f32 %twelve\n"
		"%f32arr12ptr_t = OpTypePointer Function %f32arr12_t\n"
		"%f32funcptr    = OpTypePointer Function %f32\n"

		"%main          = OpFunction %void None %voidf\n"
		"%entry         = OpLabel\n"

		"%f32arr12      = OpVariable %f32arr12ptr_t Function\n"

		"%i1            = OpVariable %u32ptr Function\n"
		"%i2            = OpVariable %u32ptr Function\n"
		"                 OpStore %i1 %uzero\n"
		"                 OpStore %i2 %six\n"

		"%idval         = OpLoad %uvec3 %id\n"
		"%x             = OpCompositeExtract %u32 %idval 0\n"
		"%inloc         = OpAccessChain %f32ptr %indata %zero %x\n"
		"%inval         = OpLoad %f32 %inloc\n"

		// for (uint i = 0; i < 6; ++i) c[i] = float(i) * input_data.elements[x];
		"                 OpBranch %loop1_entry\n"
		"%loop1_entry   = OpLabel\n"
		"%i1_val        = OpLoad %u32 %i1\n"
		"%cmp1_lt       = OpULessThan %bool %i1_val %six\n"
		"                 OpLoopMerge %loop1_merge %loop1_body None\n"
		"                 OpBranchConditional %cmp1_lt %loop1_body %loop1_merge\n"
		"%loop1_body    = OpLabel\n"
		"%i1_valf32     = OpConvertUToF %f32 %i1_val\n"
		"%mulf1         = OpFMul %f32 %i1_valf32 %inval\n"
		"%outloc1       = OpAccessChain %f32funcptr %f32arr12 %i1_val\n"
		"                 OpStore %outloc1 %mulf1\n"
		"%new1_i        = OpIAdd %u32 %i1_val %one\n"
		"                 OpStore %i1 %new1_i\n"
		"                 OpBranch %loop1_entry\n"
		"%loop1_merge   = OpLabel\n"

		//   for (uint i = 6; i < n; ++i) c[i] = c[i - 4] + c[i - 5] + c[i - 6];
		"                 OpBranch %loop2_entry\n"
		"%loop2_entry   = OpLabel\n"
		"%i2_val        = OpLoad %u32 %i2\n"
		"%cmp2_lt       = OpULessThan %bool %i2_val %twelve\n"
		"                 OpLoopMerge %loop2_merge %loop2_body DependencyLength 3\n"
		"                 OpBranchConditional %cmp2_lt %loop2_body %loop2_merge\n"
		"%loop2_body    = OpLabel\n"
		"%i2_m4         = OpISub %u32 %i2_val %four\n"
		"%arr1_i2m4loc  = OpAccessChain %f32funcptr %f32arr12 %i2_m4\n"
		"%arr1_i2m4val  = OpLoad %f32 %arr1_i2m4loc\n"
		"%i2_m5         = OpISub %u32 %i2_val %five\n"
		"%arr1_i2m5loc  = OpAccessChain %f32funcptr %f32arr12 %i2_m5\n"
		"%arr1_i2m5val  = OpLoad %f32 %arr1_i2m5loc\n"
		"%f32add1       = OpFAdd %f32 %arr1_i2m4val %arr1_i2m5val\n"
		"%i2_m6         = OpISub %u32 %i2_val %six\n"
		"%arr1_i2m6loc  = OpAccessChain %f32funcptr %f32arr12 %i2_m6\n"
		"%arr1_i2m6val  = OpLoad %f32 %arr1_i2m6loc\n"
		"%f32add2       = OpFAdd %f32 %f32add1 %arr1_i2m6val\n"
		"%outloc2       = OpAccessChain %f32funcptr %f32arr12 %i2_val\n"
		"                 OpStore %outloc2 %f32add2\n"
		"%new_i2        = OpIAdd %u32 %i2_val %one\n"
		"                 OpStore %i2 %new_i2\n"
		"                 OpBranch %loop2_entry\n"
		"%loop2_merge   = OpLabel\n"

		//   output_data.elements[x] = c[n - 1];
		"%arr1locq      = OpAccessChain %f32funcptr %f32arr12 %elleven\n"
		"%arr1valq      = OpLoad %f32 %arr1locq\n"
		"%outlocq       = OpAccessChain %f32ptr %outdata %zero %x\n"
		"                 OpStore %outlocq %arr1valq\n"
		"                 OpReturn\n"
		"                 OpFunctionEnd\n";
}

static ComputeShaderSpec getComputeShaderSpec ()
{
	de::Random			rnd				(0xABC);
	const int			numElements		= 100;
	vector<float>		inputFloats		(numElements, 0);
	vector<float>		outputFloats	(numElements, 0);
	ComputeShaderSpec	spec;

	for (size_t ndx = 0; ndx < numElements; ++ndx)
		inputFloats[ndx] = rnd.getFloat(1.0f, 100.0f);

	for (size_t ndx = 0; ndx < numElements; ++ndx)
	{
		const deUint32 n = 12;
		float c[n];

		for (deUint32 i = 0; i < 6; ++i)
			c[i] = float(i) * inputFloats[ndx];

		for (deUint32 i = 6; i < n; ++i)
			c[i] = c[i - 4] + c[i - 5] + c[i - 6];

		outputFloats[ndx] = c[n - 1];
	}

	// Shader source code can be retrieved to complete definition of ComputeShaderSpec, though it is not required at this stage
	// getComputeSourceCode (spec.assembly);

	spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
	spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
	spec.numWorkGroups	= tcu::IVec3(numElements, 1, 1);
	spec.verifyIO		= &verifyOutput;

	return spec;
}


class SpvAsmLoopControlDependencyLengthInstance : public ComputeShaderSpec, public SpvAsmComputeShaderInstance
{
public:
	SpvAsmLoopControlDependencyLengthInstance	(Context& ctx);
};

SpvAsmLoopControlDependencyLengthInstance::SpvAsmLoopControlDependencyLengthInstance (Context& ctx)
	: ComputeShaderSpec(getComputeShaderSpec())
	, SpvAsmComputeShaderInstance(ctx, *this)
{
}

SpvAsmLoopControlDependencyLengthCase::SpvAsmLoopControlDependencyLengthCase (tcu::TestContext& testCtx, const char* name, const char* description)
	: TestCase			(testCtx, name, description)
{
}

void SpvAsmLoopControlDependencyLengthCase::initPrograms (SourceCollections& programCollection) const
{
	std::string comp;

	getComputeSourceCode(comp);

	programCollection.spirvAsmSources.add("compute") << SpirVAsmBuildOptions(programCollection.usedVulkanVersion, SPIRV_VERSION_1_3) << comp;
}

TestInstance* SpvAsmLoopControlDependencyLengthCase::createInstance (Context& context) const
{
	if (!context.contextSupports(vk::ApiVersion(1, 1, 0)))
		TCU_THROW(NotSupportedError, "SPIR-V higher than 1.3 is required for this test to run");

	return new SpvAsmLoopControlDependencyLengthInstance(context);
}

} // SpirVAssembly
} // vkt
