//
// Copyright 2022 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// CompiledShaderState.cpp:
//   Implements CompiledShaderState, and helper functions for serializing and deserializing
//   shader variables.
//

#include "common/CompiledShaderState.h"

#include "common/BinaryStream.h"
#include "common/utilities.h"

namespace gl
{
namespace
{
template <typename VarT>
std::vector<VarT> GetActiveShaderVariables(const std::vector<VarT> *variableList)
{
    ASSERT(variableList);
    std::vector<VarT> result;
    for (size_t varIndex = 0; varIndex < variableList->size(); varIndex++)
    {
        const VarT &var = variableList->at(varIndex);
        if (var.active)
        {
            result.push_back(var);
        }
    }
    return result;
}

template <typename VarT>
const std::vector<VarT> &GetShaderVariables(const std::vector<VarT> *variableList)
{
    ASSERT(variableList);
    return *variableList;
}
}  // namespace

// true if varying x has a higher priority in packing than y
bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y)
{
    if (x.type == y.type)
    {
        return x.getArraySizeProduct() > y.getArraySizeProduct();
    }

    // Special case for handling structs: we sort these to the end of the list
    if (x.type == GL_NONE)
    {
        return false;
    }

    if (y.type == GL_NONE)
    {
        return true;
    }

    return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type);
}

void WriteShaderVar(gl::BinaryOutputStream *stream, const sh::ShaderVariable &var)
{
    stream->writeInt(var.type);
    stream->writeInt(var.precision);
    stream->writeString(var.name);
    stream->writeString(var.mappedName);
    stream->writeVector(var.arraySizes);
    stream->writeBool(var.staticUse);
    stream->writeBool(var.active);
    stream->writeInt<size_t>(var.fields.size());
    for (const sh::ShaderVariable &shaderVariable : var.fields)
    {
        WriteShaderVar(stream, shaderVariable);
    }
    stream->writeString(var.structOrBlockName);
    stream->writeString(var.mappedStructOrBlockName);
    stream->writeBool(var.isRowMajorLayout);
    stream->writeInt(var.location);
    stream->writeBool(var.hasImplicitLocation);
    stream->writeInt(var.binding);
    stream->writeInt(var.imageUnitFormat);
    stream->writeInt(var.offset);
    stream->writeBool(var.rasterOrdered);
    stream->writeBool(var.readonly);
    stream->writeBool(var.writeonly);
    stream->writeBool(var.isFragmentInOut);
    stream->writeInt(var.index);
    stream->writeBool(var.yuv);
    stream->writeEnum(var.interpolation);
    stream->writeBool(var.isInvariant);
    stream->writeBool(var.isShaderIOBlock);
    stream->writeBool(var.isPatch);
    stream->writeBool(var.texelFetchStaticUse);
    stream->writeInt(var.getFlattenedOffsetInParentArrays());
    stream->writeInt(var.id);
}

void LoadShaderVar(gl::BinaryInputStream *stream, sh::ShaderVariable *var)
{
    var->type      = stream->readInt<GLenum>();
    var->precision = stream->readInt<GLenum>();
    stream->readString(&var->name);
    stream->readString(&var->mappedName);
    stream->readVector(&var->arraySizes);
    var->staticUse      = stream->readBool();
    var->active         = stream->readBool();
    size_t elementCount = stream->readInt<size_t>();
    var->fields.resize(elementCount);
    for (sh::ShaderVariable &variable : var->fields)
    {
        LoadShaderVar(stream, &variable);
    }
    stream->readString(&var->structOrBlockName);
    stream->readString(&var->mappedStructOrBlockName);
    var->isRowMajorLayout    = stream->readBool();
    var->location            = stream->readInt<int>();
    var->hasImplicitLocation = stream->readBool();
    var->binding             = stream->readInt<int>();
    var->imageUnitFormat     = stream->readInt<GLenum>();
    var->offset              = stream->readInt<int>();
    var->rasterOrdered       = stream->readBool();
    var->readonly            = stream->readBool();
    var->writeonly           = stream->readBool();
    var->isFragmentInOut     = stream->readBool();
    var->index               = stream->readInt<int>();
    var->yuv                 = stream->readBool();
    var->interpolation       = stream->readEnum<sh::InterpolationType>();
    var->isInvariant         = stream->readBool();
    var->isShaderIOBlock     = stream->readBool();
    var->isPatch             = stream->readBool();
    var->texelFetchStaticUse = stream->readBool();
    var->setParentArrayIndex(stream->readInt<int>());
    var->id = stream->readInt<uint32_t>();
}

