// Copyright 2016 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.

#include "PixelProcessor.hpp"

#include "Primitive.hpp"
#include "Pipeline/PixelProgram.hpp"
#include "Pipeline/Constants.hpp"
#include "Vulkan/VkDebug.hpp"
#include "Vulkan/VkImageView.hpp"

#include <cstring>

namespace sw {

uint32_t PixelProcessor::States::computeHash()
{
	uint32_t *state = reinterpret_cast<uint32_t*>(this);
	uint32_t hash = 0;

	for(unsigned int i = 0; i < sizeof(States) / sizeof(uint32_t); i++)
	{
		hash ^= state[i];
	}

	return hash;
}

bool PixelProcessor::State::operator==(const State &state) const
{
	if(hash != state.hash)
	{
		return false;
	}

	static_assert(is_memcmparable<State>::value, "Cannot memcmp State");
	return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
}

PixelProcessor::PixelProcessor()
{
	routineCache = nullptr;
	setRoutineCacheSize(1024);
}

PixelProcessor::~PixelProcessor()
{
	delete routineCache;
	routineCache = nullptr;
}

void PixelProcessor::setBlendConstant(const Color<float> &blendConstant)
{
	// TODO(b/140935644): Compact into generic function, cheack if clamp is required
	factor.blendConstant4W[0][0] =
	factor.blendConstant4W[0][1] =
	factor.blendConstant4W[0][2] =
	factor.blendConstant4W[0][3] = static_cast<uint16_t>(iround(65535.0f * blendConstant.r));

	factor.blendConstant4W[1][0] =
	factor.blendConstant4W[1][1] =
	factor.blendConstant4W[1][2] =
	factor.blendConstant4W[1][3] = static_cast<uint16_t>(iround(65535.0f * blendConstant.g));

	factor.blendConstant4W[2][0] =
	factor.blendConstant4W[2][1] =
	factor.blendConstant4W[2][2] =
	factor.blendConstant4W[2][3] = static_cast<uint16_t>(iround(65535.0f * blendConstant.b));

	factor.blendConstant4W[3][0] =
	factor.blendConstant4W[3][1] =
	factor.blendConstant4W[3][2] =
	factor.blendConstant4W[3][3] = static_cast<uint16_t>(iround(65535.0f * blendConstant.a));

	factor.invBlendConstant4W[0][0] =
	factor.invBlendConstant4W[0][1] =
	factor.invBlendConstant4W[0][2] =
	factor.invBlendConstant4W[0][3] = 0xFFFFu - factor.blendConstant4W[0][0];

	factor.invBlendConstant4W[1][0] =
	factor.invBlendConstant4W[1][1] =
	factor.invBlendConstant4W[1][2] =
	factor.invBlendConstant4W[1][3] = 0xFFFFu - factor.blendConstant4W[1][0];

	factor.invBlendConstant4W[2][0] =
	factor.invBlendConstant4W[2][1] =
	factor.invBlendConstant4W[2][2] =
	factor.invBlendConstant4W[2][3] = 0xFFFFu - factor.blendConstant4W[2][0];

	factor.invBlendConstant4W[3][0] =
	factor.invBlendConstant4W[3][1] =
	factor.invBlendConstant4W[3][2] =
	factor.invBlendConstant4W[3][3] = 0xFFFFu - factor.blendConstant4W[3][0];

	factor.blendConstant4F[0][0] =
	factor.blendConstant4F[0][1] =
	factor.blendConstant4F[0][2] =
	factor.blendConstant4F[0][3] = blendConstant.r;

	factor.blendConstant4F[1][0] =
	factor.blendConstant4F[1][1] =
	factor.blendConstant4F[1][2] =
	factor.blendConstant4F[1][3] = blendConstant.g;

	factor.blendConstant4F[2][0] =
	factor.blendConstant4F[2][1] =
	factor.blendConstant4F[2][2] =
	factor.blendConstant4F[2][3] = blendConstant.b;

	factor.blendConstant4F[3][0] =
	factor.blendConstant4F[3][1] =
	factor.blendConstant4F[3][2] =
	factor.blendConstant4F[3][3] = blendConstant.a;

	factor.invBlendConstant4F[0][0] =
	factor.invBlendConstant4F[0][1] =
	factor.invBlendConstant4F[0][2] =
	factor.invBlendConstant4F[0][3] = 1 - blendConstant.r;

	factor.invBlendConstant4F[1][0] =
	factor.invBlendConstant4F[1][1] =
	factor.invBlendConstant4F[1][2] =
	factor.invBlendConstant4F[1][3] = 1 - blendConstant.g;

	factor.invBlendConstant4F[2][0] =
	factor.invBlendConstant4F[2][1] =
	factor.invBlendConstant4F[2][2] =
	factor.invBlendConstant4F[2][3] = 1 - blendConstant.b;

	factor.invBlendConstant4F[3][0] =
	factor.invBlendConstant4F[3][1] =
	factor.invBlendConstant4F[3][2] =
	factor.invBlendConstant4F[3][3] = 1 - blendConstant.a;
}

void PixelProcessor::setRoutineCacheSize(int cacheSize)
{
	delete routineCache;
	routineCache = new RoutineCacheType(clamp(cacheSize, 1, 65536));
}

const PixelProcessor::State PixelProcessor::update(const Context* context) const
{
	State state;

	state.numClipDistances = context->vertexShader->getNumOutputClipDistances();
	state.numCullDistances = context->vertexShader->getNumOutputCullDistances();

	if(context->pixelShader)
	{
		state.shaderID = context->pixelShader->getSerialID();
	}
	else
	{
		state.shaderID = 0;
	}

	state.alphaToCoverage = context->alphaToCoverage;
	state.depthWriteEnable = context->depthWriteActive();

	if(context->stencilActive())
	{
		state.stencilActive = true;
		state.frontStencil = context->frontStencil;
		state.backStencil = context->backStencil;
	}

	if(context->depthBufferActive())
	{
		state.depthTestActive = true;
		state.depthCompareMode = context->depthCompareMode;
		state.depthFormat = context->depthBuffer->getFormat();
	}

	state.occlusionEnabled = context->occlusionEnabled;
	state.depthClamp = (context->depthBias != 0.0f) || (context->slopeDepthBias != 0.0f);

	for(int i = 0; i < RENDERTARGETS; i++)
	{
		state.colorWriteMask |= context->colorWriteActive(i) << (4 * i);
		state.targetFormat[i] = context->renderTargetInternalFormat(i);
		state.blendState[i] = context->getBlendState(i);
	}

	state.multiSample = static_cast<unsigned int>(context->sampleCount);
	state.multiSampleMask = context->multiSampleMask;
	state.multiSampledBresenham = (state.multiSample > 1) && context->isDrawLine(true) &&
	                              (context->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT);

	if(state.multiSample > 1 && context->pixelShader)
	{
		state.centroid = context->pixelShader->getModes().NeedsCentroid;
	}

	state.frontFace = context->frontFace;

	state.hash = state.computeHash();

	return state;
}

PixelProcessor::RoutineType PixelProcessor::routine(const State &state,
	vk::PipelineLayout const *pipelineLayout,
	SpirvShader const *pixelShader,
	const vk::DescriptorSet::Bindings &descriptorSets)
{
	auto routine = routineCache->query(state);

	if(!routine)
	{
		QuadRasterizer *generator = new PixelProgram(state, pipelineLayout, pixelShader, descriptorSets);
		generator->generate();
		routine = (*generator)("PixelRoutine_%0.8X", state.shaderID);
		delete generator;

		routineCache->add(state, routine);
	}

	return routine;
}

}  // namespace sw
