//
// 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.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.

#include "libANGLE/renderer/d3d/ProgramD3D.h"

#include "common/MemoryBuffer.h"
#include "common/bitset_utils.h"
#include "common/span_util.h"
#include "common/string_utils.h"
#include "common/utilities.h"
#include "libANGLE/Context.h"
#include "libANGLE/Program.h"
#include "libANGLE/ProgramLinkedResources.h"
#include "libANGLE/Uniform.h"
#include "libANGLE/VertexArray.h"
#include "libANGLE/features.h"
#include "libANGLE/queryconversions.h"
#include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/renderer/d3d/ContextD3D.h"
#include "libANGLE/renderer/d3d/ShaderD3D.h"
#include "libANGLE/renderer/d3d/ShaderExecutableD3D.h"
#include "libANGLE/renderer/d3d/VertexDataManager.h"
#include "libANGLE/renderer/renderer_utils.h"
#include "libANGLE/trace.h"

using namespace angle;

namespace rx
{
namespace
{
bool HasFlatInterpolationVarying(const std::vector<sh::ShaderVariable> &varyings)
{
    // Note: this assumes nested structs can only be packed with one interpolation.
    for (const auto &varying : varyings)
    {
        if (varying.interpolation == sh::INTERPOLATION_FLAT)
        {
            return true;
        }
    }

    return false;
}

bool FindFlatInterpolationVaryingPerShader(const gl::SharedCompiledShaderState &shader)
{
    ASSERT(shader);
    switch (shader->shaderType)
    {
        case gl::ShaderType::Vertex:
            return HasFlatInterpolationVarying(shader->outputVaryings);
        case gl::ShaderType::Fragment:
            return HasFlatInterpolationVarying(shader->inputVaryings);
        case gl::ShaderType::Geometry:
            return HasFlatInterpolationVarying(shader->inputVaryings) ||
                   HasFlatInterpolationVarying(shader->outputVaryings);
        default:
            UNREACHABLE();
            return false;
    }
}

bool FindFlatInterpolationVarying(const gl::ShaderMap<gl::SharedCompiledShaderState> &shaders)
{
    for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
    {
        const gl::SharedCompiledShaderState &shader = shaders[shaderType];
        if (!shader)
        {
            continue;
        }

        if (FindFlatInterpolationVaryingPerShader(shader))
        {
            return true;
        }
    }

    return false;
}

class HLSLBlockLayoutEncoderFactory : public gl::CustomBlockLayoutEncoderFactory
{
  public:
    sh::BlockLayoutEncoder *makeEncoder() override { return new sh::HLSLBlockEncoder(false); }
};

// GetExecutableTask class
class GetExecutableTask : public LinkSubTask, public d3d::Context
{
  public:
    GetExecutableTask(ProgramD3D *program, const SharedCompiledShaderStateD3D &shader)
        : mProgram(program), mExecutable(program->getExecutable()), mShader(shader)
    {}
    ~GetExecutableTask() override = default;

    angle::Result getResult(const gl::Context *context, gl::InfoLog &infoLog) override
    {
        ASSERT((mResult == angle::Result::Continue) == (mStoredHR == S_OK));

        ANGLE_TRY(checkTask(context, infoLog));

        // Append debug info
        if (mShader && mShaderExecutable != nullptr)
        {
            mShader->appendDebugInfo(mShaderExecutable->getDebugInfo());
        }

        return angle::Result::Continue;
    }

    void handleResult(HRESULT hr,
                      const char *message,
                      const char *file,
                      const char *function,
                      unsigned int line) override
    {
        mStoredHR       = hr;
        mStoredMessage  = message;
        mStoredFile     = file;
        mStoredFunction = function;
        mStoredLine     = line;
    }

  protected:
    void popError(d3d::Context *context)
    {
        ASSERT(mStoredFile);
        ASSERT(mStoredFunction);
        context->handleResult(mStoredHR, mStoredMessage.c_str(), mStoredFile, mStoredFunction,
                              mStoredLine);
    }

