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

// ProgramD3D.h: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.

#ifndef LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
#define LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_

#include <string>
#include <vector>

#include "compiler/translator/blocklayoutHLSL.h"
#include "libANGLE/Constants.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/ProgramImpl.h"
#include "libANGLE/renderer/d3d/DynamicHLSL.h"
#include "libANGLE/renderer/d3d/RendererD3D.h"
#include "platform/FeaturesD3D.h"

namespace rx
{
class RendererD3D;
class UniformStorageD3D;
class ShaderExecutableD3D;

#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
// WARNING: D3DCOMPILE_OPTIMIZATION_LEVEL3 may lead to a DX9 shader compiler hang.
// It should only be used selectively to work around specific bugs.
#    define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL1
#endif

enum class HLSLRegisterType : uint8_t
{
    None                = 0,
    Texture             = 1,
    UnorderedAccessView = 2
};

// Helper struct representing a single shader uniform
// TODO(jmadill): Make uniform blocks shared between all programs, so we don't need separate
// register indices.
struct D3DUniform : private angle::NonCopyable
{
    D3DUniform(GLenum type,
               HLSLRegisterType reg,
               const std::string &nameIn,
               const std::vector<unsigned int> &arraySizesIn,
               bool defaultBlock);
    ~D3DUniform();

    bool isSampler() const;
    bool isImage() const;
    bool isImage2D() const;
    bool isArray() const { return !arraySizes.empty(); }
    unsigned int getArraySizeProduct() const;
    bool isReferencedByShader(gl::ShaderType shaderType) const;

    const uint8_t *firstNonNullData() const;
    const uint8_t *getDataPtrToElement(size_t elementIndex) const;

    // Duplicated from the GL layer
    const gl::UniformTypeInfo &typeInfo;
    std::string name;  // Names of arrays don't include [0], unlike at the GL layer.
    std::vector<unsigned int> arraySizes;

    // Pointer to a system copies of the data. Separate pointers for each uniform storage type.
    gl::ShaderMap<uint8_t *> mShaderData;

    // Register information.
    HLSLRegisterType regType;
    gl::ShaderMap<unsigned int> mShaderRegisterIndexes;
    unsigned int registerCount;

    // Register "elements" are used for uniform structs in ES3, to appropriately identify single
    // uniforms
    // inside aggregate types, which are packed according C-like structure rules.
    unsigned int registerElement;

    // Special buffer for sampler values.
    std::vector<GLint> mSamplerData;
};

struct D3DInterfaceBlock
{
    D3DInterfaceBlock();
    D3DInterfaceBlock(const D3DInterfaceBlock &other);

    bool activeInShader(gl::ShaderType shaderType) const
    {
        return mShaderRegisterIndexes[shaderType] != GL_INVALID_INDEX;
    }

    gl::ShaderMap<unsigned int> mShaderRegisterIndexes;
};

struct D3DVarying final
{
    D3DVarying();
    D3DVarying(const std::string &semanticNameIn,
               unsigned int semanticIndexIn,
               unsigned int componentCountIn,
               unsigned int outputSlotIn);

    D3DVarying(const D3DVarying &) = default;
    D3DVarying &operator=(const D3DVarying &) = default;

    std::string semanticName;
    unsigned int semanticIndex;
    unsigned int componentCount;
    unsigned int outputSlot;
};

class ProgramD3DMetadata final : angle::NonCopyable
{
  public:
    ProgramD3DMetadata(RendererD3D *renderer,
                       const gl::ShaderMap<const ShaderD3D *> &attachedShaders,
                       EGLenum clientType);
    ~ProgramD3DMetadata();

    int getRendererMajorShaderModel() const;
    bool usesBroadcast(const gl::State &data) const;
    bool usesSecondaryColor() const;
    bool usesFragDepth() const;
    bool usesPointCoord() const;
    bool usesFragCoord() const;
    bool usesPointSize() const;
    bool usesInsertedPointCoordValue() const;
    bool usesViewScale() const;
    bool hasANGLEMultiviewEnabled() const;
    bool usesVertexID() const;
    bool usesViewID() const;
    bool canSelectViewInVertexShader() const;
    bool addsPointCoordToVertexShader() const;
    bool usesTransformFeedbackGLPosition() const;
    bool usesSystemValuePointSize() const;
    bool usesMultipleFragmentOuts() const;
    bool usesCustomOutVars() const;
    const ShaderD3D *getFragmentShader() const;

