/*
 * Copyright 2015-2017 ARM Limited
 *
 * 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.
 */

#ifndef SPIRV_CROSS_INTERNAL_INTERFACE_HPP
#define SPIRV_CROSS_INTERNAL_INTERFACE_HPP

// This file must only be included by the shader generated by spirv-cross!

#ifndef GLM_FORCE_SWIZZLE
#define GLM_FORCE_SWIZZLE
#endif

#ifndef GLM_FORCE_RADIANS
#define GLM_FORCE_RADIANS
#endif

#include <glm/glm.hpp>

#include "barrier.hpp"
#include "external_interface.h"
#include "image.hpp"
#include "sampler.hpp"
#include "thread_group.hpp"
#include <assert.h>
#include <stdint.h>

namespace internal
{
// Adaptor helpers to adapt GLSL access chain syntax to C++.
// Don't bother with arrays of arrays on uniforms ...
// Would likely need horribly complex variadic template munging.

template <typename T>
struct Interface
{
	enum
	{
		ArraySize = 1,
		Size = sizeof(T)
	};

	Interface()
	    : ptr(0)
	{
	}
	T &get()
	{
		assert(ptr);
		return *ptr;
	}

	T *ptr;
};

// For array types, return a pointer instead.
template <typename T, unsigned U>
struct Interface<T[U]>
{
	enum
	{
		ArraySize = U,
		Size = U * sizeof(T)
	};

	Interface()
	    : ptr(0)
	{
	}
	T *get()
	{
		assert(ptr);
		return ptr;
	}

	T *ptr;
};

// For case when array size is 1, avoid double dereference.
template <typename T>
struct PointerInterface
{
	enum
	{
		ArraySize = 1,
		Size = sizeof(T *)
	};
	enum
	{
		PreDereference = true
	};

	PointerInterface()
	    : ptr(0)
	{
	}

	T &get()
	{
		assert(ptr);
		return *ptr;
	}

	T *ptr;
};

// Automatically converts a pointer down to reference to match GLSL syntax.
template <typename T>
struct DereferenceAdaptor
{
	DereferenceAdaptor(T **ptr)
	    : ptr(ptr)
	{
	}
	T &operator[](unsigned index) const
	{
		return *(ptr[index]);
	}
	T **ptr;
};

// We can't have a linear array of T* since T* can be an abstract type in case of samplers.
// We also need a list of pointers since we can have run-time length SSBOs.
template <typename T, unsigned U>
struct PointerInterface<T[U]>
{
	enum
	{
		ArraySize = U,
		Size = sizeof(T *) * U
	};
	enum
	{
		PreDereference = false
	};
	PointerInterface()
	    : ptr(0)
	{
	}

	DereferenceAdaptor<T> get()
	{
		assert(ptr);
		return DereferenceAdaptor<T>(ptr);
	}

	T **ptr;
};

// Resources can be more abstract and be unsized,
// so we need to have an array of pointers for those cases.
template <typename T>
struct Resource : PointerInterface<T>
{
};

// POD with no unknown sizes, so we can express these as flat arrays.
template <typename T>
struct UniformConstant : Interface<T>
{
};
template <typename T>
struct StageInput : Interface<T>
{
};
template <typename T>
struct StageOutput : Interface<T>
{
};
template <typename T>
struct PushConstant : Interface<T>
{
};
}

struct spirv_cross_shader
{
	struct PPSize
	{
		PPSize()
		    : ptr(0)
		    , size(0)
		{
		}
		void **ptr;
		size_t size;
	};

	struct PPSizeResource
	{
		PPSizeResource()
		    : ptr(0)
		    , size(0)
		    , pre_dereference(false)
		{
		}
		void **ptr;
		size_t size;
		bool pre_dereference;
	};

