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

// Clear11.cpp: Framebuffer clear utility class.

#include "libANGLE/renderer/d3d/d3d11/Clear11.h"

#include <algorithm>

#include "libANGLE/Context.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/FramebufferD3D.h"
#include "libANGLE/renderer/d3d/d3d11/Context11.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/trace.h"

// Precompiled shaders
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11_fl9vs.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewgs.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11multiviewvs.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clear11vs.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/cleardepth11ps.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11_fl9ps.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps1.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps2.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps3.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps4.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps5.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps6.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps7.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps8.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps1.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps2.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps3.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps4.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps5.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps6.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps7.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearsint11ps8.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps1.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps2.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps3.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps4.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps5.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps6.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps7.h"
#include "libANGLE/renderer/d3d/d3d11/shaders/compiled/clearuint11ps8.h"

namespace rx
{

namespace
{
constexpr uint32_t g_ConstantBufferSize = sizeof(RtvDsvClearInfo<float>);
constexpr uint32_t g_VertexSize         = sizeof(d3d11::PositionVertex);

// Updates color, depth and alpha components of cached CB if necessary.
// Returns true if any constants are updated, false otherwise.
template <typename T>
bool UpdateDataCache(RtvDsvClearInfo<T> *dataCache,
                     const gl::Color<T> &color,
                     const float *zValue,
                     const uint32_t numRtvs,
                     const uint8_t writeMask)
{
    bool cacheDirty = false;

    if (numRtvs > 0)
    {
        const bool writeRGB = (writeMask & ~D3D11_COLOR_WRITE_ENABLE_ALPHA) != 0;
        if (writeRGB && memcmp(&dataCache->r, &color.red, sizeof(T) * 3) != 0)
        {
            dataCache->r = color.red;
            dataCache->g = color.green;
            dataCache->b = color.blue;
            cacheDirty   = true;
        }

        const bool writeAlpha = (writeMask & D3D11_COLOR_WRITE_ENABLE_ALPHA) != 0;
        if (writeAlpha && (dataCache->a != color.alpha))
        {
            dataCache->a = color.alpha;
            cacheDirty   = true;
        }
    }

    if (zValue)
    {
        const float clampedZValue = gl::clamp01(*zValue);

        if (clampedZValue != dataCache->z)
        {
            dataCache->z = clampedZValue;
            cacheDirty   = true;
        }
    }

    return cacheDirty;
}

}  // anonymous namespace

#define CLEARPS(Index)                                                                    \
    d3d11::LazyShader<ID3D11PixelShader>(g_PS_Clear##Index, ArraySize(g_PS_Clear##Index), \
                                         "Clear11 PS " ANGLE_STRINGIFY(Index))

Clear11::ShaderManager::ShaderManager()
    : mIl9(),
      mVs9(g_VS_Clear_FL9, ArraySize(g_VS_Clear_FL9), "Clear11 VS FL9"),
      mPsFloat9(g_PS_ClearFloat_FL9, ArraySize(g_PS_ClearFloat_FL9), "Clear11 PS FloatFL9"),
      mVs(g_VS_Clear, ArraySize(g_VS_Clear), "Clear11 VS"),
      mVsMultiview(g_VS_Multiview_Clear, ArraySize(g_VS_Multiview_Clear), "Clear11 VS Multiview"),
      mGsMultiview(g_GS_Multiview_Clear, ArraySize(g_GS_Multiview_Clear), "Clear11 GS Multiview"),
      mPsDepth(g_PS_ClearDepth, ArraySize(g_PS_ClearDepth), "Clear11 PS Depth"),
      mPsFloat{{CLEARPS(Float1), CLEARPS(Float2), CLEARPS(Float3), CLEARPS(Float4), CLEARPS(Float5),
                CLEARPS(Float6), CLEARPS(Float7), CLEARPS(Float8)}},
      mPsUInt{{CLEARPS(Uint1), CLEARPS(Uint2), CLEARPS(Uint3), CLEARPS(Uint4), CLEARPS(Uint5),
               CLEARPS(Uint6), CLEARPS(Uint7), CLEARPS(Uint8)}},
      mPsSInt{{CLEARPS(Sint1), CLEARPS(Sint2), CLEARPS(Sint3), CLEARPS(Sint4), CLEARPS(Sint5),
               CLEARPS(Sint6), CLEARPS(Sint7), CLEARPS(Sint8)}}
{}

#undef CLEARPS

Clear11::ShaderManager::~ShaderManager() {}

angle::Result Clear11::ShaderManager::getShadersAndLayout(const gl::Context *context,
                                                          Renderer11 *renderer,
                                                          const INT clearType,
                                                          const uint32_t numRTs,
                                                          const bool hasLayeredLayout,
                                                          const d3d11::InputLayout **il,
                                                          const d3d11::VertexShader **vs,
                                                          const d3d11::GeometryShader **gs,
                                                          const d3d11::PixelShader **ps)
{
    Context11 *context11 = GetImplAs<Context11>(context);

    if (renderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
    {
        ASSERT(clearType == GL_FLOAT);

        ANGLE_TRY(mVs9.resolve(context11, renderer));
        ANGLE_TRY(mPsFloat9.resolve(context11, renderer));

        if (!mIl9.valid())
        {
            const D3D11_INPUT_ELEMENT_DESC ilDesc[] = {
                {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}};

            InputElementArray ilDescArray(ilDesc);
            ShaderData vertexShader(g_VS_Clear_FL9);

            ANGLE_TRY(renderer->allocateResource(context11, ilDescArray, &vertexShader, &mIl9));
        }

        *vs = &mVs9.getObj();
        *gs = nullptr;
        *il = &mIl9;
        *ps = &mPsFloat9.getObj();
        return angle::Result::Continue;
    }

    if (!hasLayeredLayout)
    {
        ANGLE_TRY(mVs.resolve(context11, renderer));
        *vs = &mVs.getObj();
        *gs = nullptr;
    }
    else
    {
        // For layered framebuffers we have to use the multi-view versions of the VS and GS.
        ANGLE_TRY(mVsMultiview.resolve(context11, renderer));
        ANGLE_TRY(mGsMultiview.resolve(context11, renderer));
        *vs = &mVsMultiview.getObj();
        *gs = &mGsMultiview.getObj();
    }

    *il = nullptr;

    if (numRTs == 0)
    {
        ANGLE_TRY(mPsDepth.resolve(context11, renderer));
        *ps = &mPsDepth.getObj();
        return angle::Result::Continue;
    }

    switch (clearType)
    {
        case GL_FLOAT:
            ANGLE_TRY(mPsFloat[numRTs - 1].resolve(context11, renderer));
            *ps = &mPsFloat[numRTs - 1].getObj();
            break;
        case GL_UNSIGNED_INT:
            ANGLE_TRY(mPsUInt[numRTs - 1].resolve(context11, renderer));
            *ps = &mPsUInt[numRTs - 1].getObj();
            break;
        case GL_INT:
            ANGLE_TRY(mPsSInt[numRTs - 1].resolve(context11, renderer));
            *ps = &mPsSInt[numRTs - 1].getObj();
            break;
        default:
            UNREACHABLE();
            break;
    }

    return angle::Result::Continue;
}

Clear11::Clear11(Renderer11 *renderer)
    : mRenderer(renderer),
      mResourcesInitialized(false),
      mScissorEnabledRasterizerState(),
      mScissorDisabledRasterizerState(),
      mShaderManager(),
      mConstantBuffer(),
      mVertexBuffer(),
      mShaderData({})
{}

Clear11::~Clear11() {}

angle::Result Clear11::ensureResourcesInitialized(const gl::Context *context)
{
    if (mResourcesInitialized)
    {
        return angle::Result::Continue;
    }

    ANGLE_TRACE_EVENT0("gpu.angle", "Clear11::ensureResourcesInitialized");

    static_assert((sizeof(RtvDsvClearInfo<float>) == sizeof(RtvDsvClearInfo<int>)),
                  "Size of rx::RtvDsvClearInfo<float> is not equal to rx::RtvDsvClearInfo<int>");

    static_assert(
        (sizeof(RtvDsvClearInfo<float>) == sizeof(RtvDsvClearInfo<uint32_t>)),
        "Size of rx::RtvDsvClearInfo<float> is not equal to rx::RtvDsvClearInfo<uint32_t>");

    static_assert((sizeof(RtvDsvClearInfo<float>) % 16 == 0),
                  "The size of RtvDsvClearInfo<float> should be a multiple of 16bytes.");

    // Create Rasterizer States
    D3D11_RASTERIZER_DESC rsDesc;
    rsDesc.FillMode              = D3D11_FILL_SOLID;
    rsDesc.CullMode              = D3D11_CULL_NONE;
    rsDesc.FrontCounterClockwise = FALSE;
    rsDesc.DepthBias             = 0;
    rsDesc.DepthBiasClamp        = 0.0f;
    rsDesc.SlopeScaledDepthBias  = 0.0f;
    rsDesc.DepthClipEnable       = TRUE;
    rsDesc.ScissorEnable         = FALSE;
    rsDesc.MultisampleEnable     = FALSE;
    rsDesc.AntialiasedLineEnable = FALSE;

    Context11 *context11 = GetImplAs<Context11>(context);

    ANGLE_TRY(mRenderer->allocateResource(context11, rsDesc, &mScissorDisabledRasterizerState));
    mScissorDisabledRasterizerState.setDebugName("Clear11 Rasterizer State with scissor disabled");

    rsDesc.ScissorEnable = TRUE;
    ANGLE_TRY(mRenderer->allocateResource(context11, rsDesc, &mScissorEnabledRasterizerState));
    mScissorEnabledRasterizerState.setDebugName("Clear11 Rasterizer State with scissor enabled");

    // Initialize Depthstencil state with defaults
    mDepthStencilStateKey.depthTest                = false;
    mDepthStencilStateKey.depthMask                = false;
    mDepthStencilStateKey.depthFunc                = GL_ALWAYS;
    mDepthStencilStateKey.stencilWritemask         = static_cast<GLuint>(-1);
    mDepthStencilStateKey.stencilBackWritemask     = static_cast<GLuint>(-1);
    mDepthStencilStateKey.stencilBackMask          = 0;
    mDepthStencilStateKey.stencilTest              = false;
    mDepthStencilStateKey.stencilMask              = 0;
    mDepthStencilStateKey.stencilFail              = GL_REPLACE;
    mDepthStencilStateKey.stencilPassDepthFail     = GL_REPLACE;
    mDepthStencilStateKey.stencilPassDepthPass     = GL_REPLACE;
    mDepthStencilStateKey.stencilFunc              = GL_ALWAYS;
    mDepthStencilStateKey.stencilBackFail          = GL_REPLACE;
    mDepthStencilStateKey.stencilBackPassDepthFail = GL_REPLACE;
    mDepthStencilStateKey.stencilBackPassDepthPass = GL_REPLACE;
    mDepthStencilStateKey.stencilBackFunc          = GL_ALWAYS;

    // Initialize BlendStateKey with defaults
    mBlendStateKey.blendState.blend                 = false;
    mBlendStateKey.blendState.sourceBlendRGB        = GL_ONE;
    mBlendStateKey.blendState.sourceBlendAlpha      = GL_ONE;
    mBlendStateKey.blendState.destBlendRGB          = GL_ZERO;
    mBlendStateKey.blendState.destBlendAlpha        = GL_ZERO;
    mBlendStateKey.blendState.blendEquationRGB      = GL_FUNC_ADD;
    mBlendStateKey.blendState.blendEquationAlpha    = GL_FUNC_ADD;
    mBlendStateKey.blendState.sampleAlphaToCoverage = false;
    mBlendStateKey.blendState.dither                = true;

    mResourcesInitialized = true;
    return angle::Result::Continue;
}

bool Clear11::useVertexBuffer() const
{
    return (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3);
}

angle::Result Clear11::ensureConstantBufferCreated(const gl::Context *context)
{
    if (mConstantBuffer.valid())
    {
        return angle::Result::Continue;
    }

    // Create constant buffer for color & depth data

    D3D11_BUFFER_DESC bufferDesc;
    bufferDesc.ByteWidth           = g_ConstantBufferSize;
    bufferDesc.Usage               = D3D11_USAGE_DYNAMIC;
    bufferDesc.BindFlags           = D3D11_BIND_CONSTANT_BUFFER;
    bufferDesc.CPUAccessFlags      = D3D11_CPU_ACCESS_WRITE;
    bufferDesc.MiscFlags           = 0;
    bufferDesc.StructureByteStride = 0;

    D3D11_SUBRESOURCE_DATA initialData;
    initialData.pSysMem          = &mShaderData;
    initialData.SysMemPitch      = g_ConstantBufferSize;
    initialData.SysMemSlicePitch = g_ConstantBufferSize;

    ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), bufferDesc, &initialData,
                                          &mConstantBuffer));
    mConstantBuffer.setDebugName("Clear11 Constant Buffer");
    return angle::Result::Continue;
}

