tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Blit11.cpp (79423B)


      1 //
      2 // Copyright 2013 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // Blit11.cpp: Texture copy utility class.
      8 
      9 #include "libANGLE/renderer/d3d/d3d11/Blit11.h"
     10 
     11 #include <float.h>
     12 
     13 #include "common/utilities.h"
     14 #include "libANGLE/Context.h"
     15 #include "libANGLE/formatutils.h"
     16 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
     17 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
     18 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
     19 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
     20 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
     21 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
     22 #include "libANGLE/trace.h"
     23 
     24 namespace rx
     25 {
     26 
     27 namespace
     28 {
     29 
     30 // Include inline shaders in the anonymous namespace to make sure no symbols are exported
     31 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough2d11vs.h"
     32 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthroughdepth2d11ps.h"
     33 
     34 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11gs.h"
     35 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/passthrough3d11vs.h"
     36 
     37 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepth11_ps.h"
     38 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_ps.h"
     39 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvedepthstencil11_vs.h"
     40 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/resolvestencil11_ps.h"
     41 
     42 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2darrayps.h"
     43 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef2dps.h"
     44 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlef3dps.h"
     45 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2darrayps.h"
     46 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei2dps.h"
     47 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzlei3dps.h"
     48 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2darrayps.h"
     49 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui2dps.h"
     50 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/swizzleui3dps.h"
     51 
     52 void StretchedBlitNearest_RowByRow(const gl::Box &sourceArea,
     53                                   const gl::Box &destArea,
     54                                   const gl::Rectangle &clippedDestArea,
     55                                   const gl::Extents &sourceSize,
     56                                   unsigned int sourceRowPitch,
     57                                   unsigned int destRowPitch,
     58                                   size_t pixelSize,
     59                                   const uint8_t *sourceData,
     60                                   uint8_t *destData)
     61 {
     62    int srcHeightSubOne = (sourceArea.height - 1);
     63    size_t copySize     = pixelSize * clippedDestArea.width;
     64    size_t srcOffset    = sourceArea.x * pixelSize;
     65    size_t destOffset   = clippedDestArea.x * pixelSize;
     66 
     67    for (int y = clippedDestArea.y; y < clippedDestArea.y + clippedDestArea.height; y++)
     68    {
     69        // TODO: Fix divide by zero when height == 1. http://anglebug.com/6099
     70        float yPerc = static_cast<float>(y - destArea.y) / (destArea.height - 1);
     71 
     72        // Interpolate using the original source rectangle to determine which row to sample from
     73        // while clamping to the edges
     74        unsigned int readRow = static_cast<unsigned int>(
     75            gl::clamp(sourceArea.y + floor(yPerc * srcHeightSubOne + 0.5f), 0, srcHeightSubOne));
     76        unsigned int writeRow = y;
     77 
     78        const uint8_t *sourceRow = sourceData + readRow * sourceRowPitch + srcOffset;
     79        uint8_t *destRow         = destData + writeRow * destRowPitch + destOffset;
     80        memcpy(destRow, sourceRow, copySize);
     81    }
     82 }
     83 
     84 void StretchedBlitNearest_PixelByPixel(const gl::Box &sourceArea,
     85                                       const gl::Box &destArea,
     86                                       const gl::Rectangle &clippedDestArea,
     87                                       const gl::Extents &sourceSize,
     88                                       unsigned int sourceRowPitch,
     89                                       unsigned int destRowPitch,
     90                                       ptrdiff_t readOffset,
     91                                       ptrdiff_t writeOffset,
     92                                       size_t copySize,
     93                                       size_t srcPixelStride,
     94                                       size_t destPixelStride,
     95                                       const uint8_t *sourceData,
     96                                       uint8_t *destData)
     97 {
     98    auto xMax = clippedDestArea.x + clippedDestArea.width;
     99    auto yMax = clippedDestArea.y + clippedDestArea.height;
    100 
    101    for (int writeRow = clippedDestArea.y; writeRow < yMax; writeRow++)
    102    {
    103        // Interpolate using the original source rectangle to determine which row to sample from
    104        // while clamping to the edges
    105        float yPerc    = static_cast<float>(writeRow - destArea.y) / (destArea.height - 1);
    106        float yRounded = floor(yPerc * (sourceArea.height - 1) + 0.5f);
    107        unsigned int readRow =
    108            static_cast<unsigned int>(gl::clamp(sourceArea.y + yRounded, 0, sourceSize.height - 1));
    109 
    110        for (int writeColumn = clippedDestArea.x; writeColumn < xMax; writeColumn++)
    111        {
    112            // Interpolate the original source rectangle to determine which column to sample
    113            // from while clamping to the edges
    114            float xPerc    = static_cast<float>(writeColumn - destArea.x) / (destArea.width - 1);
    115            float xRounded = floor(xPerc * (sourceArea.width - 1) + 0.5f);
    116            unsigned int readColumn = static_cast<unsigned int>(
    117                gl::clamp(sourceArea.x + xRounded, 0, sourceSize.width - 1));
    118 
    119            const uint8_t *sourcePixel =
    120                sourceData + readRow * sourceRowPitch + readColumn * srcPixelStride + readOffset;
    121 
    122            uint8_t *destPixel =
    123                destData + writeRow * destRowPitch + writeColumn * destPixelStride + writeOffset;
    124 
    125            memcpy(destPixel, sourcePixel, copySize);
    126        }
    127    }
    128 }
    129 
    130 void StretchedBlitNearest(const gl::Box &sourceArea,
    131                          const gl::Box &destArea,
    132                          const gl::Rectangle &clipRect,
    133                          const gl::Extents &sourceSize,
    134                          unsigned int sourceRowPitch,
    135                          unsigned int destRowPitch,
    136                          ptrdiff_t readOffset,
    137                          ptrdiff_t writeOffset,
    138                          size_t copySize,
    139                          size_t srcPixelStride,
    140                          size_t destPixelStride,
    141                          const uint8_t *sourceData,
    142                          uint8_t *destData)
    143 {
    144    gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height);
    145    if (!gl::ClipRectangle(clippedDestArea, clipRect, &clippedDestArea))
    146    {
    147        return;
    148    }
    149 
    150    // Determine if entire rows can be copied at once instead of each individual pixel. There
    151    // must be no out of bounds lookups, whole rows copies, and no scale.
    152    if (sourceArea.width == clippedDestArea.width && sourceArea.x >= 0 &&
    153        sourceArea.x + sourceArea.width <= sourceSize.width && copySize == srcPixelStride &&
    154        copySize == destPixelStride)
    155    {
    156        StretchedBlitNearest_RowByRow(sourceArea, destArea, clippedDestArea, sourceSize,
    157                                      sourceRowPitch, destRowPitch, srcPixelStride, sourceData,
    158                                      destData);
    159    }
    160    else
    161    {
    162        StretchedBlitNearest_PixelByPixel(sourceArea, destArea, clippedDestArea, sourceSize,
    163                                          sourceRowPitch, destRowPitch, readOffset, writeOffset,
    164                                          copySize, srcPixelStride, destPixelStride, sourceData,
    165                                          destData);
    166    }
    167 }
    168 
    169 using DepthStencilLoader = void(const float *, uint8_t *);
    170 
    171 void LoadDepth16(const float *source, uint8_t *dest)
    172 {
    173    uint32_t convertedDepth = gl::floatToNormalized<16, uint32_t>(source[0]);
    174    memcpy(dest, &convertedDepth, 2u);
    175 }
    176 
    177 void LoadDepth24(const float *source, uint8_t *dest)
    178 {
    179    uint32_t convertedDepth = gl::floatToNormalized<24, uint32_t>(source[0]);
    180    memcpy(dest, &convertedDepth, 3u);
    181 }
    182 
    183 void LoadStencilHelper(const float *source, uint8_t *dest)
    184 {
    185    uint32_t convertedStencil = gl::getShiftedData<8, 0>(static_cast<uint32_t>(source[1]));
    186    memcpy(dest, &convertedStencil, 1u);
    187 }
    188 
    189 void LoadStencil8(const float *source, uint8_t *dest)
    190 {
    191    // STENCIL_INDEX8 is implemented with D24S8, with the depth bits unused. Writes zero for safety.
    192    float zero = 0.0f;
    193    LoadDepth24(&zero, &dest[0]);
    194    LoadStencilHelper(source, &dest[3]);
    195 }
    196 
    197 void LoadDepth24Stencil8(const float *source, uint8_t *dest)
    198 {
    199    LoadDepth24(source, &dest[0]);
    200    LoadStencilHelper(source, &dest[3]);
    201 }
    202 
    203 void LoadDepth32F(const float *source, uint8_t *dest)
    204 {
    205    memcpy(dest, source, sizeof(float));
    206 }
    207 
    208 void LoadDepth32FStencil8(const float *source, uint8_t *dest)
    209 {
    210    LoadDepth32F(source, &dest[0]);
    211    LoadStencilHelper(source, &dest[4]);
    212 }
    213 
    214 template <DepthStencilLoader loader>
    215 void CopyDepthStencil(const gl::Box &sourceArea,
    216                      const gl::Box &destArea,
    217                      const gl::Rectangle &clippedDestArea,
    218                      const gl::Extents &sourceSize,
    219                      unsigned int sourceRowPitch,
    220                      unsigned int destRowPitch,
    221                      ptrdiff_t readOffset,
    222                      ptrdiff_t writeOffset,
    223                      size_t copySize,
    224                      size_t srcPixelStride,
    225                      size_t destPixelStride,
    226                      const uint8_t *sourceData,
    227                      uint8_t *destData)
    228 {
    229    // No stretching or subregions are supported, only full blits.
    230    ASSERT(sourceArea == destArea);
    231    ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height &&
    232           sourceSize.depth == 1);
    233    ASSERT(clippedDestArea.width == sourceSize.width &&
    234           clippedDestArea.height == sourceSize.height);
    235    ASSERT(readOffset == 0 && writeOffset == 0);
    236    ASSERT(destArea.x == 0 && destArea.y == 0);
    237 
    238    for (int row = 0; row < destArea.height; ++row)
    239    {
    240        for (int column = 0; column < destArea.width; ++column)
    241        {
    242            ptrdiff_t offset         = row * sourceRowPitch + column * srcPixelStride;
    243            const float *sourcePixel = reinterpret_cast<const float *>(sourceData + offset);
    244 
    245            uint8_t *destPixel = destData + row * destRowPitch + column * destPixelStride;
    246 
    247            loader(sourcePixel, destPixel);
    248        }
    249    }
    250 }
    251 
    252 void Depth32FStencil8ToDepth32F(const float *source, float *dest)
    253 {
    254    *dest = *source;
    255 }
    256 
    257 void Depth24Stencil8ToDepth32F(const uint32_t *source, float *dest)
    258 {
    259    uint32_t normDepth = source[0] & 0x00FFFFFF;
    260    float floatDepth   = gl::normalizedToFloat<24>(normDepth);
    261    *dest              = floatDepth;
    262 }
    263 
    264 void BlitD24S8ToD32F(const gl::Box &sourceArea,
    265                     const gl::Box &destArea,
    266                     const gl::Rectangle &clippedDestArea,
    267                     const gl::Extents &sourceSize,
    268                     unsigned int sourceRowPitch,
    269                     unsigned int destRowPitch,
    270                     ptrdiff_t readOffset,
    271                     ptrdiff_t writeOffset,
    272                     size_t copySize,
    273                     size_t srcPixelStride,
    274                     size_t destPixelStride,
    275                     const uint8_t *sourceData,
    276                     uint8_t *destData)
    277 {
    278    // No stretching or subregions are supported, only full blits.
    279    ASSERT(sourceArea == destArea);
    280    ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height &&
    281           sourceSize.depth == 1);
    282    ASSERT(clippedDestArea.width == sourceSize.width &&
    283           clippedDestArea.height == sourceSize.height);
    284    ASSERT(readOffset == 0 && writeOffset == 0);
    285    ASSERT(destArea.x == 0 && destArea.y == 0);
    286 
    287    for (int row = 0; row < destArea.height; ++row)
    288    {
    289        for (int column = 0; column < destArea.width; ++column)
    290        {
    291            ptrdiff_t offset            = row * sourceRowPitch + column * srcPixelStride;
    292            const uint32_t *sourcePixel = reinterpret_cast<const uint32_t *>(sourceData + offset);
    293 
    294            float *destPixel =
    295                reinterpret_cast<float *>(destData + row * destRowPitch + column * destPixelStride);
    296 
    297            Depth24Stencil8ToDepth32F(sourcePixel, destPixel);
    298        }
    299    }
    300 }
    301 
    302 void BlitD32FS8ToD32F(const gl::Box &sourceArea,
    303                      const gl::Box &destArea,
    304                      const gl::Rectangle &clippedDestArea,
    305                      const gl::Extents &sourceSize,
    306                      unsigned int sourceRowPitch,
    307                      unsigned int destRowPitch,
    308                      ptrdiff_t readOffset,
    309                      ptrdiff_t writeOffset,
    310                      size_t copySize,
    311                      size_t srcPixelStride,
    312                      size_t destPixelStride,
    313                      const uint8_t *sourceData,
    314                      uint8_t *destData)
    315 {
    316    // No stretching or subregions are supported, only full blits.
    317    ASSERT(sourceArea == destArea);
    318    ASSERT(sourceSize.width == sourceArea.width && sourceSize.height == sourceArea.height &&
    319           sourceSize.depth == 1);
    320    ASSERT(clippedDestArea.width == sourceSize.width &&
    321           clippedDestArea.height == sourceSize.height);
    322    ASSERT(readOffset == 0 && writeOffset == 0);
    323    ASSERT(destArea.x == 0 && destArea.y == 0);
    324 
    325    for (int row = 0; row < destArea.height; ++row)
    326    {
    327        for (int column = 0; column < destArea.width; ++column)
    328        {
    329            ptrdiff_t offset         = row * sourceRowPitch + column * srcPixelStride;
    330            const float *sourcePixel = reinterpret_cast<const float *>(sourceData + offset);
    331            float *destPixel =
    332                reinterpret_cast<float *>(destData + row * destRowPitch + column * destPixelStride);
    333 
    334            Depth32FStencil8ToDepth32F(sourcePixel, destPixel);
    335        }
    336    }
    337 }
    338 
    339 Blit11::BlitConvertFunction *GetCopyDepthStencilFunction(GLenum internalFormat)
    340 {
    341    switch (internalFormat)
    342    {
    343        case GL_DEPTH_COMPONENT16:
    344            return &CopyDepthStencil<LoadDepth16>;
    345        case GL_DEPTH_COMPONENT24:
    346            return &CopyDepthStencil<LoadDepth24>;
    347        case GL_DEPTH_COMPONENT32F:
    348            return &CopyDepthStencil<LoadDepth32F>;
    349        case GL_STENCIL_INDEX8:
    350            return &CopyDepthStencil<LoadStencil8>;
    351        case GL_DEPTH24_STENCIL8:
    352            return &CopyDepthStencil<LoadDepth24Stencil8>;
    353        case GL_DEPTH32F_STENCIL8:
    354            return &CopyDepthStencil<LoadDepth32FStencil8>;
    355        default:
    356            UNREACHABLE();
    357            return nullptr;
    358    }
    359 }
    360 
    361 inline void GenerateVertexCoords(const gl::Box &sourceArea,
    362                                 const gl::Extents &sourceSize,
    363                                 const gl::Box &destArea,
    364                                 const gl::Extents &destSize,
    365                                 float *x1,
    366                                 float *y1,
    367                                 float *x2,
    368                                 float *y2,
    369                                 float *u1,
    370                                 float *v1,
    371                                 float *u2,
    372                                 float *v2)
    373 {
    374    *x1 = (destArea.x / float(destSize.width)) * 2.0f - 1.0f;
    375    *y1 = ((destSize.height - destArea.y - destArea.height) / float(destSize.height)) * 2.0f - 1.0f;
    376    *x2 = ((destArea.x + destArea.width) / float(destSize.width)) * 2.0f - 1.0f;
    377    *y2 = ((destSize.height - destArea.y) / float(destSize.height)) * 2.0f - 1.0f;
    378 
    379    *u1 = sourceArea.x / float(sourceSize.width);
    380    *v1 = sourceArea.y / float(sourceSize.height);
    381    *u2 = (sourceArea.x + sourceArea.width) / float(sourceSize.width);
    382    *v2 = (sourceArea.y + sourceArea.height) / float(sourceSize.height);
    383 }
    384 
    385 void Write2DVertices(const gl::Box &sourceArea,
    386                     const gl::Extents &sourceSize,
    387                     const gl::Box &destArea,
    388                     const gl::Extents &destSize,
    389                     void *outVertices,
    390                     unsigned int *outStride,
    391                     unsigned int *outVertexCount,
    392                     D3D11_PRIMITIVE_TOPOLOGY *outTopology)
    393 {
    394    float x1, y1, x2, y2, u1, v1, u2, v2;
    395    GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1,
    396                         &u2, &v2);
    397 
    398    d3d11::PositionTexCoordVertex *vertices =
    399        static_cast<d3d11::PositionTexCoordVertex *>(outVertices);
    400 
    401    d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2);
    402    d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1);
    403    d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2);
    404    d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1);
    405 
    406    *outStride      = sizeof(d3d11::PositionTexCoordVertex);
    407    *outVertexCount = 4;
    408    *outTopology    = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
    409 }
    410 
    411 void Write3DVertices(const gl::Box &sourceArea,
    412                     const gl::Extents &sourceSize,
    413                     const gl::Box &destArea,
    414                     const gl::Extents &destSize,
    415                     void *outVertices,
    416                     unsigned int *outStride,
    417                     unsigned int *outVertexCount,
    418                     D3D11_PRIMITIVE_TOPOLOGY *outTopology)
    419 {
    420    ASSERT(sourceSize.depth > 0 && destSize.depth > 0);
    421 
    422    float x1, y1, x2, y2, u1, v1, u2, v2;
    423    GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1,
    424                         &u2, &v2);
    425 
    426    d3d11::PositionLayerTexCoord3DVertex *vertices =
    427        static_cast<d3d11::PositionLayerTexCoord3DVertex *>(outVertices);
    428 
    429    for (int i = 0; i < destSize.depth; i++)
    430    {
    431        float readDepth = (float)i / std::max(destSize.depth - 1, 1);
    432 
    433        d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 0], x1, y1, i, u1, v2, readDepth);
    434        d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 1], x1, y2, i, u1, v1, readDepth);
    435        d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 2], x2, y1, i, u2, v2, readDepth);
    436 
    437        d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 3], x1, y2, i, u1, v1, readDepth);
    438        d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 4], x2, y2, i, u2, v1, readDepth);
    439        d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 5], x2, y1, i, u2, v2, readDepth);
    440    }
    441 
    442    *outStride      = sizeof(d3d11::PositionLayerTexCoord3DVertex);
    443    *outVertexCount = destSize.depth * 6;
    444    *outTopology    = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
    445 }
    446 
    447 unsigned int GetSwizzleIndex(GLenum swizzle)
    448 {
    449    unsigned int colorIndex = 0;
    450 
    451    switch (swizzle)
    452    {
    453        case GL_RED:
    454            colorIndex = 0;
    455            break;
    456        case GL_GREEN:
    457            colorIndex = 1;
    458            break;
    459        case GL_BLUE:
    460            colorIndex = 2;
    461            break;
    462        case GL_ALPHA:
    463            colorIndex = 3;
    464            break;
    465        case GL_ZERO:
    466            colorIndex = 4;
    467            break;
    468        case GL_ONE:
    469            colorIndex = 5;
    470            break;
    471        default:
    472            UNREACHABLE();
    473            break;
    474    }
    475 
    476    return colorIndex;
    477 }
    478 
    479 D3D11_BLEND_DESC GetAlphaMaskBlendStateDesc()
    480 {
    481    D3D11_BLEND_DESC desc;
    482    memset(&desc, 0, sizeof(desc));
    483    desc.RenderTarget[0].BlendEnable           = TRUE;
    484    desc.RenderTarget[0].SrcBlend              = D3D11_BLEND_ONE;
    485    desc.RenderTarget[0].DestBlend             = D3D11_BLEND_ZERO;
    486    desc.RenderTarget[0].BlendOp               = D3D11_BLEND_OP_ADD;
    487    desc.RenderTarget[0].SrcBlendAlpha         = D3D11_BLEND_ZERO;
    488    desc.RenderTarget[0].DestBlendAlpha        = D3D11_BLEND_ZERO;
    489    desc.RenderTarget[0].BlendOpAlpha          = D3D11_BLEND_OP_ADD;
    490    desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_RED |
    491                                                 D3D11_COLOR_WRITE_ENABLE_GREEN |
    492                                                 D3D11_COLOR_WRITE_ENABLE_BLUE;
    493    return desc;
    494 }
    495 
    496 D3D11_INPUT_ELEMENT_DESC quad2DLayout[] = {
    497    {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
    498    {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0},
    499 };
    500 
    501 D3D11_INPUT_ELEMENT_DESC quad3DLayout[] = {
    502    {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
    503    {"LAYER", 0, DXGI_FORMAT_R32_UINT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0},
    504    {"TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
    505 };
    506 
    507 DXGI_FORMAT GetStencilSRVFormat(const d3d11::Format &formatSet)
    508 {
    509    switch (formatSet.texFormat)
    510    {
    511        case DXGI_FORMAT_R32G8X24_TYPELESS:
    512            return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
    513        case DXGI_FORMAT_R24G8_TYPELESS:
    514            return DXGI_FORMAT_X24_TYPELESS_G8_UINT;
    515        default:
    516            UNREACHABLE();
    517            return DXGI_FORMAT_UNKNOWN;
    518    }
    519 }
    520 
    521 }  // namespace
    522 
    523 #include "libANGLE/renderer/d3d/d3d11/Blit11Helper_autogen.inc"
    524 
    525 Blit11::Shader::Shader() = default;
    526 
    527 Blit11::Shader::Shader(Shader &&other) = default;
    528 
    529 Blit11::Shader::~Shader() = default;
    530 
    531 Blit11::Shader &Blit11::Shader::operator=(Blit11::Shader &&other) = default;
    532 
    533 Blit11::Blit11(Renderer11 *renderer)
    534    : mRenderer(renderer),
    535      mResourcesInitialized(false),
    536      mVertexBuffer(),
    537      mPointSampler(),
    538      mLinearSampler(),
    539      mScissorEnabledRasterizerState(),
    540      mScissorDisabledRasterizerState(),
    541      mDepthStencilState(),
    542      mQuad2DIL(quad2DLayout,
    543                ArraySize(quad2DLayout),
    544                g_VS_Passthrough2D,
    545                ArraySize(g_VS_Passthrough2D),
    546                "Blit11 2D input layout"),
    547      mQuad2DVS(g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), "Blit11 2D vertex shader"),
    548      mDepthPS(g_PS_PassthroughDepth2D,
    549               ArraySize(g_PS_PassthroughDepth2D),
    550               "Blit11 2D depth pixel shader"),
    551      mQuad3DIL(quad3DLayout,
    552                ArraySize(quad3DLayout),
    553                g_VS_Passthrough3D,
    554                ArraySize(g_VS_Passthrough3D),
    555                "Blit11 3D input layout"),
    556      mQuad3DVS(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), "Blit11 3D vertex shader"),
    557      mQuad3DGS(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), "Blit11 3D geometry shader"),
    558      mAlphaMaskBlendState(GetAlphaMaskBlendStateDesc(), "Blit11 Alpha Mask Blend"),
    559      mSwizzleCB(),
    560      mResolveDepthStencilVS(g_VS_ResolveDepthStencil,
    561                             ArraySize(g_VS_ResolveDepthStencil),
    562                             "Blit11::mResolveDepthStencilVS"),
    563      mResolveDepthPS(g_PS_ResolveDepth, ArraySize(g_PS_ResolveDepth), "Blit11::mResolveDepthPS"),
    564      mResolveDepthStencilPS(g_PS_ResolveDepthStencil,
    565                             ArraySize(g_PS_ResolveDepthStencil),
    566                             "Blit11::mResolveDepthStencilPS"),
    567      mResolveStencilPS(g_PS_ResolveStencil,
    568                        ArraySize(g_PS_ResolveStencil),
    569                        "Blit11::mResolveStencilPS"),
    570      mStencilSRV(),
    571      mResolvedDepthStencilRTView()
    572 {}
    573 
    574 Blit11::~Blit11() {}
    575 
    576 angle::Result Blit11::initResources(const gl::Context *context)
    577 {
    578    if (mResourcesInitialized)
    579    {
    580        return angle::Result::Continue;
    581    }
    582 
    583    ANGLE_TRACE_EVENT0("gpu.angle", "Blit11::initResources");
    584 
    585    D3D11_BUFFER_DESC vbDesc;
    586    vbDesc.ByteWidth =
    587        static_cast<unsigned int>(std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex),
    588                                           sizeof(d3d11::PositionTexCoordVertex)) *
    589                                  6 * mRenderer->getNativeCaps().max3DTextureSize);
    590    vbDesc.Usage               = D3D11_USAGE_DYNAMIC;
    591    vbDesc.BindFlags           = D3D11_BIND_VERTEX_BUFFER;
    592    vbDesc.CPUAccessFlags      = D3D11_CPU_ACCESS_WRITE;
    593    vbDesc.MiscFlags           = 0;
    594    vbDesc.StructureByteStride = 0;
    595 
    596    Context11 *context11 = GetImplAs<Context11>(context);
    597 
    598    ANGLE_TRY(mRenderer->allocateResource(context11, vbDesc, &mVertexBuffer));
    599    mVertexBuffer.setInternalName("Blit11VertexBuffer");
    600 
    601    D3D11_SAMPLER_DESC pointSamplerDesc;
    602    pointSamplerDesc.Filter         = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
    603    pointSamplerDesc.AddressU       = D3D11_TEXTURE_ADDRESS_CLAMP;
    604    pointSamplerDesc.AddressV       = D3D11_TEXTURE_ADDRESS_CLAMP;
    605    pointSamplerDesc.AddressW       = D3D11_TEXTURE_ADDRESS_CLAMP;
    606    pointSamplerDesc.MipLODBias     = 0.0f;
    607    pointSamplerDesc.MaxAnisotropy  = 0;
    608    pointSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
    609    pointSamplerDesc.BorderColor[0] = 0.0f;
    610    pointSamplerDesc.BorderColor[1] = 0.0f;
    611    pointSamplerDesc.BorderColor[2] = 0.0f;
    612    pointSamplerDesc.BorderColor[3] = 0.0f;
    613    pointSamplerDesc.MinLOD         = 0.0f;
    614    pointSamplerDesc.MaxLOD         = FLT_MAX;
    615 
    616    ANGLE_TRY(mRenderer->allocateResource(context11, pointSamplerDesc, &mPointSampler));
    617    mPointSampler.setInternalName("Blit11PointSampler");
    618 
    619    D3D11_SAMPLER_DESC linearSamplerDesc;
    620    linearSamplerDesc.Filter         = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    621    linearSamplerDesc.AddressU       = D3D11_TEXTURE_ADDRESS_CLAMP;
    622    linearSamplerDesc.AddressV       = D3D11_TEXTURE_ADDRESS_CLAMP;
    623    linearSamplerDesc.AddressW       = D3D11_TEXTURE_ADDRESS_CLAMP;
    624    linearSamplerDesc.MipLODBias     = 0.0f;
    625    linearSamplerDesc.MaxAnisotropy  = 0;
    626    linearSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
    627    linearSamplerDesc.BorderColor[0] = 0.0f;
    628    linearSamplerDesc.BorderColor[1] = 0.0f;
    629    linearSamplerDesc.BorderColor[2] = 0.0f;
    630    linearSamplerDesc.BorderColor[3] = 0.0f;
    631    linearSamplerDesc.MinLOD         = 0.0f;
    632    linearSamplerDesc.MaxLOD         = FLT_MAX;
    633 
    634    ANGLE_TRY(mRenderer->allocateResource(context11, linearSamplerDesc, &mLinearSampler));
    635    mLinearSampler.setInternalName("Blit11LinearSampler");
    636 
    637    // Use a rasterizer state that will not cull so that inverted quads will not be culled
    638    D3D11_RASTERIZER_DESC rasterDesc;
    639    rasterDesc.FillMode              = D3D11_FILL_SOLID;
    640    rasterDesc.CullMode              = D3D11_CULL_NONE;
    641    rasterDesc.FrontCounterClockwise = FALSE;
    642    rasterDesc.DepthBias             = 0;
    643    rasterDesc.SlopeScaledDepthBias  = 0.0f;
    644    rasterDesc.DepthBiasClamp        = 0.0f;
    645    rasterDesc.DepthClipEnable       = TRUE;
    646    rasterDesc.MultisampleEnable     = FALSE;
    647    rasterDesc.AntialiasedLineEnable = FALSE;
    648 
    649    rasterDesc.ScissorEnable = TRUE;
    650    ANGLE_TRY(mRenderer->allocateResource(context11, rasterDesc, &mScissorEnabledRasterizerState));
    651    mScissorEnabledRasterizerState.setInternalName("Blit11ScissoringRasterizerState");
    652 
    653    rasterDesc.ScissorEnable = FALSE;
    654    ANGLE_TRY(mRenderer->allocateResource(context11, rasterDesc, &mScissorDisabledRasterizerState));
    655    mScissorDisabledRasterizerState.setInternalName("Blit11NoScissoringRasterizerState");
    656 
    657    D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
    658    depthStencilDesc.DepthEnable                  = TRUE;
    659    depthStencilDesc.DepthWriteMask               = D3D11_DEPTH_WRITE_MASK_ALL;
    660    depthStencilDesc.DepthFunc                    = D3D11_COMPARISON_ALWAYS;
    661    depthStencilDesc.StencilEnable                = FALSE;
    662    depthStencilDesc.StencilReadMask              = D3D11_DEFAULT_STENCIL_READ_MASK;
    663    depthStencilDesc.StencilWriteMask             = D3D11_DEFAULT_STENCIL_WRITE_MASK;
    664    depthStencilDesc.FrontFace.StencilFailOp      = D3D11_STENCIL_OP_KEEP;
    665    depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
    666    depthStencilDesc.FrontFace.StencilPassOp      = D3D11_STENCIL_OP_KEEP;
    667    depthStencilDesc.FrontFace.StencilFunc        = D3D11_COMPARISON_ALWAYS;
    668    depthStencilDesc.BackFace.StencilFailOp       = D3D11_STENCIL_OP_KEEP;
    669    depthStencilDesc.BackFace.StencilDepthFailOp  = D3D11_STENCIL_OP_KEEP;
    670    depthStencilDesc.BackFace.StencilPassOp       = D3D11_STENCIL_OP_KEEP;
    671    depthStencilDesc.BackFace.StencilFunc         = D3D11_COMPARISON_ALWAYS;
    672 
    673    ANGLE_TRY(mRenderer->allocateResource(context11, depthStencilDesc, &mDepthStencilState));
    674    mDepthStencilState.setInternalName("Blit11DepthStencilState");
    675 
    676    D3D11_BUFFER_DESC swizzleBufferDesc;
    677    swizzleBufferDesc.ByteWidth           = sizeof(unsigned int) * 4;
    678    swizzleBufferDesc.Usage               = D3D11_USAGE_DYNAMIC;
    679    swizzleBufferDesc.BindFlags           = D3D11_BIND_CONSTANT_BUFFER;
    680    swizzleBufferDesc.CPUAccessFlags      = D3D11_CPU_ACCESS_WRITE;
    681    swizzleBufferDesc.MiscFlags           = 0;
    682    swizzleBufferDesc.StructureByteStride = 0;
    683 
    684    ANGLE_TRY(mRenderer->allocateResource(context11, swizzleBufferDesc, &mSwizzleCB));
    685    mSwizzleCB.setInternalName("Blit11SwizzleConstantBuffer");
    686 
    687    mResourcesInitialized = true;
    688 
    689    return angle::Result::Continue;
    690 }
    691 
    692 // static
    693 Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type,
    694                                                       D3D11_SRV_DIMENSION dimensionality)
    695 {
    696    switch (dimensionality)
    697    {
    698        case D3D11_SRV_DIMENSION_TEXTURE2D:
    699            switch (type)
    700            {
    701                case GL_FLOAT:
    702                    return SWIZZLESHADER_2D_FLOAT;
    703                case GL_UNSIGNED_INT:
    704                    return SWIZZLESHADER_2D_UINT;
    705                case GL_INT:
    706                    return SWIZZLESHADER_2D_INT;
    707                default:
    708                    UNREACHABLE();
    709                    return SWIZZLESHADER_INVALID;
    710            }
    711        case D3D11_SRV_DIMENSION_TEXTURECUBE:
    712            switch (type)
    713            {
    714                case GL_FLOAT:
    715                    return SWIZZLESHADER_CUBE_FLOAT;
    716                case GL_UNSIGNED_INT:
    717                    return SWIZZLESHADER_CUBE_UINT;
    718                case GL_INT:
    719                    return SWIZZLESHADER_CUBE_INT;
    720                default:
    721                    UNREACHABLE();
    722                    return SWIZZLESHADER_INVALID;
    723            }
    724        case D3D11_SRV_DIMENSION_TEXTURE3D:
    725            switch (type)
    726            {
    727                case GL_FLOAT:
    728                    return SWIZZLESHADER_3D_FLOAT;
    729                case GL_UNSIGNED_INT:
    730                    return SWIZZLESHADER_3D_UINT;
    731                case GL_INT:
    732                    return SWIZZLESHADER_3D_INT;
    733                default:
    734                    UNREACHABLE();
    735                    return SWIZZLESHADER_INVALID;
    736            }
    737        case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
    738            switch (type)
    739            {
    740                case GL_FLOAT:
    741                    return SWIZZLESHADER_ARRAY_FLOAT;
    742                case GL_UNSIGNED_INT:
    743                    return SWIZZLESHADER_ARRAY_UINT;
    744                case GL_INT:
    745                    return SWIZZLESHADER_ARRAY_INT;
    746                default:
    747                    UNREACHABLE();
    748                    return SWIZZLESHADER_INVALID;
    749            }
    750        default:
    751            UNREACHABLE();
    752            return SWIZZLESHADER_INVALID;
    753    }
    754 }
    755 
    756 angle::Result Blit11::getShaderSupport(const gl::Context *context,
    757                                       const Shader &shader,
    758                                       Blit11::ShaderSupport *supportOut)
    759 {
    760 
    761    Context11 *context11 = GetImplAs<Context11>(context);
    762 
    763    switch (shader.dimension)
    764    {
    765        case SHADER_2D:
    766        {
    767            ANGLE_TRY(mQuad2DIL.resolve(context11, mRenderer));
    768            ANGLE_TRY(mQuad2DVS.resolve(context11, mRenderer));
    769            supportOut->inputLayout         = &mQuad2DIL.getObj();
    770            supportOut->vertexShader        = &mQuad2DVS.getObj();
    771            supportOut->geometryShader      = nullptr;
    772            supportOut->vertexWriteFunction = Write2DVertices;
    773            break;
    774        }
    775        case SHADER_3D:
    776        case SHADER_2DARRAY:
    777        {
    778            ANGLE_TRY(mQuad3DIL.resolve(context11, mRenderer));
    779            ANGLE_TRY(mQuad3DVS.resolve(context11, mRenderer));
    780            ANGLE_TRY(mQuad3DGS.resolve(context11, mRenderer));
    781            supportOut->inputLayout         = &mQuad3DIL.getObj();
    782            supportOut->vertexShader        = &mQuad3DVS.getObj();
    783            supportOut->geometryShader      = &mQuad3DGS.getObj();
    784            supportOut->vertexWriteFunction = Write3DVertices;
    785            break;
    786        }
    787        default:
    788            UNREACHABLE();
    789    }
    790 
    791    return angle::Result::Continue;
    792 }
    793 
    794 angle::Result Blit11::swizzleTexture(const gl::Context *context,
    795                                     const d3d11::SharedSRV &source,
    796                                     const d3d11::RenderTargetView &dest,
    797                                     const gl::Extents &size,
    798                                     const gl::SwizzleState &swizzleTarget)
    799 {
    800    ANGLE_TRY(initResources(context));
    801 
    802    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
    803 
    804    D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc;
    805    source.get()->GetDesc(&sourceSRVDesc);
    806 
    807    GLenum componentType = d3d11::GetComponentType(sourceSRVDesc.Format);
    808    if (componentType == GL_NONE)
    809    {
    810        // We're swizzling the depth component of a depth-stencil texture.
    811        switch (sourceSRVDesc.Format)
    812        {
    813            case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
    814                componentType = GL_UNSIGNED_NORMALIZED;
    815                break;
    816            case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
    817                componentType = GL_FLOAT;
    818                break;
    819            default:
    820                UNREACHABLE();
    821                break;
    822        }
    823    }
    824 
    825    GLenum shaderType = GL_NONE;
    826    switch (componentType)
    827    {
    828        case GL_UNSIGNED_NORMALIZED:
    829        case GL_SIGNED_NORMALIZED:
    830        case GL_FLOAT:
    831            shaderType = GL_FLOAT;
    832            break;
    833        case GL_INT:
    834            shaderType = GL_INT;
    835            break;
    836        case GL_UNSIGNED_INT:
    837            shaderType = GL_UNSIGNED_INT;
    838            break;
    839        default:
    840            UNREACHABLE();
    841            break;
    842    }
    843 
    844    const Shader *shader = nullptr;
    845    ANGLE_TRY(getSwizzleShader(context, shaderType, sourceSRVDesc.ViewDimension, &shader));
    846 
    847    // Set vertices
    848    D3D11_MAPPED_SUBRESOURCE mappedResource;
    849    ANGLE_TRY(mRenderer->mapResource(context, mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
    850                                     &mappedResource));
    851 
    852    ShaderSupport support;
    853    ANGLE_TRY(getShaderSupport(context, *shader, &support));
    854 
    855    UINT stride    = 0;
    856    UINT drawCount = 0;
    857    D3D11_PRIMITIVE_TOPOLOGY topology;
    858 
    859    gl::Box area(0, 0, 0, size.width, size.height, size.depth);
    860    support.vertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount,
    861                                &topology);
    862 
    863    deviceContext->Unmap(mVertexBuffer.get(), 0);
    864 
    865    // Set constant buffer
    866    ANGLE_TRY(mRenderer->mapResource(context, mSwizzleCB.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
    867                                     &mappedResource));
    868 
    869    unsigned int *swizzleIndices = static_cast<unsigned int *>(mappedResource.pData);
    870    swizzleIndices[0]            = GetSwizzleIndex(swizzleTarget.swizzleRed);
    871    swizzleIndices[1]            = GetSwizzleIndex(swizzleTarget.swizzleGreen);
    872    swizzleIndices[2]            = GetSwizzleIndex(swizzleTarget.swizzleBlue);
    873    swizzleIndices[3]            = GetSwizzleIndex(swizzleTarget.swizzleAlpha);
    874 
    875    deviceContext->Unmap(mSwizzleCB.get(), 0);
    876 
    877    StateManager11 *stateManager = mRenderer->getStateManager();
    878 
    879    // Apply vertex buffer
    880    stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
    881 
    882    // Apply constant buffer
    883    stateManager->setPixelConstantBuffer(0, &mSwizzleCB);
    884 
    885    // Apply state
    886    stateManager->setSimpleBlendState(nullptr);
    887    stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF);
    888    stateManager->setRasterizerState(&mScissorDisabledRasterizerState);
    889 
    890    // Apply shaders
    891    stateManager->setInputLayout(support.inputLayout);
    892    stateManager->setPrimitiveTopology(topology);
    893 
    894    stateManager->setDrawShaders(support.vertexShader, support.geometryShader,
    895                                 &shader->pixelShader);
    896 
    897    // Apply render target
    898    stateManager->setRenderTarget(dest.get(), nullptr);
    899 
    900    // Set the viewport
    901    stateManager->setSimpleViewport(size);
    902 
    903    // Apply textures and sampler
    904    stateManager->setSimplePixelTextureAndSampler(source, mPointSampler);
    905 
    906    // Draw the quad
    907    deviceContext->Draw(drawCount, 0);
    908 
    909    return angle::Result::Continue;
    910 }
    911 
    912 angle::Result Blit11::copyTexture(const gl::Context *context,
    913                                  const d3d11::SharedSRV &source,
    914                                  const gl::Box &sourceArea,
    915                                  const gl::Extents &sourceSize,
    916                                  GLenum sourceFormat,
    917                                  const d3d11::RenderTargetView &dest,
    918                                  const gl::Box &destArea,
    919                                  const gl::Extents &destSize,
    920                                  const gl::Rectangle *scissor,
    921                                  GLenum destFormat,
    922                                  GLenum destTypeForDownsampling,
    923                                  GLenum filter,
    924                                  bool maskOffAlpha,
    925                                  bool unpackPremultiplyAlpha,
    926                                  bool unpackUnmultiplyAlpha)
    927 {
    928    ANGLE_TRY(initResources(context));
    929 
    930    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
    931 
    932    // Determine if the source format is a signed integer format, the destFormat will already
    933    // be GL_XXXX_INTEGER but it does not tell us if it is signed or unsigned.
    934    D3D11_SHADER_RESOURCE_VIEW_DESC sourceSRVDesc;
    935    source.get()->GetDesc(&sourceSRVDesc);
    936 
    937    GLenum componentType = d3d11::GetComponentType(sourceSRVDesc.Format);
    938 
    939    ASSERT(componentType != GL_NONE);
    940    ASSERT(componentType != GL_SIGNED_NORMALIZED);
    941    bool isSrcSigned = (componentType == GL_INT);
    942 
    943    D3D11_RENDER_TARGET_VIEW_DESC destRTVDesc;
    944    dest.get()->GetDesc(&destRTVDesc);
    945 
    946    GLenum destComponentType = d3d11::GetComponentType(destRTVDesc.Format);
    947 
    948    ASSERT(componentType != GL_NONE);
    949    bool isDestSigned = (destComponentType == GL_INT);
    950 
    951    ShaderDimension dimension = SHADER_INVALID;
    952 
    953    switch (sourceSRVDesc.ViewDimension)
    954    {
    955        case D3D11_SRV_DIMENSION_TEXTURE2D:
    956            dimension = SHADER_2D;
    957            break;
    958        case D3D11_SRV_DIMENSION_TEXTURE3D:
    959            dimension = SHADER_3D;
    960            break;
    961        case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
    962            dimension = SHADER_2DARRAY;
    963            break;
    964        default:
    965            UNREACHABLE();
    966    }
    967 
    968    const Shader *shader = nullptr;
    969 
    970    ANGLE_TRY(getBlitShader(context, destFormat, sourceFormat, isSrcSigned, isDestSigned,
    971                            unpackPremultiplyAlpha, unpackUnmultiplyAlpha, destTypeForDownsampling,
    972                            dimension, &shader));
    973 
    974    ShaderSupport support;
    975    ANGLE_TRY(getShaderSupport(context, *shader, &support));
    976 
    977    // Set vertices
    978    D3D11_MAPPED_SUBRESOURCE mappedResource;
    979    ANGLE_TRY(mRenderer->mapResource(context, mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
    980                                     &mappedResource));
    981 
    982    UINT stride    = 0;
    983    UINT drawCount = 0;
    984    D3D11_PRIMITIVE_TOPOLOGY topology;
    985 
    986    support.vertexWriteFunction(sourceArea, sourceSize, destArea, destSize, mappedResource.pData,
    987                                &stride, &drawCount, &topology);
    988 
    989    deviceContext->Unmap(mVertexBuffer.get(), 0);
    990 
    991    StateManager11 *stateManager = mRenderer->getStateManager();
    992 
    993    // Apply vertex buffer
    994    stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
    995 
    996    // Apply state
    997    if (maskOffAlpha)
    998    {
    999        ANGLE_TRY(mAlphaMaskBlendState.resolve(GetImplAs<Context11>(context), mRenderer));
   1000        stateManager->setSimpleBlendState(&mAlphaMaskBlendState.getObj());
   1001    }
   1002    else
   1003    {
   1004        stateManager->setSimpleBlendState(nullptr);
   1005    }
   1006    stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF);
   1007 
   1008    if (scissor)
   1009    {
   1010        stateManager->setSimpleScissorRect(*scissor);
   1011        stateManager->setRasterizerState(&mScissorEnabledRasterizerState);
   1012    }
   1013    else
   1014    {
   1015        stateManager->setRasterizerState(&mScissorDisabledRasterizerState);
   1016    }
   1017 
   1018    // Apply shaders
   1019    stateManager->setInputLayout(support.inputLayout);
   1020    stateManager->setPrimitiveTopology(topology);
   1021 
   1022    stateManager->setDrawShaders(support.vertexShader, support.geometryShader,
   1023                                 &shader->pixelShader);
   1024 
   1025    // Apply render target
   1026    stateManager->setRenderTarget(dest.get(), nullptr);
   1027 
   1028    // Set the viewport
   1029    stateManager->setSimpleViewport(destSize);
   1030 
   1031    // Apply texture and sampler
   1032    switch (filter)
   1033    {
   1034        case GL_NEAREST:
   1035            stateManager->setSimplePixelTextureAndSampler(source, mPointSampler);
   1036            break;
   1037        case GL_LINEAR:
   1038            stateManager->setSimplePixelTextureAndSampler(source, mLinearSampler);
   1039            break;
   1040 
   1041        default:
   1042            UNREACHABLE();
   1043            ANGLE_TRY_HR(GetImplAs<Context11>(context), E_FAIL,
   1044                         "Internal error, unknown blit filter mode.");
   1045    }
   1046 
   1047    // Draw the quad
   1048    deviceContext->Draw(drawCount, 0);
   1049 
   1050    return angle::Result::Continue;
   1051 }
   1052 
   1053 angle::Result Blit11::copyStencil(const gl::Context *context,
   1054                                  const TextureHelper11 &source,
   1055                                  unsigned int sourceSubresource,
   1056                                  const gl::Box &sourceArea,
   1057                                  const gl::Extents &sourceSize,
   1058                                  const TextureHelper11 &dest,
   1059                                  unsigned int destSubresource,
   1060                                  const gl::Box &destArea,
   1061                                  const gl::Extents &destSize,
   1062                                  const gl::Rectangle *scissor)
   1063 {
   1064    return copyDepthStencilImpl(context, source, sourceSubresource, sourceArea, sourceSize, dest,
   1065                                destSubresource, destArea, destSize, scissor, true);
   1066 }
   1067 
   1068 angle::Result Blit11::copyDepth(const gl::Context *context,
   1069                                const d3d11::SharedSRV &source,
   1070                                const gl::Box &sourceArea,
   1071                                const gl::Extents &sourceSize,
   1072                                const d3d11::DepthStencilView &dest,
   1073                                const gl::Box &destArea,
   1074                                const gl::Extents &destSize,
   1075                                const gl::Rectangle *scissor)
   1076 {
   1077    ANGLE_TRY(initResources(context));
   1078 
   1079    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   1080 
   1081    // Set vertices
   1082    D3D11_MAPPED_SUBRESOURCE mappedResource;
   1083    ANGLE_TRY(mRenderer->mapResource(context, mVertexBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD, 0,
   1084                                     &mappedResource));
   1085 
   1086    UINT stride    = 0;
   1087    UINT drawCount = 0;
   1088    D3D11_PRIMITIVE_TOPOLOGY topology;
   1089 
   1090    Write2DVertices(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, &stride,
   1091                    &drawCount, &topology);
   1092 
   1093    deviceContext->Unmap(mVertexBuffer.get(), 0);
   1094 
   1095    StateManager11 *stateManager = mRenderer->getStateManager();
   1096 
   1097    // Apply vertex buffer
   1098    stateManager->setSingleVertexBuffer(&mVertexBuffer, stride, 0);
   1099 
   1100    // Apply state
   1101    stateManager->setSimpleBlendState(nullptr);
   1102    stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF);
   1103 
   1104    if (scissor)
   1105    {
   1106        stateManager->setSimpleScissorRect(*scissor);
   1107        stateManager->setRasterizerState(&mScissorEnabledRasterizerState);
   1108    }
   1109    else
   1110    {
   1111        stateManager->setRasterizerState(&mScissorDisabledRasterizerState);
   1112    }
   1113 
   1114    Context11 *context11 = GetImplAs<Context11>(context);
   1115 
   1116    ANGLE_TRY(mQuad2DIL.resolve(context11, mRenderer));
   1117    ANGLE_TRY(mQuad2DVS.resolve(context11, mRenderer));
   1118    ANGLE_TRY(mDepthPS.resolve(context11, mRenderer));
   1119 
   1120    // Apply shaders
   1121    stateManager->setInputLayout(&mQuad2DIL.getObj());
   1122    stateManager->setPrimitiveTopology(topology);
   1123 
   1124    stateManager->setDrawShaders(&mQuad2DVS.getObj(), nullptr, &mDepthPS.getObj());
   1125 
   1126    // Apply render target
   1127    stateManager->setRenderTarget(nullptr, dest.get());
   1128 
   1129    // Set the viewport
   1130    stateManager->setSimpleViewport(destSize);
   1131 
   1132    // Apply texture and sampler
   1133    stateManager->setSimplePixelTextureAndSampler(source, mPointSampler);
   1134 
   1135    // Draw the quad
   1136    deviceContext->Draw(drawCount, 0);
   1137 
   1138    return angle::Result::Continue;
   1139 }
   1140 
   1141 angle::Result Blit11::copyDepthStencil(const gl::Context *context,
   1142                                       const TextureHelper11 &source,
   1143                                       unsigned int sourceSubresource,
   1144                                       const gl::Box &sourceArea,
   1145                                       const gl::Extents &sourceSize,
   1146                                       const TextureHelper11 &dest,
   1147                                       unsigned int destSubresource,
   1148                                       const gl::Box &destArea,
   1149                                       const gl::Extents &destSize,
   1150                                       const gl::Rectangle *scissor)
   1151 {
   1152    return copyDepthStencilImpl(context, source, sourceSubresource, sourceArea, sourceSize, dest,
   1153                                destSubresource, destArea, destSize, scissor, false);
   1154 }
   1155 
   1156 angle::Result Blit11::copyDepthStencilImpl(const gl::Context *context,
   1157                                           const TextureHelper11 &source,
   1158                                           unsigned int sourceSubresource,
   1159                                           const gl::Box &sourceArea,
   1160                                           const gl::Extents &sourceSize,
   1161                                           const TextureHelper11 &dest,
   1162                                           unsigned int destSubresource,
   1163                                           const gl::Box &destArea,
   1164                                           const gl::Extents &destSize,
   1165                                           const gl::Rectangle *scissor,
   1166                                           bool stencilOnly)
   1167 {
   1168    auto srcDXGIFormat         = source.getFormat();
   1169    const auto &srcSizeInfo    = d3d11::GetDXGIFormatSizeInfo(srcDXGIFormat);
   1170    unsigned int srcPixelSize  = srcSizeInfo.pixelBytes;
   1171    unsigned int copyOffset    = 0;
   1172    unsigned int copySize      = srcPixelSize;
   1173    auto destDXGIFormat        = dest.getFormat();
   1174    const auto &destSizeInfo   = d3d11::GetDXGIFormatSizeInfo(destDXGIFormat);
   1175    unsigned int destPixelSize = destSizeInfo.pixelBytes;
   1176 
   1177    ASSERT(srcDXGIFormat == destDXGIFormat || destDXGIFormat == DXGI_FORMAT_R32_TYPELESS);
   1178 
   1179    if (stencilOnly)
   1180    {
   1181        const auto &srcFormat = source.getFormatSet().format();
   1182 
   1183        // Stencil channel should be right after the depth channel. Some views to depth/stencil
   1184        // resources have red channel for depth, in which case the depth channel bit width is in
   1185        // redBits.
   1186        ASSERT((srcFormat.redBits != 0) != (srcFormat.depthBits != 0));
   1187        GLuint depthBits = srcFormat.redBits + srcFormat.depthBits;
   1188        // Known formats have either 24 or 32 bits of depth.
   1189        ASSERT(depthBits == 24 || depthBits == 32);
   1190        copyOffset = depthBits / 8;
   1191 
   1192        // Stencil is assumed to be 8-bit - currently this is true for all possible formats.
   1193        copySize = 1;
   1194    }
   1195 
   1196    if (srcDXGIFormat != destDXGIFormat)
   1197    {
   1198        if (srcDXGIFormat == DXGI_FORMAT_R24G8_TYPELESS)
   1199        {
   1200            ASSERT(sourceArea == destArea && sourceSize == destSize && scissor == nullptr);
   1201            return copyAndConvert(context, source, sourceSubresource, sourceArea, sourceSize, dest,
   1202                                  destSubresource, destArea, destSize, scissor, copyOffset,
   1203                                  copyOffset, copySize, srcPixelSize, destPixelSize,
   1204                                  BlitD24S8ToD32F);
   1205        }
   1206        ASSERT(srcDXGIFormat == DXGI_FORMAT_R32G8X24_TYPELESS);
   1207        return copyAndConvert(context, source, sourceSubresource, sourceArea, sourceSize, dest,
   1208                              destSubresource, destArea, destSize, scissor, copyOffset, copyOffset,
   1209                              copySize, srcPixelSize, destPixelSize, BlitD32FS8ToD32F);
   1210    }
   1211 
   1212    return copyAndConvert(context, source, sourceSubresource, sourceArea, sourceSize, dest,
   1213                          destSubresource, destArea, destSize, scissor, copyOffset, copyOffset,
   1214                          copySize, srcPixelSize, destPixelSize, StretchedBlitNearest);
   1215 }
   1216 
   1217 angle::Result Blit11::copyAndConvertImpl(const gl::Context *context,
   1218                                         const TextureHelper11 &source,
   1219                                         unsigned int sourceSubresource,
   1220                                         const gl::Box &sourceArea,
   1221                                         const gl::Extents &sourceSize,
   1222                                         const TextureHelper11 &destStaging,
   1223                                         const gl::Box &destArea,
   1224                                         const gl::Extents &destSize,
   1225                                         const gl::Rectangle *scissor,
   1226                                         size_t readOffset,
   1227                                         size_t writeOffset,
   1228                                         size_t copySize,
   1229                                         size_t srcPixelStride,
   1230                                         size_t destPixelStride,
   1231                                         BlitConvertFunction *convertFunction)
   1232 {
   1233    ANGLE_TRY(initResources(context));
   1234 
   1235    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   1236 
   1237    TextureHelper11 sourceStaging;
   1238    ANGLE_TRY(mRenderer->createStagingTexture(context, ResourceType::Texture2D,
   1239                                              source.getFormatSet(), sourceSize,
   1240                                              StagingAccess::READ, &sourceStaging));
   1241 
   1242    deviceContext->CopySubresourceRegion(sourceStaging.get(), 0, 0, 0, 0, source.get(),
   1243                                         sourceSubresource, nullptr);
   1244 
   1245    D3D11_MAPPED_SUBRESOURCE sourceMapping;
   1246    ANGLE_TRY(
   1247        mRenderer->mapResource(context, sourceStaging.get(), 0, D3D11_MAP_READ, 0, &sourceMapping));
   1248 
   1249    D3D11_MAPPED_SUBRESOURCE destMapping;
   1250    angle::Result error =
   1251        mRenderer->mapResource(context, destStaging.get(), 0, D3D11_MAP_WRITE, 0, &destMapping);
   1252    if (error == angle::Result::Stop)
   1253    {
   1254        deviceContext->Unmap(sourceStaging.get(), 0);
   1255        return error;
   1256    }
   1257 
   1258    // Clip dest area to the destination size
   1259    gl::Rectangle clipRect = gl::Rectangle(0, 0, destSize.width, destSize.height);
   1260 
   1261    // Clip dest area to the scissor
   1262    if (scissor)
   1263    {
   1264        if (!gl::ClipRectangle(clipRect, *scissor, &clipRect))
   1265        {
   1266            return angle::Result::Continue;
   1267        }
   1268    }
   1269 
   1270    convertFunction(sourceArea, destArea, clipRect, sourceSize, sourceMapping.RowPitch,
   1271                    destMapping.RowPitch, readOffset, writeOffset, copySize, srcPixelStride,
   1272                    destPixelStride, static_cast<const uint8_t *>(sourceMapping.pData),
   1273                    static_cast<uint8_t *>(destMapping.pData));
   1274 
   1275    deviceContext->Unmap(sourceStaging.get(), 0);
   1276    deviceContext->Unmap(destStaging.get(), 0);
   1277 
   1278    return angle::Result::Continue;
   1279 }
   1280 
   1281 angle::Result Blit11::copyAndConvert(const gl::Context *context,
   1282                                     const TextureHelper11 &source,
   1283                                     unsigned int sourceSubresource,
   1284                                     const gl::Box &sourceArea,
   1285                                     const gl::Extents &sourceSize,
   1286                                     const TextureHelper11 &dest,
   1287                                     unsigned int destSubresource,
   1288                                     const gl::Box &destArea,
   1289                                     const gl::Extents &destSize,
   1290                                     const gl::Rectangle *scissor,
   1291                                     size_t readOffset,
   1292                                     size_t writeOffset,
   1293                                     size_t copySize,
   1294                                     size_t srcPixelStride,
   1295                                     size_t destPixelStride,
   1296                                     BlitConvertFunction *convertFunction)
   1297 {
   1298    ANGLE_TRY(initResources(context));
   1299 
   1300    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   1301 
   1302    // HACK: Create the destination staging buffer as a read/write texture so
   1303    // ID3D11DevicContext::UpdateSubresource can be called
   1304    //       using it's mapped data as a source
   1305    TextureHelper11 destStaging;
   1306    ANGLE_TRY(mRenderer->createStagingTexture(context, ResourceType::Texture2D, dest.getFormatSet(),
   1307                                              destSize, StagingAccess::READ_WRITE, &destStaging));
   1308 
   1309    deviceContext->CopySubresourceRegion(destStaging.get(), 0, 0, 0, 0, dest.get(), destSubresource,
   1310                                         nullptr);
   1311 
   1312    ANGLE_TRY(copyAndConvertImpl(context, source, sourceSubresource, sourceArea, sourceSize,
   1313                                 destStaging, destArea, destSize, scissor, readOffset, writeOffset,
   1314                                 copySize, srcPixelStride, destPixelStride, convertFunction));
   1315 
   1316    // Work around timeouts/TDRs in older NVIDIA drivers.
   1317    if (mRenderer->getFeatures().depthStencilBlitExtraCopy.enabled)
   1318    {
   1319        D3D11_MAPPED_SUBRESOURCE mapped;
   1320        ANGLE_TRY(
   1321            mRenderer->mapResource(context, destStaging.get(), 0, D3D11_MAP_READ, 0, &mapped));
   1322        deviceContext->UpdateSubresource(dest.get(), destSubresource, nullptr, mapped.pData,
   1323                                         mapped.RowPitch, mapped.DepthPitch);
   1324        deviceContext->Unmap(destStaging.get(), 0);
   1325    }
   1326    else
   1327    {
   1328        deviceContext->CopySubresourceRegion(dest.get(), destSubresource, 0, 0, 0,
   1329                                             destStaging.get(), 0, nullptr);
   1330    }
   1331 
   1332    return angle::Result::Continue;
   1333 }
   1334 
   1335 angle::Result Blit11::addBlitShaderToMap(const gl::Context *context,
   1336                                         BlitShaderType blitShaderType,
   1337                                         ShaderDimension dimension,
   1338                                         const ShaderData &shaderData,
   1339                                         const char *name)
   1340 {
   1341    ASSERT(mBlitShaderMap.find(blitShaderType) == mBlitShaderMap.end());
   1342 
   1343    d3d11::PixelShader ps;
   1344    ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), shaderData, &ps));
   1345    ps.setInternalName(name);
   1346 
   1347    Shader shader;
   1348    shader.dimension   = dimension;
   1349    shader.pixelShader = std::move(ps);
   1350 
   1351    mBlitShaderMap[blitShaderType] = std::move(shader);
   1352    return angle::Result::Continue;
   1353 }
   1354 
   1355 angle::Result Blit11::addSwizzleShaderToMap(const gl::Context *context,
   1356                                            SwizzleShaderType swizzleShaderType,
   1357                                            ShaderDimension dimension,
   1358                                            const ShaderData &shaderData,
   1359                                            const char *name)
   1360 {
   1361    ASSERT(mSwizzleShaderMap.find(swizzleShaderType) == mSwizzleShaderMap.end());
   1362 
   1363    d3d11::PixelShader ps;
   1364    ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), shaderData, &ps));
   1365    ps.setInternalName(name);
   1366 
   1367    Shader shader;
   1368    shader.dimension   = dimension;
   1369    shader.pixelShader = std::move(ps);
   1370 
   1371    mSwizzleShaderMap[swizzleShaderType] = std::move(shader);
   1372    return angle::Result::Continue;
   1373 }
   1374 
   1375 void Blit11::clearShaderMap()
   1376 {
   1377    mBlitShaderMap.clear();
   1378    mSwizzleShaderMap.clear();
   1379 }
   1380 
   1381 Blit11::BlitShaderOperation Blit11::getBlitShaderOperation(GLenum destinationFormat,
   1382                                                           GLenum sourceFormat,
   1383                                                           bool isSrcSigned,
   1384                                                           bool isDestSigned,
   1385                                                           bool unpackPremultiplyAlpha,
   1386                                                           bool unpackUnmultiplyAlpha,
   1387                                                           GLenum destTypeForDownsampling)
   1388 {
   1389    bool floatToIntBlit =
   1390        !gl::IsIntegerFormat(sourceFormat) && gl::IsIntegerFormat(destinationFormat);
   1391 
   1392    if (isSrcSigned)
   1393    {
   1394        ASSERT(!unpackPremultiplyAlpha && !unpackUnmultiplyAlpha);
   1395        switch (destinationFormat)
   1396        {
   1397            case GL_RGBA_INTEGER:
   1398                return RGBAI;
   1399            case GL_RGB_INTEGER:
   1400                return RGBI;
   1401            case GL_RG_INTEGER:
   1402                return RGI;
   1403            case GL_RED_INTEGER:
   1404                return RI;
   1405            default:
   1406                UNREACHABLE();
   1407                return OPERATION_INVALID;
   1408        }
   1409    }
   1410    else if (isDestSigned)
   1411    {
   1412        ASSERT(floatToIntBlit);
   1413 
   1414        switch (destinationFormat)
   1415        {
   1416            case GL_RGBA_INTEGER:
   1417                if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
   1418                {
   1419                    return RGBAF_TOI;
   1420                }
   1421                return unpackPremultiplyAlpha ? RGBAF_TOI_PREMULTIPLY : RGBAF_TOI_UNMULTIPLY;
   1422            case GL_RGB_INTEGER:
   1423            case GL_RG_INTEGER:
   1424            case GL_RED_INTEGER:
   1425                if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
   1426                {
   1427                    return RGBF_TOI;
   1428                }
   1429                return unpackPremultiplyAlpha ? RGBF_TOI_PREMULTIPLY : RGBF_TOI_UNMULTIPLY;
   1430            default:
   1431                UNREACHABLE();
   1432                return OPERATION_INVALID;
   1433        }
   1434    }
   1435    else
   1436    {
   1437        // Check for the downsample formats first
   1438        switch (destTypeForDownsampling)
   1439        {
   1440            case GL_UNSIGNED_SHORT_4_4_4_4:
   1441                ASSERT(destinationFormat == GL_RGBA && !floatToIntBlit);
   1442                if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
   1443                {
   1444                    return RGBAF_4444;
   1445                }
   1446                else if (unpackPremultiplyAlpha)
   1447                {
   1448                    return RGBAF_4444_PREMULTIPLY;
   1449                }
   1450                else
   1451                {
   1452                    return RGBAF_4444_UNMULTIPLY;
   1453                }
   1454 
   1455            case GL_UNSIGNED_SHORT_5_6_5:
   1456                ASSERT(destinationFormat == GL_RGB && !floatToIntBlit);
   1457                if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
   1458                {
   1459                    return RGBF_565;
   1460                }
   1461                else
   1462                {
   1463                    return unpackPremultiplyAlpha ? RGBF_565_PREMULTIPLY : RGBF_565_UNMULTIPLY;
   1464                }
   1465            case GL_UNSIGNED_SHORT_5_5_5_1:
   1466                if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
   1467                {
   1468                    return RGBAF_5551;
   1469                }
   1470                else
   1471                {
   1472                    return unpackPremultiplyAlpha ? RGBAF_5551_PREMULTIPLY : RGBAF_5551_UNMULTIPLY;
   1473                }
   1474 
   1475            default:
   1476                // By default, use the regular passthrough/multiply/unmultiply shaders.  The above
   1477                // shaders are only needed for some emulated texture formats.
   1478                break;
   1479        }
   1480 
   1481        if (unpackPremultiplyAlpha != unpackUnmultiplyAlpha || floatToIntBlit)
   1482        {
   1483            switch (destinationFormat)
   1484            {
   1485                case GL_RGBA:
   1486                case GL_BGRA_EXT:
   1487                    ASSERT(!floatToIntBlit);
   1488                    return unpackPremultiplyAlpha ? RGBAF_PREMULTIPLY : RGBAF_UNMULTIPLY;
   1489                case GL_RGB:
   1490                case GL_RG:
   1491                case GL_RED:
   1492                    if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
   1493                    {
   1494                        return RGBF_TOUI;
   1495                    }
   1496                    else
   1497                    {
   1498                        return unpackPremultiplyAlpha ? RGBF_PREMULTIPLY : RGBF_UNMULTIPLY;
   1499                    }
   1500                case GL_RGBA_INTEGER:
   1501                    if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
   1502                    {
   1503                        return RGBAF_TOUI;
   1504                    }
   1505                    else
   1506                    {
   1507                        return unpackPremultiplyAlpha ? RGBAF_TOUI_PREMULTIPLY
   1508                                                      : RGBAF_TOUI_UNMULTIPLY;
   1509                    }
   1510                case GL_RGB_INTEGER:
   1511                case GL_RG_INTEGER:
   1512                case GL_RED_INTEGER:
   1513                    if (unpackPremultiplyAlpha == unpackUnmultiplyAlpha)
   1514                    {
   1515                        return RGBF_TOUI;
   1516                    }
   1517                    else
   1518                    {
   1519                        return unpackPremultiplyAlpha ? RGBF_TOUI_PREMULTIPLY
   1520                                                      : RGBF_TOUI_UNMULTIPLY;
   1521                    }
   1522                case GL_LUMINANCE:
   1523                    ASSERT(!floatToIntBlit);
   1524                    return unpackPremultiplyAlpha ? LUMAF_PREMULTIPLY : LUMAF_UNMULTIPLY;
   1525 
   1526                case GL_LUMINANCE_ALPHA:
   1527                    ASSERT(!floatToIntBlit);
   1528                    return unpackPremultiplyAlpha ? LUMAALPHAF_PREMULTIPLY : LUMAALPHAF_UNMULTIPLY;
   1529                case GL_ALPHA:
   1530                    return ALPHA;
   1531                default:
   1532                    UNREACHABLE();
   1533                    return OPERATION_INVALID;
   1534            }
   1535        }
   1536        else
   1537        {
   1538            switch (destinationFormat)
   1539            {
   1540                case GL_RGBA:
   1541                    return RGBAF;
   1542                case GL_RGBA_INTEGER:
   1543                    return RGBAUI;
   1544                case GL_BGRA_EXT:
   1545                    return BGRAF;
   1546                case GL_RGB:
   1547                    return RGBF;
   1548                case GL_RGB_INTEGER:
   1549                    return RGBUI;
   1550                case GL_RG:
   1551                    return RGF;
   1552                case GL_RG_INTEGER:
   1553                    return RGUI;
   1554                case GL_RED:
   1555                    return RF;
   1556                case GL_RED_INTEGER:
   1557                    return RUI;
   1558                case GL_ALPHA:
   1559                    return ALPHA;
   1560                case GL_LUMINANCE:
   1561                    return LUMA;
   1562                case GL_LUMINANCE_ALPHA:
   1563                    return LUMAALPHA;
   1564                default:
   1565                    UNREACHABLE();
   1566                    return OPERATION_INVALID;
   1567            }
   1568        }
   1569    }
   1570 }
   1571 
   1572 angle::Result Blit11::getBlitShader(const gl::Context *context,
   1573                                    GLenum destFormat,
   1574                                    GLenum sourceFormat,
   1575                                    bool isSrcSigned,
   1576                                    bool isDestSigned,
   1577                                    bool unpackPremultiplyAlpha,
   1578                                    bool unpackUnmultiplyAlpha,
   1579                                    GLenum destTypeForDownsampling,
   1580                                    ShaderDimension dimension,
   1581                                    const Shader **shader)
   1582 {
   1583    BlitShaderOperation blitShaderOperation = OPERATION_INVALID;
   1584 
   1585    blitShaderOperation = getBlitShaderOperation(destFormat, sourceFormat, isSrcSigned,
   1586                                                 isDestSigned, unpackPremultiplyAlpha,
   1587                                                 unpackUnmultiplyAlpha, destTypeForDownsampling);
   1588 
   1589    BlitShaderType blitShaderType = BLITSHADER_INVALID;
   1590 
   1591    blitShaderType = getBlitShaderType(blitShaderOperation, dimension);
   1592 
   1593    ANGLE_CHECK_HR(GetImplAs<Context11>(context), blitShaderType != BLITSHADER_INVALID,
   1594                   "Internal blit shader type mismatch", E_FAIL);
   1595 
   1596    auto blitShaderIt = mBlitShaderMap.find(blitShaderType);
   1597    if (blitShaderIt != mBlitShaderMap.end())
   1598    {
   1599        *shader = &blitShaderIt->second;
   1600        return angle::Result::Continue;
   1601    }
   1602 
   1603    ASSERT(dimension == SHADER_2D || mRenderer->isES3Capable());
   1604 
   1605    ANGLE_TRY(mapBlitShader(context, blitShaderType));
   1606 
   1607    blitShaderIt = mBlitShaderMap.find(blitShaderType);
   1608    ASSERT(blitShaderIt != mBlitShaderMap.end());
   1609    *shader = &blitShaderIt->second;
   1610    return angle::Result::Continue;
   1611 }
   1612 
   1613 angle::Result Blit11::getSwizzleShader(const gl::Context *context,
   1614                                       GLenum type,
   1615                                       D3D11_SRV_DIMENSION viewDimension,
   1616                                       const Shader **shader)
   1617 {
   1618    SwizzleShaderType swizzleShaderType = GetSwizzleShaderType(type, viewDimension);
   1619 
   1620    ANGLE_CHECK_HR(GetImplAs<Context11>(context), swizzleShaderType != SWIZZLESHADER_INVALID,
   1621                   "Swizzle shader type not found", E_FAIL);
   1622 
   1623    auto swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType);
   1624    if (swizzleShaderIt != mSwizzleShaderMap.end())
   1625    {
   1626        *shader = &swizzleShaderIt->second;
   1627        return angle::Result::Continue;
   1628    }
   1629 
   1630    // Swizzling shaders (OpenGL ES 3+)
   1631    ASSERT(mRenderer->isES3Capable());
   1632 
   1633    switch (swizzleShaderType)
   1634    {
   1635        case SWIZZLESHADER_2D_FLOAT:
   1636            ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_2D,
   1637                                            ShaderData(g_PS_SwizzleF2D),
   1638                                            "Blit11 2D F swizzle pixel shader"));
   1639            break;
   1640        case SWIZZLESHADER_2D_UINT:
   1641            ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_2D,
   1642                                            ShaderData(g_PS_SwizzleUI2D),
   1643                                            "Blit11 2D UI swizzle pixel shader"));
   1644            break;
   1645        case SWIZZLESHADER_2D_INT:
   1646            ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_2D,
   1647                                            ShaderData(g_PS_SwizzleI2D),
   1648                                            "Blit11 2D I swizzle pixel shader"));
   1649            break;
   1650        case SWIZZLESHADER_CUBE_FLOAT:
   1651            ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
   1652                                            ShaderData(g_PS_SwizzleF2DArray),
   1653                                            "Blit11 2D Cube F swizzle pixel shader"));
   1654            break;
   1655        case SWIZZLESHADER_CUBE_UINT:
   1656            ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
   1657                                            ShaderData(g_PS_SwizzleUI2DArray),
   1658                                            "Blit11 2D Cube UI swizzle pixel shader"));
   1659            break;
   1660        case SWIZZLESHADER_CUBE_INT:
   1661            ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
   1662                                            ShaderData(g_PS_SwizzleI2DArray),
   1663                                            "Blit11 2D Cube I swizzle pixel shader"));
   1664            break;
   1665        case SWIZZLESHADER_3D_FLOAT:
   1666            ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
   1667                                            ShaderData(g_PS_SwizzleF3D),
   1668                                            "Blit11 3D F swizzle pixel shader"));
   1669            break;
   1670        case SWIZZLESHADER_3D_UINT:
   1671            ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
   1672                                            ShaderData(g_PS_SwizzleUI3D),
   1673                                            "Blit11 3D UI swizzle pixel shader"));
   1674            break;
   1675        case SWIZZLESHADER_3D_INT:
   1676            ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
   1677                                            ShaderData(g_PS_SwizzleI3D),
   1678                                            "Blit11 3D I swizzle pixel shader"));
   1679            break;
   1680        case SWIZZLESHADER_ARRAY_FLOAT:
   1681            ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
   1682                                            ShaderData(g_PS_SwizzleF2DArray),
   1683                                            "Blit11 2D Array F swizzle pixel shader"));
   1684            break;
   1685        case SWIZZLESHADER_ARRAY_UINT:
   1686            ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
   1687                                            ShaderData(g_PS_SwizzleUI2DArray),
   1688                                            "Blit11 2D Array UI swizzle pixel shader"));
   1689            break;
   1690        case SWIZZLESHADER_ARRAY_INT:
   1691            ANGLE_TRY(addSwizzleShaderToMap(context, swizzleShaderType, SHADER_3D,
   1692                                            ShaderData(g_PS_SwizzleI2DArray),
   1693                                            "Blit11 2D Array I swizzle pixel shader"));
   1694            break;
   1695        default:
   1696            ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   1697    }
   1698 
   1699    swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType);
   1700    ASSERT(swizzleShaderIt != mSwizzleShaderMap.end());
   1701    *shader = &swizzleShaderIt->second;
   1702    return angle::Result::Continue;
   1703 }
   1704 
   1705 angle::Result Blit11::resolveDepth(const gl::Context *context,
   1706                                   RenderTarget11 *depth,
   1707                                   TextureHelper11 *textureOut)
   1708 {
   1709    ANGLE_TRY(initResources(context));
   1710 
   1711    // Multisampled depth stencil SRVs are not available in feature level 10.0
   1712    ASSERT(mRenderer->getRenderer11DeviceCaps().featureLevel > D3D_FEATURE_LEVEL_10_0);
   1713 
   1714    const auto &extents = depth->getExtents();
   1715    auto *deviceContext = mRenderer->getDeviceContext();
   1716    auto *stateManager  = mRenderer->getStateManager();
   1717 
   1718    ANGLE_TRY(initResolveDepthOnly(context, depth->getFormatSet(), extents));
   1719 
   1720    Context11 *context11 = GetImplAs<Context11>(context);
   1721 
   1722    ANGLE_TRY(mResolveDepthStencilVS.resolve(context11, mRenderer));
   1723    ANGLE_TRY(mResolveDepthPS.resolve(context11, mRenderer));
   1724 
   1725    // Apply the necessary state changes to the D3D11 immediate device context.
   1726    stateManager->setInputLayout(nullptr);
   1727    stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
   1728    stateManager->setDrawShaders(&mResolveDepthStencilVS.getObj(), nullptr,
   1729                                 &mResolveDepthPS.getObj());
   1730    stateManager->setRasterizerState(nullptr);
   1731    stateManager->setDepthStencilState(&mDepthStencilState, 0xFFFFFFFF);
   1732    stateManager->setRenderTargets(nullptr, 0, mResolvedDepthDSView.get());
   1733    stateManager->setSimpleBlendState(nullptr);
   1734    stateManager->setSimpleViewport(extents);
   1735 
   1736    // Set the viewport
   1737    const d3d11::SharedSRV *srv;
   1738    ANGLE_TRY(depth->getShaderResourceView(context, &srv));
   1739 
   1740    stateManager->setShaderResourceShared(gl::ShaderType::Fragment, 0, srv);
   1741 
   1742    // Trigger the blit on the GPU.
   1743    deviceContext->Draw(6, 0);
   1744 
   1745    *textureOut = mResolvedDepth;
   1746    return angle::Result::Continue;
   1747 }
   1748 
   1749 angle::Result Blit11::initResolveDepthOnly(const gl::Context *context,
   1750                                           const d3d11::Format &format,
   1751                                           const gl::Extents &extents)
   1752 {
   1753    if (mResolvedDepth.valid() && extents == mResolvedDepth.getExtents() &&
   1754        format.texFormat == mResolvedDepth.getFormat())
   1755    {
   1756        return angle::Result::Continue;
   1757    }
   1758 
   1759    D3D11_TEXTURE2D_DESC textureDesc;
   1760    textureDesc.Width              = extents.width;
   1761    textureDesc.Height             = extents.height;
   1762    textureDesc.MipLevels          = 1;
   1763    textureDesc.ArraySize          = 1;
   1764    textureDesc.Format             = format.texFormat;
   1765    textureDesc.SampleDesc.Count   = 1;
   1766    textureDesc.SampleDesc.Quality = 0;
   1767    textureDesc.Usage              = D3D11_USAGE_DEFAULT;
   1768    textureDesc.BindFlags          = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE;
   1769    textureDesc.CPUAccessFlags     = 0;
   1770    textureDesc.MiscFlags          = 0;
   1771 
   1772    Context11 *context11 = GetImplAs<Context11>(context);
   1773 
   1774    ANGLE_TRY(mRenderer->allocateTexture(context11, textureDesc, format, &mResolvedDepth));
   1775    mResolvedDepth.setInternalName("Blit11::mResolvedDepth");
   1776 
   1777    D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
   1778    dsvDesc.Flags              = 0;
   1779    dsvDesc.Format             = format.dsvFormat;
   1780    dsvDesc.Texture2D.MipSlice = 0;
   1781    dsvDesc.ViewDimension      = D3D11_DSV_DIMENSION_TEXTURE2D;
   1782 
   1783    ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, mResolvedDepth.get(),
   1784                                          &mResolvedDepthDSView));
   1785    mResolvedDepthDSView.setInternalName("Blit11::mResolvedDepthDSView");
   1786 
   1787    // Possibly D3D11 bug or undefined behaviour: Clear the DSV so that our first render
   1788    // works as expected. Otherwise the results of the first use seem to be incorrect.
   1789    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   1790    deviceContext->ClearDepthStencilView(mResolvedDepthDSView.get(), D3D11_CLEAR_DEPTH, 1.0f, 0);
   1791 
   1792    return angle::Result::Continue;
   1793 }
   1794 
   1795 angle::Result Blit11::initResolveDepthStencil(const gl::Context *context,
   1796                                              const gl::Extents &extents)
   1797 {
   1798    // Check if we need to recreate depth stencil view
   1799    if (mResolvedDepthStencil.valid() && extents == mResolvedDepthStencil.getExtents())
   1800    {
   1801        ASSERT(mResolvedDepthStencil.getFormat() == DXGI_FORMAT_R32G32_FLOAT);
   1802        return angle::Result::Continue;
   1803    }
   1804 
   1805    if (mResolvedDepthStencil.valid())
   1806    {
   1807        releaseResolveDepthStencilResources();
   1808    }
   1809 
   1810    const auto &formatSet = d3d11::Format::Get(GL_RG32F, mRenderer->getRenderer11DeviceCaps());
   1811 
   1812    D3D11_TEXTURE2D_DESC textureDesc;
   1813    textureDesc.Width              = extents.width;
   1814    textureDesc.Height             = extents.height;
   1815    textureDesc.MipLevels          = 1;
   1816    textureDesc.ArraySize          = 1;
   1817    textureDesc.Format             = formatSet.texFormat;
   1818    textureDesc.SampleDesc.Count   = 1;
   1819    textureDesc.SampleDesc.Quality = 0;
   1820    textureDesc.Usage              = D3D11_USAGE_DEFAULT;
   1821    textureDesc.BindFlags          = D3D11_BIND_RENDER_TARGET;
   1822    textureDesc.CPUAccessFlags     = 0;
   1823    textureDesc.MiscFlags          = 0;
   1824 
   1825    Context11 *context11 = GetImplAs<Context11>(context);
   1826 
   1827    ANGLE_TRY(
   1828        mRenderer->allocateTexture(context11, textureDesc, formatSet, &mResolvedDepthStencil));
   1829    mResolvedDepthStencil.setInternalName("Blit11::mResolvedDepthStencil");
   1830 
   1831    ANGLE_TRY(mRenderer->allocateResourceNoDesc(context11, mResolvedDepthStencil.get(),
   1832                                                &mResolvedDepthStencilRTView));
   1833    mResolvedDepthStencilRTView.setInternalName("Blit11::mResolvedDepthStencilRTView");
   1834 
   1835    return angle::Result::Continue;
   1836 }
   1837 
   1838 angle::Result Blit11::resolveStencil(const gl::Context *context,
   1839                                     RenderTarget11 *depthStencil,
   1840                                     bool alsoDepth,
   1841                                     TextureHelper11 *textureOut)
   1842 {
   1843    ANGLE_TRY(initResources(context));
   1844 
   1845    // Multisampled depth stencil SRVs are not available in feature level 10.0
   1846    ASSERT(mRenderer->getRenderer11DeviceCaps().featureLevel > D3D_FEATURE_LEVEL_10_0);
   1847 
   1848    const auto &extents = depthStencil->getExtents();
   1849 
   1850    ANGLE_TRY(initResolveDepthStencil(context, extents));
   1851 
   1852    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   1853    auto *stateManager                 = mRenderer->getStateManager();
   1854    ID3D11Resource *stencilResource    = depthStencil->getTexture().get();
   1855 
   1856    // Check if we need to re-create the stencil SRV.
   1857    if (mStencilSRV.valid())
   1858    {
   1859        ID3D11Resource *priorResource = nullptr;
   1860        mStencilSRV.get()->GetResource(&priorResource);
   1861 
   1862        if (stencilResource != priorResource)
   1863        {
   1864            mStencilSRV.reset();
   1865        }
   1866 
   1867        SafeRelease(priorResource);
   1868    }
   1869 
   1870    Context11 *context11 = GetImplAs<Context11>(context);
   1871 
   1872    if (!mStencilSRV.valid())
   1873    {
   1874        D3D11_SHADER_RESOURCE_VIEW_DESC srViewDesc;
   1875        srViewDesc.Format        = GetStencilSRVFormat(depthStencil->getFormatSet());
   1876        srViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
   1877 
   1878        ANGLE_TRY(
   1879            mRenderer->allocateResource(context11, srViewDesc, stencilResource, &mStencilSRV));
   1880        mStencilSRV.setInternalName("Blit11::mStencilSRV");
   1881    }
   1882 
   1883    // Notify the Renderer that all state should be invalidated.
   1884    ANGLE_TRY(mResolveDepthStencilVS.resolve(context11, mRenderer));
   1885 
   1886    // Resolving the depth buffer works by sampling the depth in the shader using a SRV, then
   1887    // writing to the resolved depth buffer using SV_Depth. We can't use this method for stencil
   1888    // because SV_StencilRef isn't supported until HLSL 5.1/D3D11.3.
   1889    const d3d11::PixelShader *pixelShader = nullptr;
   1890    if (alsoDepth)
   1891    {
   1892        ANGLE_TRY(mResolveDepthStencilPS.resolve(context11, mRenderer));
   1893        pixelShader = &mResolveDepthStencilPS.getObj();
   1894    }
   1895    else
   1896    {
   1897        ANGLE_TRY(mResolveStencilPS.resolve(context11, mRenderer));
   1898        pixelShader = &mResolveStencilPS.getObj();
   1899    }
   1900 
   1901    // Apply the necessary state changes to the D3D11 immediate device context.
   1902    stateManager->setInputLayout(nullptr);
   1903    stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
   1904    stateManager->setDrawShaders(&mResolveDepthStencilVS.getObj(), nullptr, pixelShader);
   1905    stateManager->setRasterizerState(nullptr);
   1906    stateManager->setDepthStencilState(nullptr, 0xFFFFFFFF);
   1907    stateManager->setRenderTarget(mResolvedDepthStencilRTView.get(), nullptr);
   1908    stateManager->setSimpleBlendState(nullptr);
   1909 
   1910    // Set the viewport
   1911    stateManager->setSimpleViewport(extents);
   1912    const d3d11::SharedSRV *srv;
   1913    ANGLE_TRY(depthStencil->getShaderResourceView(context, &srv));
   1914    stateManager->setShaderResourceShared(gl::ShaderType::Fragment, 0, srv);
   1915    stateManager->setShaderResource(gl::ShaderType::Fragment, 1, &mStencilSRV);
   1916 
   1917    // Trigger the blit on the GPU.
   1918    deviceContext->Draw(6, 0);
   1919 
   1920    gl::Box copyBox(0, 0, 0, extents.width, extents.height, 1);
   1921 
   1922    ANGLE_TRY(mRenderer->createStagingTexture(context, ResourceType::Texture2D,
   1923                                              depthStencil->getFormatSet(), extents,
   1924                                              StagingAccess::READ_WRITE, textureOut));
   1925 
   1926    const auto &copyFunction = GetCopyDepthStencilFunction(depthStencil->getInternalFormat());
   1927    const auto &dsFormatSet  = depthStencil->getFormatSet();
   1928    const auto &dsDxgiInfo   = d3d11::GetDXGIFormatSizeInfo(dsFormatSet.texFormat);
   1929 
   1930    ANGLE_TRY(copyAndConvertImpl(context, mResolvedDepthStencil, 0, copyBox, extents, *textureOut,
   1931                                 copyBox, extents, nullptr, 0, 0, 0, 8u, dsDxgiInfo.pixelBytes,
   1932                                 copyFunction));
   1933 
   1934    return angle::Result::Continue;
   1935 }
   1936 
   1937 void Blit11::releaseResolveDepthStencilResources()
   1938 {
   1939    mStencilSRV.reset();
   1940    mResolvedDepthStencilRTView.reset();
   1941 }
   1942 
   1943 }  // namespace rx