	PPSizeResource resources[SPIRV_CROSS_NUM_DESCRIPTOR_SETS][SPIRV_CROSS_NUM_DESCRIPTOR_BINDINGS];
	PPSize stage_inputs[SPIRV_CROSS_NUM_STAGE_INPUTS];
	PPSize stage_outputs[SPIRV_CROSS_NUM_STAGE_OUTPUTS];
	PPSize uniform_constants[SPIRV_CROSS_NUM_UNIFORM_CONSTANTS];
	PPSize push_constant;
	PPSize builtins[SPIRV_CROSS_NUM_BUILTINS];

	template <typename U>
	void register_builtin(spirv_cross_builtin builtin, const U &value)
	{
		assert(!builtins[builtin].ptr);

		builtins[builtin].ptr = (void **)&value.ptr;
		builtins[builtin].size = sizeof(*value.ptr) * U::ArraySize;
	}

	void set_builtin(spirv_cross_builtin builtin, void *data, size_t size)
	{
		assert(builtins[builtin].ptr);
		assert(size >= builtins[builtin].size);

		*builtins[builtin].ptr = data;
	}

	template <typename U>
	void register_resource(const internal::Resource<U> &value, unsigned set, unsigned binding)
	{
		assert(set < SPIRV_CROSS_NUM_DESCRIPTOR_SETS);
		assert(binding < SPIRV_CROSS_NUM_DESCRIPTOR_BINDINGS);
		assert(!resources[set][binding].ptr);

		resources[set][binding].ptr = (void **)&value.ptr;
		resources[set][binding].size = internal::Resource<U>::Size;
		resources[set][binding].pre_dereference = internal::Resource<U>::PreDereference;
	}

	template <typename U>
	void register_stage_input(const internal::StageInput<U> &value, unsigned location)
	{
		assert(location < SPIRV_CROSS_NUM_STAGE_INPUTS);
		assert(!stage_inputs[location].ptr);

		stage_inputs[location].ptr = (void **)&value.ptr;
		stage_inputs[location].size = internal::StageInput<U>::Size;
	}

	template <typename U>
	void register_stage_output(const internal::StageOutput<U> &value, unsigned location)
	{
		assert(location < SPIRV_CROSS_NUM_STAGE_OUTPUTS);
		assert(!stage_outputs[location].ptr);

		stage_outputs[location].ptr = (void **)&value.ptr;
		stage_outputs[location].size = internal::StageOutput<U>::Size;
	}

	template <typename U>
	void register_uniform_constant(const internal::UniformConstant<U> &value, unsigned location)
	{
		assert(location < SPIRV_CROSS_NUM_UNIFORM_CONSTANTS);
		assert(!uniform_constants[location].ptr);

		uniform_constants[location].ptr = (void **)&value.ptr;
		uniform_constants[location].size = internal::UniformConstant<U>::Size;
	}

	template <typename U>
	void register_push_constant(const internal::PushConstant<U> &value)
	{
		assert(!push_constant.ptr);

		push_constant.ptr = (void **)&value.ptr;
		push_constant.size = internal::PushConstant<U>::Size;
	}

	void set_stage_input(unsigned location, void *data, size_t size)
	{
		assert(location < SPIRV_CROSS_NUM_STAGE_INPUTS);
		assert(stage_inputs[location].ptr);
		assert(size >= stage_inputs[location].size);

		*stage_inputs[location].ptr = data;
	}

	void set_stage_output(unsigned location, void *data, size_t size)
	{
		assert(location < SPIRV_CROSS_NUM_STAGE_OUTPUTS);
		assert(stage_outputs[location].ptr);
		assert(size >= stage_outputs[location].size);

		*stage_outputs[location].ptr = data;
	}

	void set_uniform_constant(unsigned location, void *data, size_t size)
	{
		assert(location < SPIRV_CROSS_NUM_UNIFORM_CONSTANTS);
		assert(uniform_constants[location].ptr);
		assert(size >= uniform_constants[location].size);

		*uniform_constants[location].ptr = data;
	}

	void set_push_constant(void *data, size_t size)
	{
		assert(push_constant.ptr);
		assert(size >= push_constant.size);

		*push_constant.ptr = data;
	}