angle::Result Clear11::ensureVertexBufferCreated(const gl::Context *context)
{
    ASSERT(useVertexBuffer());

    if (mVertexBuffer.valid())
    {
        return angle::Result::Continue;
    }

    // Create vertex buffer with vertices for a quad covering the entire surface

    static_assert((sizeof(d3d11::PositionVertex) % 16) == 0,
                  "d3d11::PositionVertex should be a multiple of 16 bytes");
    const d3d11::PositionVertex vbData[6] = {{-1.0f, 1.0f, 0.0f, 1.0f},  {1.0f, -1.0f, 0.0f, 1.0f},
                                             {-1.0f, -1.0f, 0.0f, 1.0f}, {-1.0f, 1.0f, 0.0f, 1.0f},
                                             {1.0f, 1.0f, 0.0f, 1.0f},   {1.0f, -1.0f, 0.0f, 1.0f}};

    const UINT vbSize = sizeof(vbData);

    D3D11_BUFFER_DESC bufferDesc;
    bufferDesc.ByteWidth           = vbSize;
    bufferDesc.Usage               = D3D11_USAGE_IMMUTABLE;
    bufferDesc.BindFlags           = D3D11_BIND_VERTEX_BUFFER;
    bufferDesc.CPUAccessFlags      = 0;
    bufferDesc.MiscFlags           = 0;
    bufferDesc.StructureByteStride = 0;

    D3D11_SUBRESOURCE_DATA initialData;
    initialData.pSysMem          = vbData;
    initialData.SysMemPitch      = vbSize;
    initialData.SysMemSlicePitch = initialData.SysMemPitch;

    ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), bufferDesc, &initialData,
                                          &mVertexBuffer));
    mVertexBuffer.setDebugName("Clear11 Vertex Buffer");
    return angle::Result::Continue;
}