    angle::Result checkTask(const gl::Context *context, gl::InfoLog &infoLog)
    {
        // Forward any logs
        if (!mInfoLog.empty())
        {
            infoLog << mInfoLog.str();
        }

        // Forward any errors
        if (mResult != angle::Result::Continue)
        {
            ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
            popError(contextD3D);
            return angle::Result::Stop;
        }

        return angle::Result::Continue;
    }

    ProgramD3D *mProgram              = nullptr;
    ProgramExecutableD3D *mExecutable = nullptr;
    angle::Result mResult             = angle::Result::Continue;
    gl::InfoLog mInfoLog;
    ShaderExecutableD3D *mShaderExecutable = nullptr;
    SharedCompiledShaderStateD3D mShader;

    // Error handling
    HRESULT mStoredHR = S_OK;
    std::string mStoredMessage;
    const char *mStoredFile     = nullptr;
    const char *mStoredFunction = nullptr;
    unsigned int mStoredLine    = 0;
};
}  // anonymous namespace

// ProgramD3DMetadata Implementation
ProgramD3DMetadata::ProgramD3DMetadata(
    RendererD3D *renderer,
    const gl::SharedCompiledShaderState &fragmentShader,
    const gl::ShaderMap<SharedCompiledShaderStateD3D> &attachedShaders,
    int shaderVersion)
    : mUsesViewScale(renderer->presentPathFastEnabled()),
      mCanSelectViewInVertexShader(renderer->canSelectViewInVertexShader()),
      mFragmentShader(fragmentShader),
      mAttachedShaders(attachedShaders),
      mShaderVersion(shaderVersion)
{}

ProgramD3DMetadata::~ProgramD3DMetadata() = default;

bool ProgramD3DMetadata::usesBroadcast(const gl::Version &clientVersion) const
{
    const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
    return shader && shader->usesFragColor && shader->usesMultipleRenderTargets &&
           clientVersion < gl::ES_3_0;
}

bool ProgramD3DMetadata::usesSecondaryColor() const
{
    const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
    return shader && shader->usesSecondaryColor;
}

FragDepthUsage ProgramD3DMetadata::getFragDepthUsage() const
{
    const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
    return shader ? shader->fragDepthUsage : FragDepthUsage::Unused;
}

bool ProgramD3DMetadata::usesPointCoord() const
{
    const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
    return shader && shader->usesPointCoord;
}

bool ProgramD3DMetadata::usesFragCoord() const
{
    const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
    return shader && shader->usesFragCoord;
}

bool ProgramD3DMetadata::usesPointSize() const
{
    const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Vertex];
    return shader && shader->usesPointSize;
}

bool ProgramD3DMetadata::usesInsertedPointCoordValue() const
{
    return usesPointCoord();
}

bool ProgramD3DMetadata::usesViewScale() const
{
    return mUsesViewScale;
}

bool ProgramD3DMetadata::hasMultiviewEnabled() const
{
    const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Vertex];
    return shader && shader->hasMultiviewEnabled;
}

bool ProgramD3DMetadata::usesVertexID() const
{
    const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Vertex];
    return shader && shader->usesVertexID;
}

bool ProgramD3DMetadata::usesViewID() const
{
    const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
    return shader && shader->usesViewID;
}

bool ProgramD3DMetadata::canSelectViewInVertexShader() const
{
    return mCanSelectViewInVertexShader;
}

bool ProgramD3DMetadata::addsPointCoordToVertexShader() const
{
    // With a geometry shader, the app can render triangles or lines and reference
    // gl_PointCoord in the fragment shader, requiring us to provide a placeholder value. For
    // simplicity, we always add this to the vertex shader when the fragment shader
    // references gl_PointCoord, even if we could skip it in the geometry shader.
    return usesInsertedPointCoordValue();
}

bool ProgramD3DMetadata::usesTransformFeedbackGLPosition() const
{
    return true;
}

bool ProgramD3DMetadata::usesSystemValuePointSize() const
{
    return usesPointSize();
}

bool ProgramD3DMetadata::usesMultipleFragmentOuts() const
{
    const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
    return shader && shader->usesMultipleRenderTargets;
}

bool ProgramD3DMetadata::usesCustomOutVars() const
{
    return mShaderVersion >= 300;
}

bool ProgramD3DMetadata::usesSampleMask() const
{
    const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Fragment];
    return shader && shader->usesSampleMask;
}