	void set_resource(unsigned set, unsigned binding, void **data, size_t size)
	{
		assert(set < SPIRV_CROSS_NUM_DESCRIPTOR_SETS);
		assert(binding < SPIRV_CROSS_NUM_DESCRIPTOR_BINDINGS);
		assert(resources[set][binding].ptr);
		assert(size >= resources[set][binding].size);

		// We're using the regular PointerInterface, dereference ahead of time.
		if (resources[set][binding].pre_dereference)
			*resources[set][binding].ptr = *data;
		else
			*resources[set][binding].ptr = data;
	}
};

namespace spirv_cross
{
template <typename T>
struct BaseShader : spirv_cross_shader
{
	void invoke()
	{
		static_cast<T *>(this)->main();
	}
};

struct FragmentResources
{
	internal::StageOutput<glm::vec4> gl_FragCoord;
	void init(spirv_cross_shader &s)
	{
		s.register_builtin(SPIRV_CROSS_BUILTIN_FRAG_COORD, gl_FragCoord);
	}
#define gl_FragCoord __res->gl_FragCoord.get()
};

template <typename T, typename Res>
struct FragmentShader : BaseShader<FragmentShader<T, Res>>
{
	inline void main()
	{
		impl.main();
	}

	FragmentShader()
	{
		resources.init(*this);
		impl.__res = &resources;
	}

	T impl;
	Res resources;
};

struct VertexResources
{
	internal::StageOutput<glm::vec4> gl_Position;
	void init(spirv_cross_shader &s)
	{
		s.register_builtin(SPIRV_CROSS_BUILTIN_POSITION, gl_Position);
	}
#define gl_Position __res->gl_Position.get()
};

template <typename T, typename Res>
struct VertexShader : BaseShader<VertexShader<T, Res>>
{
	inline void main()
	{
		impl.main();
	}

	VertexShader()
	{
		resources.init(*this);
		impl.__res = &resources;
	}

	T impl;
	Res resources;
};

struct TessEvaluationResources
{
	inline void init(spirv_cross_shader &)
	{
	}
};

template <typename T, typename Res>
struct TessEvaluationShader : BaseShader<TessEvaluationShader<T, Res>>
{
	inline void main()
	{
		impl.main();
	}

	TessEvaluationShader()
	{
		resources.init(*this);
		impl.__res = &resources;
	}

	T impl;
	Res resources;
};

struct TessControlResources
{
	inline void init(spirv_cross_shader &)
	{
	}
};

template <typename T, typename Res>
struct TessControlShader : BaseShader<TessControlShader<T, Res>>
{
	inline void main()
	{
		impl.main();
	}

	TessControlShader()
	{
		resources.init(*this);
		impl.__res = &resources;
	}

	T impl;
	Res resources;
};

struct GeometryResources
{
	inline void init(spirv_cross_shader &)
	{
	}
};

template <typename T, typename Res>
struct GeometryShader : BaseShader<GeometryShader<T, Res>>
{
	inline void main()
	{
		impl.main();
	}

	GeometryShader()
	{
		resources.init(*this);
		impl.__res = &resources;
	}

	T impl;
	Res resources;
};

struct ComputeResources
{
	internal::StageInput<glm::uvec3> gl_WorkGroupID__;
	internal::StageInput<glm::uvec3> gl_NumWorkGroups__;
	void init(spirv_cross_shader &s)
	{
		s.register_builtin(SPIRV_CROSS_BUILTIN_WORK_GROUP_ID, gl_WorkGroupID__);
		s.register_builtin(SPIRV_CROSS_BUILTIN_NUM_WORK_GROUPS, gl_NumWorkGroups__);
	}
#define gl_WorkGroupID __res->gl_WorkGroupID__.get()
#define gl_NumWorkGroups __res->gl_NumWorkGroups__.get()

