// 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

#include "SpirvShader.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