const gl::SharedCompiledShaderState &ProgramD3DMetadata::getFragmentShader() const
{
    return mFragmentShader;
}

uint8_t ProgramD3DMetadata::getClipDistanceArraySize() const
{
    const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Vertex];
    return shader ? shader->clipDistanceSize : 0;
}

uint8_t ProgramD3DMetadata::getCullDistanceArraySize() const
{
    const SharedCompiledShaderStateD3D &shader = mAttachedShaders[gl::ShaderType::Vertex];
    return shader ? shader->cullDistanceSize : 0;
}

// ProgramD3D Implementation

class ProgramD3D::GetVertexExecutableTask : public GetExecutableTask
{
  public:
    GetVertexExecutableTask(ProgramD3D *program, const SharedCompiledShaderStateD3D &shader)
        : GetExecutableTask(program, shader)
    {}
    ~GetVertexExecutableTask() override = default;

    void operator()() override
    {
        ANGLE_TRACE_EVENT0("gpu.angle", "GetVertexExecutableTask::run");

        mExecutable->updateCachedImage2DBindLayoutFromShader(gl::ShaderType::Vertex);
        mResult = mExecutable->getVertexExecutableForCachedInputLayout(
            this, mProgram->mRenderer, &mShaderExecutable, &mInfoLog);
    }
};

class ProgramD3D::GetPixelExecutableTask : public GetExecutableTask
{
  public:
    GetPixelExecutableTask(ProgramD3D *program, const SharedCompiledShaderStateD3D &shader)
        : GetExecutableTask(program, shader)
    {}
    ~GetPixelExecutableTask() override = default;

    void operator()() override
    {
        ANGLE_TRACE_EVENT0("gpu.angle", "GetPixelExecutableTask::run");
        if (!mShader)
        {
            return;
        }

        mExecutable->updateCachedOutputLayoutFromShader();
        mExecutable->updateCachedImage2DBindLayoutFromShader(gl::ShaderType::Fragment);
        mResult = mExecutable->getPixelExecutableForCachedOutputLayout(
            this, mProgram->mRenderer, &mShaderExecutable, &mInfoLog);
    }
};

class ProgramD3D::GetGeometryExecutableTask : public GetExecutableTask
{
  public:
    GetGeometryExecutableTask(ProgramD3D *program,
                              const SharedCompiledShaderStateD3D &shader,
                              const gl::Caps &caps,
                              gl::ProvokingVertexConvention provokingVertex)
        : GetExecutableTask(program, shader), mCaps(caps), mProvokingVertex(provokingVertex)
    {}
    ~GetGeometryExecutableTask() override = default;

    void operator()() override
    {
        ANGLE_TRACE_EVENT0("gpu.angle", "GetGeometryExecutableTask::run");
        // Auto-generate the geometry shader here, if we expect to be using point rendering in
        // D3D11.
        if (mExecutable->usesGeometryShader(mProgram->mRenderer, mProvokingVertex,
                                            gl::PrimitiveMode::Points))
        {
            mResult = mExecutable->getGeometryExecutableForPrimitiveType(
                this, mProgram->mRenderer, mCaps, mProvokingVertex, gl::PrimitiveMode::Points,
                &mShaderExecutable, &mInfoLog);
        }
    }

  private:
    const gl::Caps mCaps;
    gl::ProvokingVertexConvention mProvokingVertex;
};

class ProgramD3D::LinkLoadTaskD3D : public d3d::Context, public LinkTask
{
  public:
    LinkLoadTaskD3D(ProgramD3D *program) : mProgram(program), mExecutable(program->getExecutable())
    {
        ASSERT(mProgram);
    }
    ~LinkLoadTaskD3D() override = default;

    angle::Result getResult(const gl::Context *context, gl::InfoLog &infoLog) override
    {
        if (mStoredHR != S_OK)
        {
            GetImplAs<ContextD3D>(context)->handleResult(mStoredHR, mStoredMessage.c_str(),
                                                         mStoredFile, mStoredFunction, mStoredLine);
            return angle::Result::Stop;
        }

        return angle::Result::Continue;
    }