angle::Result Clear11::clearFramebuffer(const gl::Context *context,
                                        const ClearParameters &clearParams,
                                        const gl::FramebufferState &fboData)
{
    ANGLE_TRY(ensureResourcesInitialized(context));

    // Iterate over the color buffers which require clearing and determine if they can be
    // cleared with ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView.
    // This requires:
    // 1) The render target is being cleared to a float value (will be cast to integer when clearing
    // integer render targets as expected but does not work the other way around)
    // 2) The format of the render target has no color channels that are currently masked out.
    // Clear the easy-to-clear buffers on the spot and accumulate the ones that require special
    // work.
    //
    // If these conditions are met, and:
    // - No scissored clear is needed, then clear using ID3D11DeviceContext::ClearRenderTargetView.
    // - A scissored clear is needed then clear using ID3D11DeviceContext1::ClearView if available.
    // Otherwise perform a shader based clear.
    //
    // Also determine if the DSV can be cleared withID3D11DeviceContext::ClearDepthStencilView by
    // checking if the stencil write mask covers the entire stencil.
    //
    // To clear the remaining buffers, a shader based clear is performed:
    // - The appropriate ShaderManagers (VS & PS) for the clearType is set
    // - A CB containing the clear color and Z values is bound
    // - An IL and VB are bound (for FL93 and below)
    // - ScissorRect/Raststate/Viewport set as required
    // - Blendstate set containing appropriate colorMasks
    // - DepthStencilState set with appropriate parameters for a z or stencil clear if required
    // - Color and/or Z buffers to be cleared are bound
    // - Primitive covering entire clear area is drawn

    gl::Extents framebufferSize;

    const auto *depthStencilAttachment = fboData.getDepthOrStencilAttachment();
    if (depthStencilAttachment != nullptr)
    {
        framebufferSize = depthStencilAttachment->getSize();
    }
    else
    {
        const gl::FramebufferAttachment *colorAttachment = fboData.getFirstColorAttachment();
        ASSERT(colorAttachment);
        framebufferSize = colorAttachment->getSize();
    }

    bool needScissoredClear = false;
    D3D11_RECT scissorRect;
    if (clearParams.scissorEnabled)
    {
        if (clearParams.scissor.x >= framebufferSize.width ||
            clearParams.scissor.y >= framebufferSize.height || clearParams.scissor.width == 0 ||
            clearParams.scissor.height == 0)
        {
            // The check assumes that the viewport offsets are not negative as according to the
            // OVR_multiview2 spec.
            // Scissor rect is outside the renderbuffer or is an empty rect.
            return angle::Result::Continue;
        }

        if (clearParams.scissor.x + clearParams.scissor.width <= 0 ||
            clearParams.scissor.y + clearParams.scissor.height <= 0)
        {
            // Scissor rect is outside the renderbuffer.
            return angle::Result::Continue;
        }
        needScissoredClear =
            clearParams.scissor.x > 0 || clearParams.scissor.y > 0 ||
            clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width ||
            clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height;

        if (needScissoredClear)
        {
            // Apply viewport offsets to compute the final scissor rectangles.
            // Even in multiview all layers share the same viewport and scissor.
            scissorRect.left   = clearParams.scissor.x;
            scissorRect.right  = scissorRect.left + clearParams.scissor.width;
            scissorRect.top    = clearParams.scissor.y;
            scissorRect.bottom = scissorRect.top + clearParams.scissor.height;
        }
    }

    ID3D11DeviceContext *deviceContext   = mRenderer->getDeviceContext();
    ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();

    std::array<ID3D11RenderTargetView *, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> rtvs;
    std::array<uint8_t, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT> rtvMasks = {};

    uint32_t numRtvs = 0;
    const uint8_t colorMask =
        gl_d3d11::ConvertColorMask(clearParams.colorMaskRed, clearParams.colorMaskGreen,
                                   clearParams.colorMaskBlue, clearParams.colorMaskAlpha);

    const auto &colorAttachments = fboData.getColorAttachments();
    for (auto colorAttachmentIndex : fboData.getEnabledDrawBuffers())
    {
        const gl::FramebufferAttachment &attachment = colorAttachments[colorAttachmentIndex];

        if (!clearParams.clearColor[colorAttachmentIndex])
        {
            continue;
        }

        RenderTarget11 *renderTarget = nullptr;
        ANGLE_TRY(attachment.getRenderTarget(context, attachment.getRenderToTextureSamples(),
                                             &renderTarget));

        const gl::InternalFormat &formatInfo = *attachment.getFormat().info;

        if (clearParams.colorType == GL_FLOAT &&
            !(formatInfo.componentType == GL_FLOAT ||
              formatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
              formatInfo.componentType == GL_SIGNED_NORMALIZED))
        {
            WARN() << "It is undefined behaviour to clear a render buffer which is not "
                      "normalized fixed point or floating-point to floating point values (color "
                      "attachment "
                   << colorAttachmentIndex << " has internal format " << attachment.getFormat()
                   << ").";
        }

        if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) &&
            (formatInfo.greenBits == 0 || !clearParams.colorMaskGreen) &&
            (formatInfo.blueBits == 0 || !clearParams.colorMaskBlue) &&
            (formatInfo.alphaBits == 0 || !clearParams.colorMaskAlpha))
        {
            // Every channel either does not exist in the render target or is masked out
            continue;
        }

        const auto &framebufferRTV = renderTarget->getRenderTargetView();
        ASSERT(framebufferRTV.valid());

        if ((!(mRenderer->getRenderer11DeviceCaps().supportsClearView) && needScissoredClear) ||
            clearParams.colorType != GL_FLOAT ||
            (formatInfo.redBits > 0 && !clearParams.colorMaskRed) ||
            (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) ||
            (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) ||
            (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha))
        {
            rtvs[numRtvs]     = framebufferRTV.get();
            rtvMasks[numRtvs] = gl_d3d11::GetColorMask(formatInfo) & colorMask;
            numRtvs++;
        }
        else
        {
            // ID3D11DeviceContext::ClearRenderTargetView or ID3D11DeviceContext1::ClearView is
            // possible

            const auto &nativeFormat = renderTarget->getFormatSet().format();

            // Check if the actual format has a channel that the internal format does not and
            // set them to the default values
            float clearValues[4] = {
                ((formatInfo.redBits == 0 && nativeFormat.redBits > 0) ? 0.0f
                                                                       : clearParams.colorF.red),
                ((formatInfo.greenBits == 0 && nativeFormat.greenBits > 0)
                     ? 0.0f
                     : clearParams.colorF.green),
                ((formatInfo.blueBits == 0 && nativeFormat.blueBits > 0) ? 0.0f
                                                                         : clearParams.colorF.blue),
                ((formatInfo.alphaBits == 0 && nativeFormat.alphaBits > 0)
                     ? 1.0f
                     : clearParams.colorF.alpha),
            };

            if (formatInfo.alphaBits == 1)
            {
                // Some drivers do not correctly handle calling Clear() on a format with 1-bit
                // alpha. They can incorrectly round all non-zero values up to 1.0f. Note that
                // WARP does not do this. We should handle the rounding for them instead.
                clearValues[3] = (clearParams.colorF.alpha >= 0.5f) ? 1.0f : 0.0f;
            }

            if (needScissoredClear)
            {
                // We shouldn't reach here if deviceContext1 is unavailable.
                ASSERT(deviceContext1);
                deviceContext1->ClearView(framebufferRTV.get(), clearValues, &scissorRect, 1);
                if (mRenderer->getFeatures().callClearTwice.enabled)
                {
                    deviceContext1->ClearView(framebufferRTV.get(), clearValues, &scissorRect, 1);
                }
            }
            else
            {
                deviceContext->ClearRenderTargetView(framebufferRTV.get(), clearValues);
                if (mRenderer->getFeatures().callClearTwice.enabled)
                {
                    deviceContext->ClearRenderTargetView(framebufferRTV.get(), clearValues);
                }
            }
        }
    }

    ID3D11DepthStencilView *dsv = nullptr;

    if (clearParams.clearDepth || clearParams.clearStencil)
    {
        RenderTarget11 *depthStencilRenderTarget = nullptr;

        ASSERT(depthStencilAttachment != nullptr);
        ANGLE_TRY(depthStencilAttachment->getRenderTarget(
            context, depthStencilAttachment->getRenderToTextureSamples(),
            &depthStencilRenderTarget));

        dsv = depthStencilRenderTarget->getDepthStencilView().get();
        ASSERT(dsv != nullptr);

        const auto &nativeFormat      = depthStencilRenderTarget->getFormatSet().format();
        const auto *stencilAttachment = fboData.getStencilAttachment();

        uint32_t stencilUnmasked =
            (stencilAttachment != nullptr) ? (1 << nativeFormat.stencilBits) - 1 : 0;
        bool needMaskedStencilClear =
            clearParams.clearStencil &&
            (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;

        if (!needScissoredClear && !needMaskedStencilClear)
        {
            const UINT clearFlags = (clearParams.clearDepth ? D3D11_CLEAR_DEPTH : 0) |
                                    (clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0);
            const FLOAT depthClear   = gl::clamp01(clearParams.depthValue);
            const UINT8 stencilClear = clearParams.stencilValue & 0xFF;

            deviceContext->ClearDepthStencilView(dsv, clearFlags, depthClear, stencilClear);

            dsv = nullptr;
        }
    }

    if (numRtvs == 0 && dsv == nullptr)
    {
        return angle::Result::Continue;
    }

    // Clear the remaining render targets and depth stencil in one pass by rendering a quad:
    //
    // IA/VS: Vertices containing position and color members are passed through to the next stage.
    // The vertex position has XY coordinates equal to clip extents and a Z component equal to the
    // Z clear value. The vertex color contains the clear color.
    //
    // Rasterizer: Viewport scales the VS output over the entire surface and depending on whether
    // or not scissoring is enabled the appropriate scissor rect and rasterizerState with or without
    // the scissor test enabled is set as well.
    //
    // DepthStencilTest: DepthTesting, DepthWrites, StencilMask and StencilWrites will be enabled or
    // disabled or set depending on what the input depthStencil clear parameters are. Since the PS
    // is not writing out depth or rejecting pixels, this should happen prior to the PS stage.
    //
    // PS: Will write out the color values passed through from the previous stage to all outputs.
    //
    // OM: BlendState will perform the required color masking and output to RTV(s).

    //
    // ======================================================================================
    //
    // Luckily, the gl spec (ES 3.0.2 pg 183) states that the results of clearing a render-
    // buffer that is not normalized fixed point or floating point with floating point values
    // are undefined so we can just write floats to them and D3D11 will bit cast them to
    // integers.
    //
    // Also, we don't have to worry about attempting to clear a normalized fixed/floating point
    // buffer with integer values because there is no gl API call which would allow it,
    // glClearBuffer* calls only clear a single renderbuffer at a time which is verified to
    // be a compatible clear type.

    ASSERT(numRtvs <= static_cast<uint32_t>(mRenderer->getNativeCaps().maxDrawBuffers));

    // Setup BlendStateKey parameters
    mBlendStateKey.blendState.colorMaskRed   = clearParams.colorMaskRed;
    mBlendStateKey.blendState.colorMaskGreen = clearParams.colorMaskGreen;
    mBlendStateKey.blendState.colorMaskBlue  = clearParams.colorMaskBlue;
    mBlendStateKey.blendState.colorMaskAlpha = clearParams.colorMaskAlpha;
    mBlendStateKey.rtvMax                    = numRtvs;
    memcpy(mBlendStateKey.rtvMasks, &rtvMasks[0], sizeof(mBlendStateKey.rtvMasks));

    // Get BlendState
    const d3d11::BlendState *blendState = nullptr;
    ANGLE_TRY(mRenderer->getBlendState(context, mBlendStateKey, &blendState));

    const d3d11::DepthStencilState *dsState = nullptr;
    const float *zValue                     = nullptr;

    if (dsv)
    {
        // Setup DepthStencilStateKey
        mDepthStencilStateKey.depthTest        = clearParams.clearDepth;
        mDepthStencilStateKey.depthMask        = clearParams.clearDepth;
        mDepthStencilStateKey.stencilWritemask = clearParams.stencilWriteMask;
        mDepthStencilStateKey.stencilTest      = clearParams.clearStencil;

        // Get DepthStencilState
        ANGLE_TRY(mRenderer->getDepthStencilState(context, mDepthStencilStateKey, &dsState));
        zValue = clearParams.clearDepth ? &clearParams.depthValue : nullptr;
    }

    bool dirtyCb = false;

    // Compare the input color/z values against the CB cache and update it if necessary
    switch (clearParams.colorType)
    {
        case GL_FLOAT:
            dirtyCb = UpdateDataCache(&mShaderData, clearParams.colorF, zValue, numRtvs, colorMask);
            break;
        case GL_UNSIGNED_INT:
            dirtyCb = UpdateDataCache(reinterpret_cast<RtvDsvClearInfo<uint32_t> *>(&mShaderData),
                                      clearParams.colorUI, zValue, numRtvs, colorMask);
            break;
        case GL_INT:
            dirtyCb = UpdateDataCache(reinterpret_cast<RtvDsvClearInfo<int> *>(&mShaderData),
                                      clearParams.colorI, zValue, numRtvs, colorMask);
            break;
        default:
            UNREACHABLE();
            break;
    }

    ANGLE_TRY(ensureConstantBufferCreated(context));

    if (dirtyCb)
    {
        // Update the constant buffer with the updated cache contents
        // TODO(Shahmeer): Consider using UpdateSubresource1 D3D11_COPY_DISCARD where possible.
        D3D11_MAPPED_SUBRESOURCE mappedResource;
        ANGLE_TRY(mRenderer->mapResource(context, mConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD,
                                         0, &mappedResource));

        memcpy(mappedResource.pData, &mShaderData, g_ConstantBufferSize);
        deviceContext->Unmap(mConstantBuffer.get(), 0);
    }

    auto *stateManager = mRenderer->getStateManager();

    // Set the viewport to be the same size as the framebuffer.
    stateManager->setSimpleViewport(framebufferSize);

    // Apply state
    stateManager->setSimpleBlendState(blendState);

    const UINT stencilValue = clearParams.stencilValue & 0xFF;
    stateManager->setDepthStencilState(dsState, stencilValue);

    if (needScissoredClear)
    {
        stateManager->setRasterizerState(&mScissorEnabledRasterizerState);
    }
    else
    {
        stateManager->setRasterizerState(&mScissorDisabledRasterizerState);
    }

    // Get Shaders
    const d3d11::VertexShader *vs   = nullptr;
    const d3d11::GeometryShader *gs = nullptr;
    const d3d11::InputLayout *il    = nullptr;
    const d3d11::PixelShader *ps    = nullptr;
    const bool hasLayeredLayout     = (fboData.isMultiview());
    ANGLE_TRY(mShaderManager.getShadersAndLayout(context, mRenderer, clearParams.colorType, numRtvs,
                                                 hasLayeredLayout, &il, &vs, &gs, &ps));

    // Apply Shaders
    stateManager->setDrawShaders(vs, gs, ps);
    stateManager->setPixelConstantBuffer(0, &mConstantBuffer);

    // Bind IL & VB if needed
    stateManager->setIndexBuffer(nullptr, DXGI_FORMAT_UNKNOWN, 0);
    stateManager->setInputLayout(il);

    if (useVertexBuffer())
    {
        ANGLE_TRY(ensureVertexBufferCreated(context));
        stateManager->setSingleVertexBuffer(&mVertexBuffer, g_VertexSize, 0);
    }
    else
    {
        stateManager->setSingleVertexBuffer(nullptr, 0, 0);
    }

    stateManager->setPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    // Apply render targets
    stateManager->setRenderTargets(&rtvs[0], numRtvs, dsv);

    if (needScissoredClear)
    {
        stateManager->setScissorRectD3D(scissorRect);
    }
    // Draw the fullscreen quad.
    if (!hasLayeredLayout)
    {
        deviceContext->Draw(6, 0);
    }
    else
    {
        ASSERT(hasLayeredLayout);
        deviceContext->DrawInstanced(6, static_cast<UINT>(fboData.getNumViews()), 0, 0);
    }

    return angle::Result::Continue;
}

}  // namespace rx
