tor-browser

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

PixelTransfer11.cpp (12251B)


      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 // PixelTransfer11.cpp:
      8 //   Implementation for buffer-to-texture and texture-to-buffer copies.
      9 //   Used to implement pixel transfers from unpack and to pack buffers.
     10 //
     11 
     12 #include "libANGLE/renderer/d3d/d3d11/PixelTransfer11.h"
     13 
     14 #include "libANGLE/Buffer.h"
     15 #include "libANGLE/Context.h"
     16 #include "libANGLE/Texture.h"
     17 #include "libANGLE/formatutils.h"
     18 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
     19 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
     20 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
     21 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
     22 #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
     23 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
     24 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
     25 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
     26 #include "libANGLE/renderer/serial_utils.h"
     27 
     28 // Precompiled shaders
     29 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h"
     30 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h"
     31 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h"
     32 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h"
     33 #include "libANGLE/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h"
     34 
     35 namespace rx
     36 {
     37 
     38 PixelTransfer11::PixelTransfer11(Renderer11 *renderer)
     39    : mRenderer(renderer),
     40      mResourcesLoaded(false),
     41      mBufferToTextureVS(),
     42      mBufferToTextureGS(),
     43      mParamsConstantBuffer(),
     44      mCopyRasterizerState(),
     45      mCopyDepthStencilState()
     46 {}
     47 
     48 PixelTransfer11::~PixelTransfer11() {}
     49 
     50 angle::Result PixelTransfer11::loadResources(const gl::Context *context)
     51 {
     52    if (mResourcesLoaded)
     53    {
     54        return angle::Result::Continue;
     55    }
     56 
     57    D3D11_RASTERIZER_DESC rasterDesc;
     58    rasterDesc.FillMode              = D3D11_FILL_SOLID;
     59    rasterDesc.CullMode              = D3D11_CULL_NONE;
     60    rasterDesc.FrontCounterClockwise = FALSE;
     61    rasterDesc.DepthBias             = 0;
     62    rasterDesc.SlopeScaledDepthBias  = 0.0f;
     63    rasterDesc.DepthBiasClamp        = 0.0f;
     64    rasterDesc.DepthClipEnable       = TRUE;
     65    rasterDesc.ScissorEnable         = FALSE;
     66    rasterDesc.MultisampleEnable     = FALSE;
     67    rasterDesc.AntialiasedLineEnable = FALSE;
     68 
     69    Context11 *context11 = GetImplAs<Context11>(context);
     70 
     71    ANGLE_TRY(mRenderer->allocateResource(context11, rasterDesc, &mCopyRasterizerState));
     72 
     73    D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
     74    depthStencilDesc.DepthEnable                  = true;
     75    depthStencilDesc.DepthWriteMask               = D3D11_DEPTH_WRITE_MASK_ALL;
     76    depthStencilDesc.DepthFunc                    = D3D11_COMPARISON_ALWAYS;
     77    depthStencilDesc.StencilEnable                = FALSE;
     78    depthStencilDesc.StencilReadMask              = D3D11_DEFAULT_STENCIL_READ_MASK;
     79    depthStencilDesc.StencilWriteMask             = D3D11_DEFAULT_STENCIL_WRITE_MASK;
     80    depthStencilDesc.FrontFace.StencilFailOp      = D3D11_STENCIL_OP_KEEP;
     81    depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
     82    depthStencilDesc.FrontFace.StencilPassOp      = D3D11_STENCIL_OP_KEEP;
     83    depthStencilDesc.FrontFace.StencilFunc        = D3D11_COMPARISON_ALWAYS;
     84    depthStencilDesc.BackFace.StencilFailOp       = D3D11_STENCIL_OP_KEEP;
     85    depthStencilDesc.BackFace.StencilDepthFailOp  = D3D11_STENCIL_OP_KEEP;
     86    depthStencilDesc.BackFace.StencilPassOp       = D3D11_STENCIL_OP_KEEP;
     87    depthStencilDesc.BackFace.StencilFunc         = D3D11_COMPARISON_ALWAYS;
     88 
     89    ANGLE_TRY(mRenderer->allocateResource(context11, depthStencilDesc, &mCopyDepthStencilState));
     90 
     91    D3D11_BUFFER_DESC constantBufferDesc   = {};
     92    constantBufferDesc.ByteWidth           = roundUpPow2<UINT>(sizeof(CopyShaderParams), 32u);
     93    constantBufferDesc.Usage               = D3D11_USAGE_DYNAMIC;
     94    constantBufferDesc.BindFlags           = D3D11_BIND_CONSTANT_BUFFER;
     95    constantBufferDesc.CPUAccessFlags      = D3D11_CPU_ACCESS_WRITE;
     96    constantBufferDesc.MiscFlags           = 0;
     97    constantBufferDesc.StructureByteStride = 0;
     98 
     99    ANGLE_TRY(mRenderer->allocateResource(context11, constantBufferDesc, &mParamsConstantBuffer));
    100    mParamsConstantBuffer.setInternalName("PixelTransfer11ConstantBuffer");
    101 
    102    // init shaders
    103    ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_VS_BufferToTexture),
    104                                          &mBufferToTextureVS));
    105    mBufferToTextureVS.setInternalName("BufferToTextureVS");
    106 
    107    ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_GS_BufferToTexture),
    108                                          &mBufferToTextureGS));
    109    mBufferToTextureGS.setInternalName("BufferToTextureGS");
    110 
    111    ANGLE_TRY(buildShaderMap(context));
    112 
    113    StructZero(&mParamsData);
    114 
    115    mResourcesLoaded = true;
    116 
    117    return angle::Result::Continue;
    118 }
    119 
    120 void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea,
    121                                                   const gl::Extents &destSize,
    122                                                   GLenum internalFormat,
    123                                                   const gl::PixelUnpackState &unpack,
    124                                                   unsigned int offset,
    125                                                   CopyShaderParams *parametersOut)
    126 {
    127    StructZero(parametersOut);
    128 
    129    float texelCenterX = 0.5f / static_cast<float>(destSize.width);
    130    float texelCenterY = 0.5f / static_cast<float>(destSize.height);
    131 
    132    unsigned int bytesPerPixel  = gl::GetSizedInternalFormatInfo(internalFormat).pixelBytes;
    133    unsigned int alignmentBytes = static_cast<unsigned int>(unpack.alignment);
    134    unsigned int alignmentPixels =
    135        (alignmentBytes <= bytesPerPixel ? 1 : alignmentBytes / bytesPerPixel);
    136 
    137    parametersOut->FirstPixelOffset = offset / bytesPerPixel;
    138    parametersOut->PixelsPerRow =
    139        static_cast<unsigned int>((unpack.rowLength > 0) ? unpack.rowLength : destArea.width);
    140    parametersOut->RowStride    = roundUp(parametersOut->PixelsPerRow, alignmentPixels);
    141    parametersOut->RowsPerSlice = static_cast<unsigned int>(destArea.height);
    142    parametersOut->PositionOffset[0] =
    143        texelCenterX + (destArea.x / float(destSize.width)) * 2.0f - 1.0f;
    144    parametersOut->PositionOffset[1] =
    145        texelCenterY + ((destSize.height - destArea.y - 1) / float(destSize.height)) * 2.0f - 1.0f;
    146    parametersOut->PositionScale[0] = 2.0f / static_cast<float>(destSize.width);
    147    parametersOut->PositionScale[1] = -2.0f / static_cast<float>(destSize.height);
    148    parametersOut->FirstSlice       = destArea.z;
    149 }
    150 
    151 angle::Result PixelTransfer11::copyBufferToTexture(const gl::Context *context,
    152                                                   const gl::PixelUnpackState &unpack,
    153                                                   gl::Buffer *unpackBuffer,
    154                                                   unsigned int offset,
    155                                                   RenderTargetD3D *destRenderTarget,
    156                                                   GLenum destinationFormat,
    157                                                   GLenum sourcePixelsType,
    158                                                   const gl::Box &destArea)
    159 {
    160    ASSERT(unpackBuffer);
    161 
    162    ANGLE_TRY(loadResources(context));
    163 
    164    gl::Extents destSize = destRenderTarget->getExtents();
    165 
    166    ASSERT(destArea.x >= 0 && destArea.x + destArea.width <= destSize.width && destArea.y >= 0 &&
    167           destArea.y + destArea.height <= destSize.height && destArea.z >= 0 &&
    168           destArea.z + destArea.depth <= destSize.depth);
    169 
    170    ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat));
    171 
    172    const d3d11::PixelShader *pixelShader = findBufferToTexturePS(destinationFormat);
    173    ASSERT(pixelShader);
    174 
    175    // The SRV must be in the proper read format, which may be different from the destination format
    176    // EG: for half float data, we can load full precision floats with implicit conversion
    177    GLenum unsizedFormat = gl::GetUnsizedFormat(destinationFormat);
    178    const gl::InternalFormat &sourceglFormatInfo =
    179        gl::GetInternalFormatInfo(unsizedFormat, sourcePixelsType);
    180 
    181    const d3d11::Format &sourceFormatInfo = d3d11::Format::Get(
    182        sourceglFormatInfo.sizedInternalFormat, mRenderer->getRenderer11DeviceCaps());
    183    DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat;
    184    ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN);
    185    Buffer11 *bufferStorage11                  = GetAs<Buffer11>(unpackBuffer->getImplementation());
    186    const d3d11::ShaderResourceView *bufferSRV = nullptr;
    187    ANGLE_TRY(bufferStorage11->getSRV(context, srvFormat, &bufferSRV));
    188    ASSERT(bufferSRV != nullptr);
    189 
    190    const d3d11::RenderTargetView &textureRTV =
    191        GetAs<RenderTarget11>(destRenderTarget)->getRenderTargetView();
    192    ASSERT(textureRTV.valid());
    193 
    194    CopyShaderParams shaderParams;
    195    setBufferToTextureCopyParams(destArea, destSize, sourceglFormatInfo.sizedInternalFormat, unpack,
    196                                 offset, &shaderParams);
    197 
    198    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
    199 
    200    // Are we doing a 2D or 3D copy?
    201    const auto *geometryShader   = ((destSize.depth > 1) ? &mBufferToTextureGS : nullptr);
    202    StateManager11 *stateManager = mRenderer->getStateManager();
    203 
    204    stateManager->setDrawShaders(&mBufferToTextureVS, geometryShader, pixelShader);
    205    stateManager->setShaderResource(gl::ShaderType::Fragment, 0, bufferSRV);
    206    stateManager->setInputLayout(nullptr);
    207    stateManager->setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
    208 
    209    stateManager->setSingleVertexBuffer(nullptr, 0, 0);
    210    stateManager->setSimpleBlendState(nullptr);
    211    stateManager->setDepthStencilState(&mCopyDepthStencilState, 0xFFFFFFFF);
    212    stateManager->setRasterizerState(&mCopyRasterizerState);
    213 
    214    stateManager->setRenderTarget(textureRTV.get(), nullptr);
    215 
    216    if (!StructEquals(mParamsData, shaderParams))
    217    {
    218        d3d11::SetBufferData(deviceContext, mParamsConstantBuffer.get(), shaderParams);
    219        mParamsData = shaderParams;
    220    }
    221 
    222    stateManager->setVertexConstantBuffer(0, &mParamsConstantBuffer);
    223 
    224    // Set the viewport
    225    stateManager->setSimpleViewport(destSize);
    226 
    227    UINT numPixels = (shaderParams.PixelsPerRow * destArea.height * destArea.depth);
    228    deviceContext->Draw(numPixels, 0);
    229 
    230    return angle::Result::Continue;
    231 }
    232 
    233 angle::Result PixelTransfer11::buildShaderMap(const gl::Context *context)
    234 {
    235    d3d11::PixelShader bufferToTextureFloat;
    236    d3d11::PixelShader bufferToTextureInt;
    237    d3d11::PixelShader bufferToTextureUint;
    238 
    239    Context11 *context11 = GetImplAs<Context11>(context);
    240 
    241    ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_PS_BufferToTexture_4F),
    242                                          &bufferToTextureFloat));
    243    ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_PS_BufferToTexture_4I),
    244                                          &bufferToTextureInt));
    245    ANGLE_TRY(mRenderer->allocateResource(context11, ShaderData(g_PS_BufferToTexture_4UI),
    246                                          &bufferToTextureUint));
    247 
    248    bufferToTextureFloat.setInternalName("BufferToTextureRGBA.ps");
    249    bufferToTextureInt.setInternalName("BufferToTextureRGBA-I.ps");
    250    bufferToTextureUint.setInternalName("BufferToTextureRGBA-UI.ps");
    251 
    252    mBufferToTexturePSMap[GL_FLOAT]        = std::move(bufferToTextureFloat);
    253    mBufferToTexturePSMap[GL_INT]          = std::move(bufferToTextureInt);
    254    mBufferToTexturePSMap[GL_UNSIGNED_INT] = std::move(bufferToTextureUint);
    255 
    256    return angle::Result::Continue;
    257 }
    258 
    259 const d3d11::PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const
    260 {
    261    GLenum componentType = gl::GetSizedInternalFormatInfo(internalFormat).componentType;
    262    if (componentType == GL_SIGNED_NORMALIZED || componentType == GL_UNSIGNED_NORMALIZED)
    263    {
    264        componentType = GL_FLOAT;
    265    }
    266 
    267    auto shaderMapIt = mBufferToTexturePSMap.find(componentType);
    268    return (shaderMapIt == mBufferToTexturePSMap.end() ? nullptr : &shaderMapIt->second);
    269 }
    270 
    271 }  // namespace rx