    void handleResult(HRESULT hr,
                      const char *message,
                      const char *file,
                      const char *function,
                      unsigned int line) override
    {
        mStoredHR       = hr;
        mStoredMessage  = message;
        mStoredFile     = file;
        mStoredFunction = function;
        mStoredLine     = line;
    }

  protected:
    // The front-end ensures that the program is not accessed while linking, so it is safe to
    // direclty access the state from a potentially parallel job.
    ProgramD3D *mProgram;
    ProgramExecutableD3D *mExecutable = nullptr;

    // Error handling
    HRESULT mStoredHR = S_OK;
    std::string mStoredMessage;
    const char *mStoredFile     = nullptr;
    const char *mStoredFunction = nullptr;
    unsigned int mStoredLine    = 0;
};

class ProgramD3D::LinkTaskD3D final : public LinkLoadTaskD3D
{
  public:
    LinkTaskD3D(const gl::Version &clientVersion,
                const gl::Caps &caps,
                ProgramD3D *program,
                gl::ProvokingVertexConvention provokingVertex)
        : LinkLoadTaskD3D(program),
          mClientVersion(clientVersion),
          mCaps(caps),
          mProvokingVertex(provokingVertex)
    {}
    ~LinkTaskD3D() override = default;

    void link(const gl::ProgramLinkedResources &resources,
              const gl::ProgramMergedVaryings &mergedVaryings,
              std::vector<std::shared_ptr<LinkSubTask>> *linkSubTasksOut,
              std::vector<std::shared_ptr<LinkSubTask>> *postLinkSubTasksOut) override;

  private:
    const gl::Version mClientVersion;
    const gl::Caps &mCaps;
    const gl::ProvokingVertexConvention mProvokingVertex;
};

void ProgramD3D::LinkTaskD3D::link(const gl::ProgramLinkedResources &resources,
                                   const gl::ProgramMergedVaryings &mergedVaryings,
                                   std::vector<std::shared_ptr<LinkSubTask>> *linkSubTasksOut,
                                   std::vector<std::shared_ptr<LinkSubTask>> *postLinkSubTasksOut)
{
    ANGLE_TRACE_EVENT0("gpu.angle", "LinkTaskD3D::link");

    ASSERT(linkSubTasksOut && linkSubTasksOut->empty());
    ASSERT(postLinkSubTasksOut && postLinkSubTasksOut->empty());

    angle::Result result =
        mProgram->linkJobImpl(this, mCaps, mClientVersion, resources, mergedVaryings);
    ASSERT((result == angle::Result::Continue) == (mStoredHR == S_OK));

    if (result != angle::Result::Continue)
    {
        return;
    }

    // Geometry shaders are currently only used internally, so there is no corresponding shader
    // object at the interface level. For now the geometry shader debug info is prepended to the
    // vertex shader.
    linkSubTasksOut->push_back(std::make_shared<GetVertexExecutableTask>(
        mProgram, mProgram->getAttachedShader(gl::ShaderType::Vertex)));
    linkSubTasksOut->push_back(std::make_shared<GetPixelExecutableTask>(
        mProgram, mProgram->getAttachedShader(gl::ShaderType::Fragment)));
    linkSubTasksOut->push_back(std::make_shared<GetGeometryExecutableTask>(
        mProgram, mProgram->getAttachedShader(gl::ShaderType::Vertex), mCaps, mProvokingVertex));
}

class ProgramD3D::LoadTaskD3D final : public LinkLoadTaskD3D
{
  public:
    LoadTaskD3D(ProgramD3D *program, angle::MemoryBuffer &&streamData)
        : LinkLoadTaskD3D(program), mStreamData(std::move(streamData))
    {}
    ~LoadTaskD3D() override = default;

    void load(std::vector<std::shared_ptr<LinkSubTask>> *linkSubTasksOut,
              std::vector<std::shared_ptr<LinkSubTask>> *postLinkSubTasksOut) override
    {
        ANGLE_TRACE_EVENT0("gpu.angle", "LoadTaskD3D::load");

        ASSERT(linkSubTasksOut && linkSubTasksOut->empty());
        ASSERT(postLinkSubTasksOut && postLinkSubTasksOut->empty());

        gl::BinaryInputStream stream(mStreamData);
        mResult = mExecutable->loadBinaryShaderExecutables(this, mProgram->mRenderer, &stream);

        return;
    }