  private:
    const int mRendererMajorShaderModel;
    const std::string mShaderModelSuffix;
    const bool mUsesInstancedPointSpriteEmulation;
    const bool mUsesViewScale;
    const bool mCanSelectViewInVertexShader;
    const gl::ShaderMap<const ShaderD3D *> mAttachedShaders;
    const EGLenum mClientType;
};

using D3DUniformMap = std::map<std::string, D3DUniform *>;

class ProgramD3D : public ProgramImpl
{
  public:
    ProgramD3D(const gl::ProgramState &data, RendererD3D *renderer);
    ~ProgramD3D() override;

    const std::vector<PixelShaderOutputVariable> &getPixelShaderKey() { return mPixelShaderKey; }

    GLint getSamplerMapping(gl::ShaderType type,
                            unsigned int samplerIndex,
                            const gl::Caps &caps) const;
    gl::TextureType getSamplerTextureType(gl::ShaderType type, unsigned int samplerIndex) const;
    gl::RangeUI getUsedSamplerRange(gl::ShaderType type) const;

    enum SamplerMapping
    {
        WasDirty,
        WasClean,
    };

    SamplerMapping updateSamplerMapping();

    GLint getImageMapping(gl::ShaderType type,
                          unsigned int imageIndex,
                          bool readonly,
                          const gl::Caps &caps) const;
    gl::RangeUI getUsedImageRange(gl::ShaderType type, bool readonly) const;

    bool usesPointSize() const { return mUsesPointSize; }
    bool usesPointSpriteEmulation() const;
    bool usesGeometryShader(const gl::State &state, gl::PrimitiveMode drawMode) const;
    bool usesGeometryShaderForPointSpriteEmulation() const;
    bool usesGetDimensionsIgnoresBaseLevel() const;
    bool usesInstancedPointSpriteEmulation() const;

    std::unique_ptr<LinkEvent> load(const gl::Context *context,
                                    gl::BinaryInputStream *stream,
                                    gl::InfoLog &infoLog) override;
    void save(const gl::Context *context, gl::BinaryOutputStream *stream) override;
    void setBinaryRetrievableHint(bool retrievable) override;
    void setSeparable(bool separable) override;

    angle::Result getVertexExecutableForCachedInputLayout(d3d::Context *context,
                                                          ShaderExecutableD3D **outExectuable,
                                                          gl::InfoLog *infoLog);
    angle::Result getGeometryExecutableForPrimitiveType(d3d::Context *errContext,
                                                        const gl::State &state,
                                                        gl::PrimitiveMode drawMode,
                                                        ShaderExecutableD3D **outExecutable,
                                                        gl::InfoLog *infoLog);
    angle::Result getPixelExecutableForCachedOutputLayout(d3d::Context *context,
                                                          ShaderExecutableD3D **outExectuable,
                                                          gl::InfoLog *infoLog);
#if defined(STARBOARD)
    angle::Result getPixelExecutableForCachedHdrOutputLayout(d3d::Context *context,
                                                             ShaderExecutableD3D **outExectuable,
                                                             gl::InfoLog *infoLog);
#endif  // STARBOARD
    angle::Result getComputeExecutableForImage2DBindLayout(d3d::Context *context,
                                                           ShaderExecutableD3D **outExecutable,
                                                           gl::InfoLog *infoLog);
    std::unique_ptr<LinkEvent> link(const gl::Context *context,
                                    const gl::ProgramLinkedResources &resources,
                                    gl::InfoLog &infoLog) override;
    GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;

    void setPathFragmentInputGen(const std::string &inputName,
                                 GLenum genMode,
                                 GLint components,
                                 const GLfloat *coeffs) override;

    void updateUniformBufferCache(const gl::Caps &caps,
                                  const gl::ShaderMap<unsigned int> &reservedShaderRegisterIndexes);

    unsigned int getAtomicCounterBufferRegisterIndex(GLuint binding,
                                                     gl::ShaderType shaderType) const;

    unsigned int getShaderStorageBufferRegisterIndex(GLuint blockIndex,
                                                     gl::ShaderType shaderType) const;
    const std::vector<GLint> &getShaderUniformBufferCache(gl::ShaderType shaderType) const;

    void dirtyAllUniforms();