void WriteShInterfaceBlock(gl::BinaryOutputStream *stream, const sh::InterfaceBlock &block)
{
    stream->writeString(block.name);
    stream->writeString(block.mappedName);
    stream->writeString(block.instanceName);
    stream->writeInt(block.arraySize);
    stream->writeEnum(block.layout);
    stream->writeBool(block.isRowMajorLayout);
    stream->writeInt(block.binding);
    stream->writeBool(block.staticUse);
    stream->writeBool(block.active);
    stream->writeEnum(block.blockType);
    stream->writeInt(block.id);

    stream->writeInt<size_t>(block.fields.size());
    for (const sh::ShaderVariable &shaderVariable : block.fields)
    {
        WriteShaderVar(stream, shaderVariable);
    }
}

void LoadShInterfaceBlock(gl::BinaryInputStream *stream, sh::InterfaceBlock *block)
{
    block->name             = stream->readString();
    block->mappedName       = stream->readString();
    block->instanceName     = stream->readString();
    block->arraySize        = stream->readInt<unsigned int>();
    block->layout           = stream->readEnum<sh::BlockLayoutType>();
    block->isRowMajorLayout = stream->readBool();
    block->binding          = stream->readInt<int>();
    block->staticUse        = stream->readBool();
    block->active           = stream->readBool();
    block->blockType        = stream->readEnum<sh::BlockType>();
    block->id               = stream->readInt<uint32_t>();

    block->fields.resize(stream->readInt<size_t>());
    for (sh::ShaderVariable &variable : block->fields)
    {
        LoadShaderVar(stream, &variable);
    }
}

CompiledShaderState::CompiledShaderState(gl::ShaderType type)
    : shaderType(type),
      shaderVersion(100),
      hasClipDistance(false),
      hasDiscard(false),
      enablesPerSampleShading(false),
      numViews(-1),
      geometryShaderInvocations(1),
      tessControlShaderVertices(0),
      tessGenMode(0),
      tessGenSpacing(0),
      tessGenVertexOrder(0),
      tessGenPointMode(0)
{
    localSize.fill(-1);
}

CompiledShaderState::~CompiledShaderState() {}

void CompiledShaderState::buildCompiledShaderState(const ShHandle compilerHandle,
                                                   const bool isBinaryOutput)
{
    if (isBinaryOutput)
    {
        compiledBinary = sh::GetObjectBinaryBlob(compilerHandle);
    }
    else
    {
        translatedSource = sh::GetObjectCode(compilerHandle);
    }

    // Gather the shader information
    shaderVersion = sh::GetShaderVersion(compilerHandle);

    uniforms            = GetShaderVariables(sh::GetUniforms(compilerHandle));
    uniformBlocks       = GetShaderVariables(sh::GetUniformBlocks(compilerHandle));
    shaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle));
    specConstUsageBits  = SpecConstUsageBits(sh::GetShaderSpecConstUsageBits(compilerHandle));

    switch (shaderType)
    {
        case gl::ShaderType::Compute:
        {
            allAttributes    = GetShaderVariables(sh::GetAttributes(compilerHandle));
            activeAttributes = GetActiveShaderVariables(&allAttributes);
            localSize        = sh::GetComputeShaderLocalGroupSize(compilerHandle);
            break;
        }
        case gl::ShaderType::Vertex:
        {
            outputVaryings   = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
            allAttributes    = GetShaderVariables(sh::GetAttributes(compilerHandle));
            activeAttributes = GetActiveShaderVariables(&allAttributes);
            hasClipDistance  = sh::HasClipDistanceInVertexShader(compilerHandle);
            numViews         = sh::GetVertexShaderNumViews(compilerHandle);
            break;
        }
        case gl::ShaderType::Fragment:
        {
            allAttributes    = GetShaderVariables(sh::GetAttributes(compilerHandle));
            activeAttributes = GetActiveShaderVariables(&allAttributes);
            inputVaryings    = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
            // TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
            std::sort(inputVaryings.begin(), inputVaryings.end(), CompareShaderVar);
            activeOutputVariables =
                GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle));
            hasDiscard              = sh::HasDiscardInFragmentShader(compilerHandle);
            enablesPerSampleShading = sh::EnablesPerSampleShading(compilerHandle);
            advancedBlendEquations =
                gl::BlendEquationBitSet(sh::GetAdvancedBlendEquations(compilerHandle));
            break;
        }
        case gl::ShaderType::Geometry:
        {
            inputVaryings  = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
            outputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));

            if (sh::HasValidGeometryShaderInputPrimitiveType(compilerHandle))
            {
                geometryShaderInputPrimitiveType = gl::FromGLenum<gl::PrimitiveMode>(
                    sh::GetGeometryShaderInputPrimitiveType(compilerHandle));
            }
            if (sh::HasValidGeometryShaderOutputPrimitiveType(compilerHandle))
            {
                geometryShaderOutputPrimitiveType = gl::FromGLenum<gl::PrimitiveMode>(
                    sh::GetGeometryShaderOutputPrimitiveType(compilerHandle));
            }
            if (sh::HasValidGeometryShaderMaxVertices(compilerHandle))
            {
                geometryShaderMaxVertices = sh::GetGeometryShaderMaxVertices(compilerHandle);
            }
            geometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle);
            break;
        }
        case gl::ShaderType::TessControl:
        {
            inputVaryings             = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
            outputVaryings            = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
            tessControlShaderVertices = sh::GetTessControlShaderVertices(compilerHandle);
            break;
        }
        case gl::ShaderType::TessEvaluation:
        {
            inputVaryings  = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
            outputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
            if (sh::HasValidTessGenMode(compilerHandle))
            {
                tessGenMode = sh::GetTessGenMode(compilerHandle);
            }
            if (sh::HasValidTessGenSpacing(compilerHandle))
            {
                tessGenSpacing = sh::GetTessGenSpacing(compilerHandle);
            }
            if (sh::HasValidTessGenVertexOrder(compilerHandle))
            {
                tessGenVertexOrder = sh::GetTessGenVertexOrder(compilerHandle);
            }
            if (sh::HasValidTessGenPointMode(compilerHandle))
            {
                tessGenPointMode = sh::GetTessGenPointMode(compilerHandle);
            }
            break;
        }

        default:
            UNREACHABLE();
    }
}