    angle::Result getResult(const gl::Context *context, gl::InfoLog &infoLog) override
    {
        ANGLE_TRY(LinkLoadTaskD3D::getResult(context, infoLog));
        return mResult;
    }

  private:
    angle::MemoryBuffer mStreamData;
    angle::Result mResult = angle::Result::Continue;
};

ProgramD3D::ProgramD3D(const gl::ProgramState &state, RendererD3D *renderer)
    : ProgramImpl(state), mRenderer(renderer)
{}

ProgramD3D::~ProgramD3D() = default;

void ProgramD3D::destroy(const gl::Context *context)
{
    getExecutable()->reset();
}

angle::Result ProgramD3D::load(const gl::Context *context,
                               gl::BinaryInputStream *stream,
                               std::shared_ptr<LinkTask> *loadTaskOut,
                               egl::CacheGetResult *resultOut)
{
    if (!getExecutable()->load(context, mRenderer, stream))
    {
        mState.getExecutable().getInfoLog()
            << "Invalid program binary, device configuration has changed.";
        return angle::Result::Continue;
    }

    // Copy the remaining data from the stream locally so that the client can't modify it when
    // loading off thread.
    angle::MemoryBuffer streamData;
    angle::Span<const uint8_t> remaining = stream->remainingSpan();
    if (!streamData.resize(remaining.size()))
    {
        mState.getExecutable().getInfoLog()
            << "Failed to copy program binary data to local buffer.";
        return angle::Result::Stop;
    }
    angle::SpanMemcpy(angle::Span(streamData), remaining);

    // Note: pretty much all the above can also be moved to the task
    *loadTaskOut = std::shared_ptr<LinkTask>(new LoadTaskD3D(this, std::move(streamData)));
    *resultOut   = egl::CacheGetResult::Success;

    return angle::Result::Continue;
}

void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream)
{
    getExecutable()->save(context, mRenderer, stream);
}

void ProgramD3D::setBinaryRetrievableHint(bool /* retrievable */) {}

void ProgramD3D::setSeparable(bool /* separable */) {}

void ProgramD3D::prepareForLink(const gl::ShaderMap<ShaderImpl *> &shaders)
{
    ProgramExecutableD3D *executableD3D = getExecutable();

    for (gl::ShaderType shaderType : gl::AllShaderTypes())
    {
        executableD3D->mAttachedShaders[shaderType].reset();

        if (shaders[shaderType] != nullptr)
        {
            const ShaderD3D *shaderD3D                  = GetAs<ShaderD3D>(shaders[shaderType]);
            executableD3D->mAttachedShaders[shaderType] = shaderD3D->getCompiledState();
        }
    }
}

angle::Result ProgramD3D::link(const gl::Context *context, std::shared_ptr<LinkTask> *linkTaskOut)
{
    ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::link");
    const gl::Version &clientVersion = context->getClientVersion();
    const gl::Caps &caps             = context->getCaps();

    // Ensure the compiler is initialized to avoid race conditions.
    ANGLE_TRY(mRenderer->ensureHLSLCompilerInitialized(GetImplAs<ContextD3D>(context)));

    *linkTaskOut = std::shared_ptr<LinkTask>(
        new LinkTaskD3D(clientVersion, caps, this, context->getState().getProvokingVertex()));

    return angle::Result::Continue;
}