    void setUniform1fv(GLint location, GLsizei count, const GLfloat *v) override;
    void setUniform2fv(GLint location, GLsizei count, const GLfloat *v) override;
    void setUniform3fv(GLint location, GLsizei count, const GLfloat *v) override;
    void setUniform4fv(GLint location, GLsizei count, const GLfloat *v) override;
    void setUniform1iv(GLint location, GLsizei count, const GLint *v) override;
    void setUniform2iv(GLint location, GLsizei count, const GLint *v) override;
    void setUniform3iv(GLint location, GLsizei count, const GLint *v) override;
    void setUniform4iv(GLint location, GLsizei count, const GLint *v) override;
    void setUniform1uiv(GLint location, GLsizei count, const GLuint *v) override;
    void setUniform2uiv(GLint location, GLsizei count, const GLuint *v) override;
    void setUniform3uiv(GLint location, GLsizei count, const GLuint *v) override;
    void setUniform4uiv(GLint location, GLsizei count, const GLuint *v) override;
    void setUniformMatrix2fv(GLint location,
                             GLsizei count,
                             GLboolean transpose,
                             const GLfloat *value) override;
    void setUniformMatrix3fv(GLint location,
                             GLsizei count,
                             GLboolean transpose,
                             const GLfloat *value) override;
    void setUniformMatrix4fv(GLint location,
                             GLsizei count,
                             GLboolean transpose,
                             const GLfloat *value) override;
    void setUniformMatrix2x3fv(GLint location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value) override;
    void setUniformMatrix3x2fv(GLint location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value) override;
    void setUniformMatrix2x4fv(GLint location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value) override;
    void setUniformMatrix4x2fv(GLint location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value) override;
    void setUniformMatrix3x4fv(GLint location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value) override;
    void setUniformMatrix4x3fv(GLint location,
                               GLsizei count,
                               GLboolean transpose,
                               const GLfloat *value) override;

    void getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const override;
    void getUniformiv(const gl::Context *context, GLint location, GLint *params) const override;
    void getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const override;

    UniformStorageD3D *getShaderUniformStorage(gl::ShaderType shaderType) const
    {
        return mShaderUniformStorages[shaderType].get();
    }

    unsigned int getSerial() const;

    const AttribIndexArray &getAttribLocationToD3DSemantics() const
    {
        return mAttribLocationToD3DSemantic;
    }

    void updateCachedInputLayout(Serial associatedSerial, const gl::State &state);
    void updateCachedOutputLayout(const gl::Context *context, const gl::Framebuffer *framebuffer);
    void updateCachedComputeImage2DBindLayout(const gl::Context *context);

    bool isSamplerMappingDirty() { return mDirtySamplerMapping; }

    // Checks if we need to recompile certain shaders.
    bool hasVertexExecutableForCachedInputLayout();
    bool hasGeometryExecutableForPrimitiveType(const gl::State &state, gl::PrimitiveMode drawMode);
    bool hasPixelExecutableForCachedOutputLayout();
    bool hasComputeExecutableForCachedImage2DBindLayout();

    bool anyShaderUniformsDirty() const { return mShaderUniformsDirty.any(); }

    bool areShaderUniformsDirty(gl::ShaderType shaderType) const
    {
        return mShaderUniformsDirty[shaderType];
    }
    const std::vector<D3DUniform *> &getD3DUniforms() const { return mD3DUniforms; }
    void markUniformsClean();

    const gl::ProgramState &getState() const { return mState; }

    bool hasShaderStage(gl::ShaderType shaderType) const
    {
        return mState.getLinkedShaderStages()[shaderType];
    }

    void assignImage2DRegisters(unsigned int startImageIndex,
                                int startLogicalImageUnit,
                                bool readonly);
    bool hasNamedUniform(const std::string &name);

    bool usesVertexID() const { return mUsesVertexID; }

  private:
    // These forward-declared tasks are used for multi-thread shader compiles.
    class GetExecutableTask;
    class GetVertexExecutableTask;
    class GetPixelExecutableTask;
    class GetGeometryExecutableTask;
    class GetComputeExecutableTask;
    class GraphicsProgramLinkEvent;
    class ComputeProgramLinkEvent;

    class LoadBinaryTask;
    class LoadBinaryLinkEvent;