	Barrier barrier__;
#define barrier() __res->barrier__.wait()
};

struct ComputePrivateResources
{
	uint32_t gl_LocalInvocationIndex__;
#define gl_LocalInvocationIndex __priv_res.gl_LocalInvocationIndex__
	glm::uvec3 gl_LocalInvocationID__;
#define gl_LocalInvocationID __priv_res.gl_LocalInvocationID__
	glm::uvec3 gl_GlobalInvocationID__;
#define gl_GlobalInvocationID __priv_res.gl_GlobalInvocationID__
};

template <typename T, typename Res, unsigned WorkGroupX, unsigned WorkGroupY, unsigned WorkGroupZ>
struct ComputeShader : BaseShader<ComputeShader<T, Res, WorkGroupX, WorkGroupY, WorkGroupZ>>
{
	inline void main()
	{
		resources.barrier__.reset_counter();

		for (unsigned z = 0; z < WorkGroupZ; z++)
			for (unsigned y = 0; y < WorkGroupY; y++)
				for (unsigned x = 0; x < WorkGroupX; x++)
					impl[z][y][x].__priv_res.gl_GlobalInvocationID__ =
					    glm::uvec3(WorkGroupX, WorkGroupY, WorkGroupZ) * resources.gl_WorkGroupID__.get() +
					    glm::uvec3(x, y, z);

		group.run();
		group.wait();
	}

	ComputeShader()
	    : group(&impl[0][0][0])
	{
		resources.init(*this);
		resources.barrier__.set_release_divisor(WorkGroupX * WorkGroupY * WorkGroupZ);

		unsigned i = 0;
		for (unsigned z = 0; z < WorkGroupZ; z++)
		{
			for (unsigned y = 0; y < WorkGroupY; y++)
			{
				for (unsigned x = 0; x < WorkGroupX; x++)
				{
					impl[z][y][x].__priv_res.gl_LocalInvocationID__ = glm::uvec3(x, y, z);
					impl[z][y][x].__priv_res.gl_LocalInvocationIndex__ = i++;
					impl[z][y][x].__res = &resources;
				}
			}
		}
	}

	T impl[WorkGroupZ][WorkGroupY][WorkGroupX];
	ThreadGroup<T, WorkGroupX * WorkGroupY * WorkGroupZ> group;
	Res resources;
};

inline void memoryBarrierShared()
{
	Barrier::memoryBarrier();
}
inline void memoryBarrier()
{
	Barrier::memoryBarrier();
}
// TODO: Rest of the barriers.

// Atomics
template <typename T>
inline T atomicAdd(T &v, T a)
{
	static_assert(sizeof(std::atomic<T>) == sizeof(T), "Cannot cast properly to std::atomic<T>.");

	// We need explicit memory barriers in GLSL to enfore any ordering.
	// FIXME: Can we really cast this? There is no other way I think ...
	return std::atomic_fetch_add_explicit(reinterpret_cast<std::atomic<T> *>(&v), a, std::memory_order_relaxed);
}
}

void spirv_cross_set_stage_input(spirv_cross_shader_t *shader, unsigned location, void *data, size_t size)
{
	shader->set_stage_input(location, data, size);
}

void spirv_cross_set_stage_output(spirv_cross_shader_t *shader, unsigned location, void *data, size_t size)
{
	shader->set_stage_output(location, data, size);
}

void spirv_cross_set_uniform_constant(spirv_cross_shader_t *shader, unsigned location, void *data, size_t size)
{
	shader->set_uniform_constant(location, data, size);
}

void spirv_cross_set_resource(spirv_cross_shader_t *shader, unsigned set, unsigned binding, void **data, size_t size)
{
	shader->set_resource(set, binding, data, size);
}

void spirv_cross_set_push_constant(spirv_cross_shader_t *shader, void *data, size_t size)
{
	shader->set_push_constant(data, size);
}

void spirv_cross_set_builtin(spirv_cross_shader_t *shader, spirv_cross_builtin builtin, void *data, size_t size)
{
	shader->set_builtin(builtin, data, size);
}

#endif