angle::Result ProgramD3D::linkJobImpl(d3d::Context *context,
                                      const gl::Caps &caps,
                                      const gl::Version &clientVersion,
                                      const gl::ProgramLinkedResources &resources,
                                      const gl::ProgramMergedVaryings &mergedVaryings)
{
    ProgramExecutableD3D *executableD3D = getExecutable();

    for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
    {
        const gl::SharedCompiledShaderState &shader = mState.getAttachedShader(shaderType);
        if (shader)
        {
            executableD3D->mAttachedShaders[shaderType]->generateWorkarounds(
                &executableD3D->mShaderWorkarounds[shaderType]);
            executableD3D->mShaderSamplers[shaderType].resize(
                caps.maxShaderTextureImageUnits[shaderType]);
            executableD3D->mImages[shaderType].resize(caps.maxImageUnits);
            executableD3D->mReadonlyImages[shaderType].resize(caps.maxImageUnits);

            executableD3D->mShaderUniformsDirty.set(shaderType);

            for (const sh::ShaderVariable &uniform : shader->uniforms)
            {
                if (gl::IsImageType(uniform.type) && gl::IsImage2DType(uniform.type))
                {
                    executableD3D->mImage2DUniforms[shaderType].push_back(uniform);
                }
            }

            for (const std::string &slowBlock :
                 executableD3D->mAttachedShaders[shaderType]->slowCompilingUniformBlockSet)
            {
                WARN() << "Uniform block '" << slowBlock << "' will be slow to compile. "
                       << "See UniformBlockToStructuredBufferTranslation.md "
                       << "(https://shorturl.at/drFY7) for details.";
            }
        }
    }

    const gl::VaryingPacking &varyingPacking =
        resources.varyingPacking.getOutputPacking(gl::ShaderType::Vertex);

    ProgramD3DMetadata metadata(mRenderer, mState.getAttachedShader(gl::ShaderType::Fragment),
                                executableD3D->mAttachedShaders,
                                mState.getAttachedShader(gl::ShaderType::Vertex)->shaderVersion);
    BuiltinVaryingsD3D builtins(metadata, varyingPacking);

    DynamicHLSL::GenerateShaderLinkHLSL(caps, mState.getAttachedShaders(),
                                        executableD3D->mAttachedShaders, metadata, varyingPacking,
                                        builtins, &executableD3D->mShaderHLSL);

    executableD3D->mUsesPointSize =
        executableD3D->mAttachedShaders[gl::ShaderType::Vertex] &&
        executableD3D->mAttachedShaders[gl::ShaderType::Vertex]->usesPointSize;
    DynamicHLSL::GetPixelShaderOutputKey(mRenderer, caps, clientVersion, mState.getExecutable(),
                                         metadata, &executableD3D->mPixelShaderKey);
    executableD3D->mFragDepthUsage      = metadata.getFragDepthUsage();
    executableD3D->mUsesSampleMask      = metadata.usesSampleMask();
    executableD3D->mUsesVertexID        = metadata.usesVertexID();
    executableD3D->mUsesViewID          = metadata.usesViewID();
    executableD3D->mHasMultiviewEnabled = metadata.hasMultiviewEnabled();

    // Cache if we use flat shading
    executableD3D->mUsesFlatInterpolation =
        FindFlatInterpolationVarying(mState.getAttachedShaders());

    executableD3D->mGeometryShaderPreamble = DynamicHLSL::GenerateGeometryShaderPreamble(
        varyingPacking, builtins, executableD3D->mHasMultiviewEnabled,
        metadata.canSelectViewInVertexShader());

    executableD3D->initAttribLocationsToD3DSemantic(
        mState.getAttachedShader(gl::ShaderType::Vertex));

    executableD3D->defineUniformsAndAssignRegisters(mRenderer, mState.getAttachedShaders());

    executableD3D->gatherTransformFeedbackVaryings(varyingPacking,
                                                   mState.getTransformFeedbackVaryingNames(),
                                                   builtins[gl::ShaderType::Vertex]);

    linkResources(resources);

    if (mState.getAttachedShader(gl::ShaderType::Vertex))
    {
        executableD3D->updateCachedInputLayoutFromShader(
            mRenderer, mState.getAttachedShader(gl::ShaderType::Vertex));
    }

    return angle::Result::Continue;
}

GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/)
{
    // TODO(jmadill): Do something useful here?
    return GL_TRUE;
}

void ProgramD3D::linkResources(const gl::ProgramLinkedResources &resources)
{
    HLSLBlockLayoutEncoderFactory hlslEncoderFactory;
    gl::ProgramLinkedResourcesLinker linker(&hlslEncoderFactory);

    linker.linkResources(mState, resources);

    ProgramExecutableD3D *executableD3D = getExecutable();

    executableD3D->initializeUniformBlocks();
}

}  // namespace rx