    class VertexExecutable
    {
      public:
        enum HLSLAttribType
        {
            FLOAT,
            UNSIGNED_INT,
            SIGNED_INT,
        };

        typedef std::vector<HLSLAttribType> Signature;

        VertexExecutable(const gl::InputLayout &inputLayout,
                         const Signature &signature,
                         ShaderExecutableD3D *shaderExecutable);
        ~VertexExecutable();

        bool matchesSignature(const Signature &signature) const;
        static void getSignature(RendererD3D *renderer,
                                 const gl::InputLayout &inputLayout,
                                 Signature *signatureOut);

        const gl::InputLayout &inputs() const { return mInputs; }
        const Signature &signature() const { return mSignature; }
        ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }

      private:
        static HLSLAttribType GetAttribType(GLenum type);

        gl::InputLayout mInputs;
        Signature mSignature;
        ShaderExecutableD3D *mShaderExecutable;
    };

    class PixelExecutable
    {
      public:
        PixelExecutable(const std::vector<GLenum> &outputSignature,
                        ShaderExecutableD3D *shaderExecutable);
        ~PixelExecutable();

        bool matchesSignature(const std::vector<GLenum> &signature) const
        {
            return mOutputSignature == signature;
        }

        const std::vector<GLenum> &outputSignature() const { return mOutputSignature; }
        ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable; }

      private:
        std::vector<GLenum> mOutputSignature;
        ShaderExecutableD3D *mShaderExecutable;
    };

    class ComputeExecutable
    {
      public:
        ComputeExecutable(const gl::ImageUnitTextureTypeMap &signature,
                          std::unique_ptr<ShaderExecutableD3D> shaderExecutable);
        ~ComputeExecutable();

        bool matchesSignature(const gl::ImageUnitTextureTypeMap &signature) const
        {
            return mSignature == signature;
        }

        const gl::ImageUnitTextureTypeMap &signature() const { return mSignature; }
        ShaderExecutableD3D *shaderExecutable() const { return mShaderExecutable.get(); }

      private:
        gl::ImageUnitTextureTypeMap mSignature;
        std::unique_ptr<ShaderExecutableD3D> mShaderExecutable;
    };

    struct Sampler
    {
        Sampler();

        bool active;
        GLint logicalTextureUnit;
        gl::TextureType textureType;
    };

    struct Image
    {
        Image();
        bool active;
        GLint logicalImageUnit;
    };

    void initializeUniformStorage(const gl::ShaderBitSet &availableShaderStages);

    void defineUniformsAndAssignRegisters();
    void defineUniformBase(const gl::Shader *shader,
                           const sh::ShaderVariable &uniform,
                           D3DUniformMap *uniformMap);
    void assignAllSamplerRegisters();
    void assignSamplerRegisters(size_t uniformIndex);

    static void AssignSamplers(unsigned int startSamplerIndex,
                               const gl::UniformTypeInfo &typeInfo,
                               unsigned int samplerCount,
                               std::vector<Sampler> &outSamplers,
                               gl::RangeUI *outUsedRange);

    void assignAllImageRegisters();
    void assignAllAtomicCounterRegisters();
    void assignImageRegisters(size_t uniformIndex);
    static void AssignImages(unsigned int startImageIndex,
                             int startLogicalImageUnit,
                             unsigned int imageCount,
                             std::vector<Image> &outImages,
                             gl::RangeUI *outUsedRange);

    template <typename DestT>
    void getUniformInternal(GLint location, DestT *dataOut) const;

    template <typename T>
    void setUniformImpl(const gl::VariableLocation &locationInfo,
                        GLsizei count,
                        const T *v,
                        uint8_t *targetData,
                        GLenum uniformType);

    template <typename T>
    void setUniformInternal(GLint location, GLsizei count, const T *v, GLenum uniformType);

    template <int cols, int rows>
    void setUniformMatrixfvInternal(GLint location,
                                    GLsizei count,
                                    GLboolean transpose,
                                    const GLfloat *value);

    std::unique_ptr<LinkEvent> compileProgramExecutables(const gl::Context *context,
                                                         gl::InfoLog &infoLog);
    std::unique_ptr<LinkEvent> compileComputeExecutable(const gl::Context *context,
                                                        gl::InfoLog &infoLog);

    angle::Result loadBinaryShaderExecutables(d3d::Context *contextD3D,
                                              gl::BinaryInputStream *stream,
                                              gl::InfoLog &infoLog);

    void gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyings,
                                         const BuiltinInfo &builtins);
    D3DUniform *getD3DUniformFromLocation(GLint location);
    const D3DUniform *getD3DUniformFromLocation(GLint location) const;

    void initAttribLocationsToD3DSemantic();

    void reset();
    void initializeUniformBlocks();
    void initializeShaderStorageBlocks();

    void updateCachedInputLayoutFromShader();
    void updateCachedOutputLayoutFromShader();
    void updateCachedImage2DBindLayoutFromComputeShader();
    void updateCachedVertexExecutableIndex();
    void updateCachedPixelExecutableIndex();
    void updateCachedComputeExecutableIndex();

    void linkResources(const gl::ProgramLinkedResources &resources);

    RendererD3D *mRenderer;
    DynamicHLSL *mDynamicHLSL;

    std::vector<std::unique_ptr<VertexExecutable>> mVertexExecutables;
    std::vector<std::unique_ptr<PixelExecutable>> mPixelExecutables;
    angle::PackedEnumMap<gl::PrimitiveMode, std::unique_ptr<ShaderExecutableD3D>>
        mGeometryExecutables;
    std::vector<std::unique_ptr<ComputeExecutable>> mComputeExecutables;
