
// 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 <= 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
