tor-browser

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

TextureStorage9.cpp (22084B)


      1 //
      2 // Copyright 2012 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 // TextureStorage9.cpp: Implements the abstract rx::TextureStorage9 class and its concrete derived
      8 // classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the
      9 // D3D9 texture.
     10 
     11 #include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h"
     12 
     13 #include "common/utilities.h"
     14 #include "libANGLE/Context.h"
     15 #include "libANGLE/Texture.h"
     16 #include "libANGLE/formatutils.h"
     17 #include "libANGLE/renderer/d3d/EGLImageD3D.h"
     18 #include "libANGLE/renderer/d3d/TextureD3D.h"
     19 #include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h"
     20 #include "libANGLE/renderer/d3d/d3d9/Renderer9.h"
     21 #include "libANGLE/renderer/d3d/d3d9/SwapChain9.h"
     22 #include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
     23 #include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
     24 
     25 namespace rx
     26 {
     27 TextureStorage9::TextureStorage9(Renderer9 *renderer, DWORD usage, const std::string &label)
     28    : TextureStorage(label),
     29      mTopLevel(0),
     30      mMipLevels(0),
     31      mTextureWidth(0),
     32      mTextureHeight(0),
     33      mInternalFormat(GL_NONE),
     34      mTextureFormat(D3DFMT_UNKNOWN),
     35      mRenderer(renderer),
     36      mD3DUsage(usage),
     37      mD3DPool(mRenderer->getTexturePool(usage))
     38 {}
     39 
     40 TextureStorage9::~TextureStorage9() {}
     41 
     42 DWORD TextureStorage9::GetTextureUsage(GLenum internalformat, bool renderTarget)
     43 {
     44    DWORD d3dusage = 0;
     45 
     46    const gl::InternalFormat &formatInfo     = gl::GetSizedInternalFormatInfo(internalformat);
     47    const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
     48    if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0)
     49    {
     50        d3dusage |= D3DUSAGE_DEPTHSTENCIL;
     51    }
     52    else if (renderTarget && (d3dFormatInfo.renderFormat != D3DFMT_UNKNOWN))
     53    {
     54        d3dusage |= D3DUSAGE_RENDERTARGET;
     55    }
     56 
     57    return d3dusage;
     58 }
     59 
     60 bool TextureStorage9::isRenderTarget() const
     61 {
     62    return (mD3DUsage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) != 0;
     63 }
     64 
     65 bool TextureStorage9::isManaged() const
     66 {
     67    return (mD3DPool == D3DPOOL_MANAGED);
     68 }
     69 
     70 bool TextureStorage9::supportsNativeMipmapFunction() const
     71 {
     72    return false;
     73 }
     74 
     75 D3DPOOL TextureStorage9::getPool() const
     76 {
     77    return mD3DPool;
     78 }
     79 
     80 DWORD TextureStorage9::getUsage() const
     81 {
     82    return mD3DUsage;
     83 }
     84 
     85 int TextureStorage9::getTopLevel() const
     86 {
     87    return mTopLevel;
     88 }
     89 
     90 int TextureStorage9::getLevelCount() const
     91 {
     92    return static_cast<int>(mMipLevels) - mTopLevel;
     93 }
     94 
     95 angle::Result TextureStorage9::setData(const gl::Context *context,
     96                                       const gl::ImageIndex &index,
     97                                       ImageD3D *image,
     98                                       const gl::Box *destBox,
     99                                       GLenum type,
    100                                       const gl::PixelUnpackState &unpack,
    101                                       const uint8_t *pixelData)
    102 {
    103    ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
    104    return angle::Result::Stop;
    105 }
    106 
    107 TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer,
    108                                       SwapChain9 *swapchain,
    109                                       const std::string &label)
    110    : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET, label)
    111 {
    112    IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture();
    113    mTexture                          = surfaceTexture;
    114    mMipLevels                        = surfaceTexture->GetLevelCount();
    115 
    116    mInternalFormat = swapchain->getRenderTargetInternalFormat();
    117 
    118    D3DSURFACE_DESC surfaceDesc;
    119    surfaceTexture->GetLevelDesc(0, &surfaceDesc);
    120    mTextureWidth  = surfaceDesc.Width;
    121    mTextureHeight = surfaceDesc.Height;
    122    mTextureFormat = surfaceDesc.Format;
    123 
    124    mRenderTargets.resize(mMipLevels, nullptr);
    125 }
    126 
    127 TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer,
    128                                       GLenum internalformat,
    129                                       bool renderTarget,
    130                                       GLsizei width,
    131                                       GLsizei height,
    132                                       int levels,
    133                                       const std::string &label)
    134    : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget), label)
    135 {
    136    mTexture = nullptr;
    137 
    138    mInternalFormat = internalformat;
    139 
    140    const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
    141    mTextureFormat                           = d3dFormatInfo.texFormat;
    142 
    143    d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &width, &height, &mTopLevel);
    144    mTextureWidth  = width;
    145    mTextureHeight = height;
    146    mMipLevels     = mTopLevel + levels;
    147 
    148    mRenderTargets.resize(levels, nullptr);
    149 }
    150 
    151 TextureStorage9_2D::~TextureStorage9_2D()
    152 {
    153    SafeRelease(mTexture);
    154    for (RenderTargetD3D *renderTarget : mRenderTargets)
    155    {
    156        SafeDelete(renderTarget);
    157    }
    158 }
    159 
    160 // Increments refcount on surface.
    161 // caller must Release() the returned surface
    162 angle::Result TextureStorage9_2D::getSurfaceLevel(const gl::Context *context,
    163                                                  gl::TextureTarget target,
    164                                                  int level,
    165                                                  bool dirty,
    166                                                  IDirect3DSurface9 **outSurface)
    167 {
    168    ASSERT(target == gl::TextureTarget::_2D);
    169 
    170    IDirect3DBaseTexture9 *baseTexture = nullptr;
    171    ANGLE_TRY(getBaseTexture(context, &baseTexture));
    172 
    173    IDirect3DTexture9 *texture = static_cast<IDirect3DTexture9 *>(baseTexture);
    174 
    175    HRESULT result = texture->GetSurfaceLevel(level + mTopLevel, outSurface);
    176    ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to get the surface from a texture");
    177 
    178    // With managed textures the driver needs to be informed of updates to the lower mipmap levels
    179    if (level + mTopLevel != 0 && isManaged() && dirty)
    180    {
    181        texture->AddDirtyRect(nullptr);
    182    }
    183 
    184    return angle::Result::Continue;
    185 }
    186 
    187 angle::Result TextureStorage9_2D::findRenderTarget(const gl::Context *context,
    188                                                   const gl::ImageIndex &index,
    189                                                   GLsizei samples,
    190                                                   RenderTargetD3D **outRT) const
    191 {
    192    ASSERT(index.getLevelIndex() < getLevelCount());
    193 
    194    ASSERT(outRT);
    195    *outRT = mRenderTargets[index.getLevelIndex()];
    196    return angle::Result::Continue;
    197 }
    198 
    199 angle::Result TextureStorage9_2D::getRenderTarget(const gl::Context *context,
    200                                                  const gl::ImageIndex &index,
    201                                                  GLsizei samples,
    202                                                  RenderTargetD3D **outRT)
    203 {
    204    ASSERT(index.getLevelIndex() < getLevelCount());
    205 
    206    if (!mRenderTargets[index.getLevelIndex()] && isRenderTarget())
    207    {
    208        IDirect3DBaseTexture9 *baseTexture = nullptr;
    209        ANGLE_TRY(getBaseTexture(context, &baseTexture));
    210 
    211        IDirect3DSurface9 *surface = nullptr;
    212        ANGLE_TRY(getSurfaceLevel(context, gl::TextureTarget::_2D, index.getLevelIndex(), false,
    213                                  &surface));
    214 
    215        size_t textureMipLevel = mTopLevel + index.getLevelIndex();
    216        size_t mipWidth        = std::max<size_t>(mTextureWidth >> textureMipLevel, 1u);
    217        size_t mipHeight       = std::max<size_t>(mTextureHeight >> textureMipLevel, 1u);
    218 
    219        baseTexture->AddRef();
    220        mRenderTargets[index.getLevelIndex()] = new TextureRenderTarget9(
    221            baseTexture, textureMipLevel, surface, mInternalFormat, static_cast<GLsizei>(mipWidth),
    222            static_cast<GLsizei>(mipHeight), 1, 0);
    223    }
    224 
    225    ASSERT(outRT);
    226    *outRT = mRenderTargets[index.getLevelIndex()];
    227    return angle::Result::Continue;
    228 }
    229 
    230 angle::Result TextureStorage9_2D::generateMipmap(const gl::Context *context,
    231                                                 const gl::ImageIndex &sourceIndex,
    232                                                 const gl::ImageIndex &destIndex)
    233 {
    234    angle::ComPtr<IDirect3DSurface9> upper = nullptr;
    235    ANGLE_TRY(getSurfaceLevel(context, gl::TextureTarget::_2D, sourceIndex.getLevelIndex(), false,
    236                              &upper));
    237 
    238    angle::ComPtr<IDirect3DSurface9> lower = nullptr;
    239    ANGLE_TRY(
    240        getSurfaceLevel(context, gl::TextureTarget::_2D, destIndex.getLevelIndex(), true, &lower));
    241 
    242    ASSERT(upper && lower);
    243    return mRenderer->boxFilter(GetImplAs<Context9>(context), upper.Get(), lower.Get());
    244 }
    245 
    246 angle::Result TextureStorage9_2D::getBaseTexture(const gl::Context *context,
    247                                                 IDirect3DBaseTexture9 **outTexture)
    248 {
    249    // if the width or height is not positive this should be treated as an incomplete texture
    250    // we handle that here by skipping the d3d texture creation
    251    if (mTexture == nullptr && mTextureWidth > 0 && mTextureHeight > 0)
    252    {
    253        ASSERT(mMipLevels > 0);
    254 
    255        IDirect3DDevice9 *device = mRenderer->getDevice();
    256        HRESULT result           = device->CreateTexture(static_cast<unsigned int>(mTextureWidth),
    257                                               static_cast<unsigned int>(mTextureHeight),
    258                                               static_cast<unsigned int>(mMipLevels), getUsage(),
    259                                               mTextureFormat, getPool(), &mTexture, nullptr);
    260        ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to create 2D storage texture");
    261    }
    262 
    263    *outTexture = mTexture;
    264    return angle::Result::Continue;
    265 }
    266 
    267 angle::Result TextureStorage9_2D::copyToStorage(const gl::Context *context,
    268                                                TextureStorage *destStorage)
    269 {
    270    ASSERT(destStorage);
    271 
    272    TextureStorage9_2D *dest9 = GetAs<TextureStorage9_2D>(destStorage);
    273 
    274    int levels = getLevelCount();
    275    for (int i = 0; i < levels; ++i)
    276    {
    277        angle::ComPtr<IDirect3DSurface9> srcSurf = nullptr;
    278        ANGLE_TRY(getSurfaceLevel(context, gl::TextureTarget::_2D, i, false, &srcSurf));
    279 
    280        angle::ComPtr<IDirect3DSurface9> dstSurf = nullptr;
    281        ANGLE_TRY(dest9->getSurfaceLevel(context, gl::TextureTarget::_2D, i, true, &dstSurf));
    282 
    283        ANGLE_TRY(
    284            mRenderer->copyToRenderTarget(context, dstSurf.Get(), srcSurf.Get(), isManaged()));
    285    }
    286 
    287    return angle::Result::Continue;
    288 }
    289 
    290 TextureStorage9_EGLImage::TextureStorage9_EGLImage(Renderer9 *renderer,
    291                                                   EGLImageD3D *image,
    292                                                   RenderTarget9 *renderTarget9,
    293                                                   const std::string &label)
    294    : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET, label), mImage(image)
    295 {
    296 
    297    mInternalFormat = renderTarget9->getInternalFormat();
    298    mTextureFormat  = renderTarget9->getD3DFormat();
    299    mTextureWidth   = renderTarget9->getWidth();
    300    mTextureHeight  = renderTarget9->getHeight();
    301    mTopLevel       = static_cast<int>(renderTarget9->getTextureLevel());
    302    mMipLevels      = mTopLevel + 1;
    303 }
    304 
    305 TextureStorage9_EGLImage::~TextureStorage9_EGLImage() {}
    306 
    307 angle::Result TextureStorage9_EGLImage::getSurfaceLevel(const gl::Context *context,
    308                                                        gl::TextureTarget target,
    309                                                        int level,
    310                                                        bool,
    311                                                        IDirect3DSurface9 **outSurface)
    312 {
    313    ASSERT(target == gl::TextureTarget::_2D);
    314    ASSERT(level == 0);
    315 
    316    RenderTargetD3D *renderTargetD3D = nullptr;
    317    ANGLE_TRY(mImage->getRenderTarget(context, &renderTargetD3D));
    318 
    319    RenderTarget9 *renderTarget9 = GetAs<RenderTarget9>(renderTargetD3D);
    320 
    321    *outSurface = renderTarget9->getSurface();
    322    return angle::Result::Continue;
    323 }
    324 
    325 angle::Result TextureStorage9_EGLImage::findRenderTarget(const gl::Context *context,
    326                                                         const gl::ImageIndex &index,
    327                                                         GLsizei samples,
    328                                                         RenderTargetD3D **outRT) const
    329 {
    330    // Since the render target of a EGL image will be updated when orphaning, trying to find a cache
    331    // of it can be rarely useful.
    332    ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
    333    return angle::Result::Stop;
    334 }
    335 
    336 angle::Result TextureStorage9_EGLImage::getRenderTarget(const gl::Context *context,
    337                                                        const gl::ImageIndex &index,
    338                                                        GLsizei samples,
    339                                                        RenderTargetD3D **outRT)
    340 {
    341    ASSERT(!index.hasLayer());
    342    ASSERT(index.getLevelIndex() == 0);
    343    ASSERT(samples == 0);
    344 
    345    return mImage->getRenderTarget(context, outRT);
    346 }
    347 
    348 angle::Result TextureStorage9_EGLImage::getBaseTexture(const gl::Context *context,
    349                                                       IDirect3DBaseTexture9 **outTexture)
    350 {
    351    RenderTargetD3D *renderTargetD3D = nullptr;
    352    ANGLE_TRY(mImage->getRenderTarget(context, &renderTargetD3D));
    353 
    354    RenderTarget9 *renderTarget9 = GetAs<RenderTarget9>(renderTargetD3D);
    355    *outTexture                  = renderTarget9->getTexture();
    356    ASSERT(*outTexture != nullptr);
    357 
    358    return angle::Result::Continue;
    359 }
    360 
    361 angle::Result TextureStorage9_EGLImage::generateMipmap(const gl::Context *context,
    362                                                       const gl::ImageIndex &,
    363                                                       const gl::ImageIndex &)
    364 {
    365    ANGLE_HR_UNREACHABLE(GetImplAs<Context9>(context));
    366    return angle::Result::Stop;
    367 }
    368 
    369 angle::Result TextureStorage9_EGLImage::copyToStorage(const gl::Context *context,
    370                                                      TextureStorage *destStorage)
    371 {
    372    ASSERT(destStorage);
    373    ASSERT(getLevelCount() == 1);
    374 
    375    TextureStorage9 *dest9 = GetAs<TextureStorage9>(destStorage);
    376 
    377    IDirect3DBaseTexture9 *destBaseTexture9 = nullptr;
    378    ANGLE_TRY(dest9->getBaseTexture(context, &destBaseTexture9));
    379 
    380    IDirect3DTexture9 *destTexture9 = static_cast<IDirect3DTexture9 *>(destBaseTexture9);
    381 
    382    angle::ComPtr<IDirect3DSurface9> destSurface = nullptr;
    383    HRESULT result = destTexture9->GetSurfaceLevel(destStorage->getTopLevel(), &destSurface);
    384    ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to get the surface from a texture");
    385 
    386    RenderTargetD3D *sourceRenderTarget = nullptr;
    387    ANGLE_TRY(mImage->getRenderTarget(context, &sourceRenderTarget));
    388 
    389    RenderTarget9 *sourceRenderTarget9 = GetAs<RenderTarget9>(sourceRenderTarget);
    390    ANGLE_TRY(mRenderer->copyToRenderTarget(context, destSurface.Get(),
    391                                            sourceRenderTarget9->getSurface(), isManaged()));
    392 
    393    if (destStorage->getTopLevel() != 0)
    394    {
    395        destTexture9->AddDirtyRect(nullptr);
    396    }
    397 
    398    return angle::Result::Continue;
    399 }
    400 
    401 TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer,
    402                                           GLenum internalformat,
    403                                           bool renderTarget,
    404                                           int size,
    405                                           int levels,
    406                                           bool hintLevelZeroOnly,
    407                                           const std::string &label)
    408    : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget), label)
    409 {
    410    mTexture = nullptr;
    411    for (size_t i = 0; i < gl::kCubeFaceCount; ++i)
    412    {
    413        mRenderTarget[i] = nullptr;
    414    }
    415 
    416    mInternalFormat = internalformat;
    417 
    418    const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat);
    419    mTextureFormat                           = d3dFormatInfo.texFormat;
    420 
    421    int height = size;
    422    d3d9::MakeValidSize(false, d3dFormatInfo.texFormat, &size, &height, &mTopLevel);
    423    mTextureWidth  = size;
    424    mTextureHeight = size;
    425    mMipLevels     = mTopLevel + levels;
    426 }
    427 
    428 TextureStorage9_Cube::~TextureStorage9_Cube()
    429 {
    430    SafeRelease(mTexture);
    431 
    432    for (size_t i = 0; i < gl::kCubeFaceCount; ++i)
    433    {
    434        SafeDelete(mRenderTarget[i]);
    435    }
    436 }
    437 
    438 // Increments refcount on surface.
    439 // caller must Release() the returned surface
    440 angle::Result TextureStorage9_Cube::getSurfaceLevel(const gl::Context *context,
    441                                                    gl::TextureTarget target,
    442                                                    int level,
    443                                                    bool dirty,
    444                                                    IDirect3DSurface9 **outSurface)
    445 {
    446    IDirect3DBaseTexture9 *baseTexture = nullptr;
    447    ANGLE_TRY(getBaseTexture(context, &baseTexture));
    448 
    449    IDirect3DCubeTexture9 *texture = static_cast<IDirect3DCubeTexture9 *>(baseTexture);
    450 
    451    D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(target);
    452    HRESULT result        = texture->GetCubeMapSurface(face, level, outSurface);
    453    ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to get the surface from a texture");
    454 
    455    // With managed textures the driver needs to be informed of updates to the lower mipmap levels
    456    if (level != 0 && isManaged() && dirty)
    457    {
    458        texture->AddDirtyRect(face, nullptr);
    459    }
    460 
    461    return angle::Result::Continue;
    462 }
    463 
    464 angle::Result TextureStorage9_Cube::findRenderTarget(const gl::Context *context,
    465                                                     const gl::ImageIndex &index,
    466                                                     GLsizei samples,
    467                                                     RenderTargetD3D **outRT) const
    468 {
    469    ASSERT(outRT);
    470    ASSERT(index.getLevelIndex() == 0);
    471    ASSERT(samples == 0);
    472 
    473    ASSERT(index.getType() == gl::TextureType::CubeMap &&
    474           gl::IsCubeMapFaceTarget(index.getTarget()));
    475    const size_t renderTargetIndex = index.cubeMapFaceIndex();
    476 
    477    *outRT = mRenderTarget[renderTargetIndex];
    478    return angle::Result::Continue;
    479 }
    480 
    481 angle::Result TextureStorage9_Cube::getRenderTarget(const gl::Context *context,
    482                                                    const gl::ImageIndex &index,
    483                                                    GLsizei samples,
    484                                                    RenderTargetD3D **outRT)
    485 {
    486    ASSERT(outRT);
    487    ASSERT(index.getLevelIndex() == 0);
    488    ASSERT(samples == 0);
    489 
    490    ASSERT(index.getType() == gl::TextureType::CubeMap &&
    491           gl::IsCubeMapFaceTarget(index.getTarget()));
    492    const size_t renderTargetIndex = index.cubeMapFaceIndex();
    493 
    494    if (mRenderTarget[renderTargetIndex] == nullptr && isRenderTarget())
    495    {
    496        IDirect3DBaseTexture9 *baseTexture = nullptr;
    497        ANGLE_TRY(getBaseTexture(context, &baseTexture));
    498 
    499        IDirect3DSurface9 *surface = nullptr;
    500        ANGLE_TRY(getSurfaceLevel(context, index.getTarget(), mTopLevel + index.getLevelIndex(),
    501                                  false, &surface));
    502 
    503        baseTexture->AddRef();
    504        mRenderTarget[renderTargetIndex] = new TextureRenderTarget9(
    505            baseTexture, mTopLevel + index.getLevelIndex(), surface, mInternalFormat,
    506            static_cast<GLsizei>(mTextureWidth), static_cast<GLsizei>(mTextureHeight), 1, 0);
    507    }
    508 
    509    *outRT = mRenderTarget[renderTargetIndex];
    510    return angle::Result::Continue;
    511 }
    512 
    513 angle::Result TextureStorage9_Cube::generateMipmap(const gl::Context *context,
    514                                                   const gl::ImageIndex &sourceIndex,
    515                                                   const gl::ImageIndex &destIndex)
    516 {
    517    angle::ComPtr<IDirect3DSurface9> upper = nullptr;
    518    ANGLE_TRY(getSurfaceLevel(context, sourceIndex.getTarget(), sourceIndex.getLevelIndex(), false,
    519                              &upper));
    520 
    521    angle::ComPtr<IDirect3DSurface9> lower = nullptr;
    522    ANGLE_TRY(
    523        getSurfaceLevel(context, destIndex.getTarget(), destIndex.getLevelIndex(), true, &lower));
    524 
    525    ASSERT(upper && lower);
    526    return mRenderer->boxFilter(GetImplAs<Context9>(context), upper.Get(), lower.Get());
    527 }
    528 
    529 angle::Result TextureStorage9_Cube::getBaseTexture(const gl::Context *context,
    530                                                   IDirect3DBaseTexture9 **outTexture)
    531 {
    532    // if the size is not positive this should be treated as an incomplete texture
    533    // we handle that here by skipping the d3d texture creation
    534    if (mTexture == nullptr && mTextureWidth > 0 && mTextureHeight > 0)
    535    {
    536        ASSERT(mMipLevels > 0);
    537        ASSERT(mTextureWidth == mTextureHeight);
    538 
    539        IDirect3DDevice9 *device = mRenderer->getDevice();
    540        HRESULT result           = device->CreateCubeTexture(
    541            static_cast<unsigned int>(mTextureWidth), static_cast<unsigned int>(mMipLevels),
    542            getUsage(), mTextureFormat, getPool(), &mTexture, nullptr);
    543        ANGLE_TRY_HR(GetImplAs<Context9>(context), result, "Failed to create cube storage texture");
    544    }
    545 
    546    *outTexture = mTexture;
    547    return angle::Result::Continue;
    548 }
    549 
    550 angle::Result TextureStorage9_Cube::copyToStorage(const gl::Context *context,
    551                                                  TextureStorage *destStorage)
    552 {
    553    ASSERT(destStorage);
    554 
    555    TextureStorage9_Cube *dest9 = GetAs<TextureStorage9_Cube>(destStorage);
    556 
    557    int levels = getLevelCount();
    558    for (gl::TextureTarget face : gl::AllCubeFaceTextureTargets())
    559    {
    560        for (int i = 0; i < levels; i++)
    561        {
    562            angle::ComPtr<IDirect3DSurface9> srcSurf = nullptr;
    563            ANGLE_TRY(getSurfaceLevel(context, face, i, false, &srcSurf));
    564 
    565            angle::ComPtr<IDirect3DSurface9> dstSurf = nullptr;
    566            ANGLE_TRY(dest9->getSurfaceLevel(context, face, i, true, &dstSurf));
    567 
    568            ANGLE_TRY(
    569                mRenderer->copyToRenderTarget(context, dstSurf.Get(), srcSurf.Get(), isManaged()));
    570        }
    571    }
    572 
    573    return angle::Result::Continue;
    574 }
    575 }  // namespace rx