#if defined(STARBOARD)
    std::unique_ptr<PixelExecutable> mPixelHdrExecutable;
#endif  // STARBOARD

    gl::ShaderMap<std::string> mShaderHLSL;
    gl::ShaderMap<angle::CompilerWorkaroundsD3D> mShaderWorkarounds;

    bool mUsesFragDepth;
    bool mHasANGLEMultiviewEnabled;
    bool mUsesVertexID;
    bool mUsesViewID;
    std::vector<PixelShaderOutputVariable> mPixelShaderKey;

    // Common code for all dynamic geometry shaders. Consists mainly of the GS input and output
    // structures, built from the linked varying info. We store the string itself instead of the
    // packed varyings for simplicity.
    std::string mGeometryShaderPreamble;

    bool mUsesPointSize;
    bool mUsesFlatInterpolation;

    gl::ShaderMap<std::unique_ptr<UniformStorageD3D>> mShaderUniformStorages;

    gl::ShaderMap<std::vector<Sampler>> mShaderSamplers;
    gl::ShaderMap<gl::RangeUI> mUsedShaderSamplerRanges;
    bool mDirtySamplerMapping;

    std::vector<Image> mImagesCS;
    std::vector<Image> mReadonlyImagesCS;
    gl::RangeUI mUsedComputeImageRange;
    gl::RangeUI mUsedComputeReadonlyImageRange;
    gl::RangeUI mUsedComputeAtomicCounterRange;

    // Cache for pixel shader output layout to save reallocations.
    std::vector<GLenum> mPixelShaderOutputLayoutCache;
    Optional<size_t> mCachedPixelExecutableIndex;

    AttribIndexArray mAttribLocationToD3DSemantic;

    unsigned int mSerial;

    gl::ShaderMap<std::vector<int>> mShaderUBOCaches;
    VertexExecutable::Signature mCachedVertexSignature;
    gl::InputLayout mCachedInputLayout;
    Optional<size_t> mCachedVertexExecutableIndex;

    std::vector<D3DVarying> mStreamOutVaryings;
    std::vector<D3DUniform *> mD3DUniforms;
    std::map<std::string, int> mImageBindingMap;
    std::map<std::string, int> mAtomicBindingMap;
    std::vector<D3DInterfaceBlock> mD3DUniformBlocks;
    std::vector<D3DInterfaceBlock> mD3DShaderStorageBlocks;
    std::array<unsigned int, gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFERS>
        mComputeAtomicCounterBufferRegisterIndices;

    std::vector<sh::ShaderVariable> mImage2DUniforms;
    gl::ImageUnitTextureTypeMap mComputeShaderImage2DBindLayoutCache;
    Optional<size_t> mCachedComputeExecutableIndex;

    gl::ShaderBitSet mShaderUniformsDirty;

    static unsigned int issueSerial();
    static unsigned int mCurrentSerial;

    Serial mCurrentVertexArrayStateSerial;
};
}  // namespace rx

#endif  // LIBANGLE_RENDERER_D3D_PROGRAMD3D_H_