void CompiledShaderState::serialize(gl::BinaryOutputStream &stream) const
{
    stream.writeInt(shaderVersion);

    stream.writeInt(uniforms.size());
    for (const sh::ShaderVariable &shaderVariable : uniforms)
    {
        WriteShaderVar(&stream, shaderVariable);
    }

    stream.writeInt(uniformBlocks.size());
    for (const sh::InterfaceBlock &interfaceBlock : uniformBlocks)
    {
        WriteShInterfaceBlock(&stream, interfaceBlock);
    }

    stream.writeInt(shaderStorageBlocks.size());
    for (const sh::InterfaceBlock &interfaceBlock : shaderStorageBlocks)
    {
        WriteShInterfaceBlock(&stream, interfaceBlock);
    }

    stream.writeInt(specConstUsageBits.bits());

    switch (shaderType)
    {
        case gl::ShaderType::Compute:
        {
            stream.writeInt(allAttributes.size());
            for (const sh::ShaderVariable &shaderVariable : allAttributes)
            {
                WriteShaderVar(&stream, shaderVariable);
            }
            stream.writeInt(activeAttributes.size());
            for (const sh::ShaderVariable &shaderVariable : activeAttributes)
            {
                WriteShaderVar(&stream, shaderVariable);
            }
            stream.writeInt(localSize[0]);
            stream.writeInt(localSize[1]);
            stream.writeInt(localSize[2]);
            break;
        }

        case gl::ShaderType::Vertex:
        {
            stream.writeInt(outputVaryings.size());
            for (const sh::ShaderVariable &shaderVariable : outputVaryings)
            {
                WriteShaderVar(&stream, shaderVariable);
            }
            stream.writeInt(allAttributes.size());
            for (const sh::ShaderVariable &shaderVariable : allAttributes)
            {
                WriteShaderVar(&stream, shaderVariable);
            }
            stream.writeInt(activeAttributes.size());
            for (const sh::ShaderVariable &shaderVariable : activeAttributes)
            {
                WriteShaderVar(&stream, shaderVariable);
            }
            stream.writeBool(hasClipDistance);
            stream.writeInt(numViews);
            break;
        }
        case gl::ShaderType::Fragment:
        {
            stream.writeInt(inputVaryings.size());
            for (const sh::ShaderVariable &shaderVariable : inputVaryings)
            {
                WriteShaderVar(&stream, shaderVariable);
            }
            stream.writeInt(activeOutputVariables.size());
            for (const sh::ShaderVariable &shaderVariable : activeOutputVariables)
            {
                WriteShaderVar(&stream, shaderVariable);
            }
            stream.writeBool(hasDiscard);
            stream.writeBool(enablesPerSampleShading);
            stream.writeInt(advancedBlendEquations.bits());
            break;
        }
        case gl::ShaderType::Geometry:
        {
            bool valid;

            stream.writeInt(inputVaryings.size());
            for (const sh::ShaderVariable &shaderVariable : inputVaryings)
            {
                WriteShaderVar(&stream, shaderVariable);
            }
            stream.writeInt(outputVaryings.size());
            for (const sh::ShaderVariable &shaderVariable : outputVaryings)
            {
                WriteShaderVar(&stream, shaderVariable);
            }

            valid = (bool)geometryShaderInputPrimitiveType.valid();
            stream.writeBool(valid);
            if (valid)
            {
                unsigned char value = (unsigned char)geometryShaderInputPrimitiveType.value();
                stream.writeBytes(&value, 1);
            }
            valid = (bool)geometryShaderOutputPrimitiveType.valid();
            stream.writeBool(valid);
            if (valid)
            {
                unsigned char value = (unsigned char)geometryShaderOutputPrimitiveType.value();
                stream.writeBytes(&value, 1);
            }
            valid = geometryShaderMaxVertices.valid();
            stream.writeBool(valid);
            if (valid)
            {
                int value = (int)geometryShaderMaxVertices.value();
                stream.writeInt(value);
            }

            stream.writeInt(geometryShaderInvocations);
            break;
        }
        case gl::ShaderType::TessControl:
        {
            stream.writeInt(inputVaryings.size());
            for (const sh::ShaderVariable &shaderVariable : inputVaryings)
            {
                WriteShaderVar(&stream, shaderVariable);
            }
            stream.writeInt(outputVaryings.size());
            for (const sh::ShaderVariable &shaderVariable : outputVaryings)
            {
                WriteShaderVar(&stream, shaderVariable);
            }
            stream.writeInt(tessControlShaderVertices);
            break;
        }
        case gl::ShaderType::TessEvaluation:
        {
            unsigned int value;

            stream.writeInt(inputVaryings.size());
            for (const sh::ShaderVariable &shaderVariable : inputVaryings)
            {
                WriteShaderVar(&stream, shaderVariable);
            }
            stream.writeInt(outputVaryings.size());
            for (const sh::ShaderVariable &shaderVariable : outputVaryings)
            {
                WriteShaderVar(&stream, shaderVariable);
            }

            value = (unsigned int)(tessGenMode);
            stream.writeInt(value);

            value = (unsigned int)tessGenSpacing;
            stream.writeInt(value);

            value = (unsigned int)tessGenVertexOrder;
            stream.writeInt(value);

            value = (unsigned int)tessGenPointMode;
            stream.writeInt(value);
            break;
        }
        default:
            UNREACHABLE();
    }

    stream.writeVector(compiledBinary);
}

