// Copyright 2020 The SwiftShader Authors. All Rights Reserved.
//
// 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 sw_SpirvShaderDebug_hpp
#define sw_SpirvShaderDebug_hpp

// Enable this to print verbose debug messages as each SPIR-V instructon is
// executed. Very handy for performing text diffs when the thread count is
// reduced to 1 and execution is deterministic.
#define SPIRV_SHADER_ENABLE_DBG 0

// Enable this to write a GraphViz dot file containing a graph of the shader's
// control flow to the given file path. Helpful for diagnosing control-flow
// related issues.
#if 0
#	define SPIRV_SHADER_CFG_GRAPHVIZ_DOT_FILEPATH "swiftshader_%d.dot"
#endif

#if SPIRV_SHADER_ENABLE_DBG
#	define SPIRV_SHADER_DBG(fmt, ...) rr::Print(fmt "\n", ##__VA_ARGS__)
#	include "spirv-tools/libspirv.h"
namespace spvtools {
// Function implemented in third_party/SPIRV-Tools/source/disassemble.cpp
// but with no public header.
std::string spvInstructionBinaryToText(const spv_target_env env,
                                       const uint32_t *inst_binary,
                                       const size_t inst_word_count,
                                       const uint32_t *binary,
                                       const size_t word_count,
                                       const uint32_t options);

}  // namespace spvtools
#else
#	define SPIRV_SHADER_DBG(...)
#endif  // SPIRV_SHADER_ENABLE_DBG

#ifdef ENABLE_RR_PRINT
namespace rr {
template<>
struct PrintValue::Ty<sw::SpirvShader::Object::ID>
{
	static inline std::string fmt(sw::SpirvShader::Object::ID v) { return "Object<" + std::to_string(v.value()) + ">"; }
	static inline std::vector<Value *> val(sw::SpirvShader::Object::ID v) { return {}; }
};
template<>
struct PrintValue::Ty<sw::SpirvShader::Type::ID>
{
	static inline std::string fmt(sw::SpirvShader::Type::ID v) { return "Type<" + std::to_string(v.value()) + ">"; }
	static inline std::vector<Value *> val(sw::SpirvShader::Type::ID v) { return {}; }
};
template<>
struct PrintValue::Ty<sw::SpirvShader::Block::ID>
{
	static inline std::string fmt(sw::SpirvShader::Block::ID v) { return "Block<" + std::to_string(v.value()) + ">"; }
	static inline std::vector<Value *> val(sw::SpirvShader::Block::ID v) { return {}; }
};

template<>
struct PrintValue::Ty<sw::Intermediate>
{
	static inline std::string fmt(const sw::Intermediate &v, uint32_t i)
	{
		switch(v.typeHint)
		{
			case sw::Intermediate::TypeHint::Float:
				return PrintValue::Ty<sw::SIMD::Float>::fmt(v.Float(i));
			case sw::Intermediate::TypeHint::Int:
				return PrintValue::Ty<sw::SIMD::Int>::fmt(v.Int(i));
			case sw::Intermediate::TypeHint::UInt:
				return PrintValue::Ty<sw::SIMD::UInt>::fmt(v.UInt(i));
		}
		return "";
	}

	static inline std::vector<Value *> val(const sw::Intermediate &v, uint32_t i)
	{
		switch(v.typeHint)
		{
			case sw::Intermediate::TypeHint::Float:
				return PrintValue::Ty<sw::SIMD::Float>::val(v.Float(i));
			case sw::Intermediate::TypeHint::Int:
				return PrintValue::Ty<sw::SIMD::Int>::val(v.Int(i));
			case sw::Intermediate::TypeHint::UInt:
				return PrintValue::Ty<sw::SIMD::UInt>::val(v.UInt(i));
		}
		return {};
	}

	static inline std::string fmt(const sw::Intermediate &v)
	{
		if(v.componentCount == 1)
		{
			return fmt(v, 0);
		}

		std::string out = "[";
		for(uint32_t i = 0; i < v.componentCount; i++)
		{
			if(i > 0) { out += ", "; }
			out += std::to_string(i) + ": ";
			out += fmt(v, i);
		}
		return out + "]";
	}

	static inline std::vector<Value *> val(const sw::Intermediate &v)
	{
		std::vector<Value *> out;
		for(uint32_t i = 0; i < v.componentCount; i++)
		{
			auto vals = val(v, i);
			out.insert(out.end(), vals.begin(), vals.end());
		}
		return out;
	}
};

template<>
struct PrintValue::Ty<sw::SpirvShader::Operand>
{
	static inline std::string fmt(const sw::SpirvShader::Operand &v)
	{
		return (v.intermediate != nullptr) ? PrintValue::Ty<sw::Intermediate>::fmt(*v.intermediate) : PrintValue::Ty<sw::SIMD::UInt>::fmt(v.UInt(0));
	}

	static inline std::vector<Value *> val(const sw::SpirvShader::Operand &v)
	{
		return (v.intermediate != nullptr) ? PrintValue::Ty<sw::Intermediate>::val(*v.intermediate) : PrintValue::Ty<sw::SIMD::UInt>::val(v.UInt(0));
	}
};
}  // namespace rr
#endif  // ENABLE_RR_PRINT

#endif  // sw_SpirvShaderDebug_hpp