void CompiledShaderState::deserialize(gl::BinaryInputStream &stream)
{
    stream.readInt(&shaderVersion);

    size_t size;
    size = stream.readInt<size_t>();
    uniforms.resize(size);
    for (sh::ShaderVariable &shaderVariable : uniforms)
    {
        LoadShaderVar(&stream, &shaderVariable);
    }

    size = stream.readInt<size_t>();
    uniformBlocks.resize(size);
    for (sh::InterfaceBlock &interfaceBlock : uniformBlocks)
    {
        LoadShInterfaceBlock(&stream, &interfaceBlock);
    }

    size = stream.readInt<size_t>();
    shaderStorageBlocks.resize(size);
    for (sh::InterfaceBlock &interfaceBlock : shaderStorageBlocks)
    {
        LoadShInterfaceBlock(&stream, &interfaceBlock);
    }

    specConstUsageBits = SpecConstUsageBits(stream.readInt<uint32_t>());

    switch (shaderType)
    {
        case gl::ShaderType::Compute:
        {
            size = stream.readInt<size_t>();
            allAttributes.resize(size);
            for (sh::ShaderVariable &shaderVariable : allAttributes)
            {
                LoadShaderVar(&stream, &shaderVariable);
            }
            size = stream.readInt<size_t>();
            activeAttributes.resize(size);
            for (sh::ShaderVariable &shaderVariable : activeAttributes)
            {
                LoadShaderVar(&stream, &shaderVariable);
            }
            stream.readInt(&localSize[0]);
            stream.readInt(&localSize[1]);
            stream.readInt(&localSize[2]);
            break;
        }
        case gl::ShaderType::Vertex:
        {
            size = stream.readInt<size_t>();
            outputVaryings.resize(size);
            for (sh::ShaderVariable &shaderVariable : outputVaryings)
            {
                LoadShaderVar(&stream, &shaderVariable);
            }
            size = stream.readInt<size_t>();
            allAttributes.resize(size);
            for (sh::ShaderVariable &shaderVariable : allAttributes)
            {
                LoadShaderVar(&stream, &shaderVariable);
            }
            size = stream.readInt<size_t>();
            activeAttributes.resize(size);
            for (sh::ShaderVariable &shaderVariable : activeAttributes)
            {
                LoadShaderVar(&stream, &shaderVariable);
            }
            stream.readBool(&hasClipDistance);
            stream.readInt(&numViews);
            break;
        }
        case gl::ShaderType::Fragment:
        {
            size = stream.readInt<size_t>();
            inputVaryings.resize(size);
            for (sh::ShaderVariable &shaderVariable : inputVaryings)
            {
                LoadShaderVar(&stream, &shaderVariable);
            }
            size = stream.readInt<size_t>();
            activeOutputVariables.resize(size);
            for (sh::ShaderVariable &shaderVariable : activeOutputVariables)
            {
                LoadShaderVar(&stream, &shaderVariable);
            }
            stream.readBool(&hasDiscard);
            stream.readBool(&enablesPerSampleShading);
            int advancedBlendEquationBits;
            stream.readInt(&advancedBlendEquationBits);
            advancedBlendEquations = gl::BlendEquationBitSet(advancedBlendEquationBits);
            break;
        }
        case gl::ShaderType::Geometry:
        {
            bool valid;

            size = stream.readInt<size_t>();
            inputVaryings.resize(size);
            for (sh::ShaderVariable &shaderVariable : inputVaryings)
            {
                LoadShaderVar(&stream, &shaderVariable);
            }
            size = stream.readInt<size_t>();
            outputVaryings.resize(size);
            for (sh::ShaderVariable &shaderVariable : outputVaryings)
            {
                LoadShaderVar(&stream, &shaderVariable);
            }

            stream.readBool(&valid);
            if (valid)
            {
                unsigned char value;
                stream.readBytes(&value, 1);
                geometryShaderInputPrimitiveType = static_cast<gl::PrimitiveMode>(value);
            }
            else
            {
                geometryShaderInputPrimitiveType.reset();
            }

            stream.readBool(&valid);
            if (valid)
            {
                unsigned char value;
                stream.readBytes(&value, 1);
                geometryShaderOutputPrimitiveType = static_cast<gl::PrimitiveMode>(value);
            }
            else
            {
                geometryShaderOutputPrimitiveType.reset();
            }

            stream.readBool(&valid);
            if (valid)
            {
                int value;
                stream.readInt(&value);
                geometryShaderMaxVertices = static_cast<GLint>(value);
            }
            else
            {
                geometryShaderMaxVertices.reset();
            }

            stream.readInt(&geometryShaderInvocations);
            break;
        }
        case gl::ShaderType::TessControl:
        {
            size = stream.readInt<size_t>();
            inputVaryings.resize(size);
            for (sh::ShaderVariable &shaderVariable : inputVaryings)
            {
                LoadShaderVar(&stream, &shaderVariable);
            }
            size = stream.readInt<size_t>();
            outputVaryings.resize(size);
            for (sh::ShaderVariable &shaderVariable : outputVaryings)
            {
                LoadShaderVar(&stream, &shaderVariable);
            }
            stream.readInt(&tessControlShaderVertices);
            break;
        }
        case gl::ShaderType::TessEvaluation:
        {
            unsigned int value;

            size = stream.readInt<size_t>();
            inputVaryings.resize(size);
            for (sh::ShaderVariable &shaderVariable : inputVaryings)
            {
                LoadShaderVar(&stream, &shaderVariable);
            }
            size = stream.readInt<size_t>();
            outputVaryings.resize(size);
            for (sh::ShaderVariable &shaderVariable : outputVaryings)
            {
                LoadShaderVar(&stream, &shaderVariable);
            }

            stream.readInt(&value);
            tessGenMode = (GLenum)value;

            stream.readInt(&value);
            tessGenSpacing = (GLenum)value;

            stream.readInt(&value);
            tessGenVertexOrder = (GLenum)value;

            stream.readInt(&value);
            tessGenPointMode = (GLenum)value;
            break;
        }
        default:
            UNREACHABLE();
    }

    stream.readVector(&compiledBinary);
}
}  // namespace gl
