Edit

kc3-lang/angle/src/libANGLE/renderer/d3d/RenderbufferD3D.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2017-10-03 09:01:44
    Hash : 05b35b21
    Message : D3D11: Lazy robust resource init. This patch moves the robust resource init logic to the GL front-end. Instead of initializing texture resources immediately on creation in D3D11, it defers the clear until before a draw call in some cases, or skips the update if we can determine if a texture (or other resource) has been fully initialized. Currently lazy init is only implemented for Textures, Renderbuffers, and Surfaces. Various places where lazy resource init is triggered: * Framebuffer operations (Draw, Blit, CopyTexImage, Clear, ReadPixels) * Texture operations (SubImage, GenerateMipmap, CopyTexImage) Some efficiency gains remain to be implemented, such as when a SubImage call fills the entire object. Similarly for Blit, and a few other operations. In these cases we can skip lazy init as an optimization. Edge cases with EGLImage are mostly untested. BUG=angleproject:2107 Change-Id: I2bf3a69b1eae0d4feeb5b17daca23451f1037be8 Reviewed-on: https://chromium-review.googlesource.com/576058 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>

  • src/libANGLE/renderer/d3d/RenderbufferD3D.cpp
  • //
    // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    // RenderbufferD3d.cpp: Implements the RenderbufferD3D class, a specialization of RenderbufferImpl
    
    
    #include "libANGLE/renderer/d3d/RenderbufferD3D.h"
    
    #include "libANGLE/Image.h"
    #include "libANGLE/renderer/d3d/EGLImageD3D.h"
    #include "libANGLE/renderer/d3d/RendererD3D.h"
    #include "libANGLE/renderer/d3d/RenderTargetD3D.h"
    
    namespace rx
    {
    RenderbufferD3D::RenderbufferD3D(RendererD3D *renderer)
        : mRenderer(renderer), mRenderTarget(nullptr), mImage(nullptr)
    {
    }
    
    RenderbufferD3D::~RenderbufferD3D()
    {
        SafeDelete(mRenderTarget);
        mImage = nullptr;
    }
    
    gl::Error RenderbufferD3D::onDestroy(const gl::Context *context)
    {
        deleteRenderTarget(context);
        return gl::NoError();
    }
    
    gl::Error RenderbufferD3D::setStorage(const gl::Context *context,
                                          GLenum internalformat,
                                          size_t width,
                                          size_t height)
    {
        return setStorageMultisample(context, 0, internalformat, width, height);
    }
    
    gl::Error RenderbufferD3D::setStorageMultisample(const gl::Context *context,
                                                     size_t samples,
                                                     GLenum internalformat,
                                                     size_t width,
                                                     size_t height)
    {
        // If the renderbuffer parameters are queried, the calling function
        // will expect one of the valid renderbuffer formats for use in
        // glRenderbufferStorage, but we should create depth and stencil buffers
        // as DEPTH24_STENCIL8
        GLenum creationFormat = internalformat;
        if (internalformat == GL_DEPTH_COMPONENT16 || internalformat == GL_STENCIL_INDEX8)
        {
            creationFormat = GL_DEPTH24_STENCIL8_OES;
        }
    
        // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
        // the specified storage.
        // Because ES 3.0 already knows the exact number of supported samples, it would already have been
        // validated and generated GL_INVALID_VALUE.
        const gl::TextureCaps &formatCaps = mRenderer->getNativeTextureCaps().get(creationFormat);
        if (samples > formatCaps.getMaxSamples())
        {
            return gl::OutOfMemory() << "Renderbuffer format does not support " << samples
                                     << " samples, " << formatCaps.getMaxSamples()
                                     << " is the maximum.";
        }
    
        RenderTargetD3D *newRT = nullptr;
        ANGLE_TRY(mRenderer->createRenderTarget(static_cast<int>(width), static_cast<int>(height),
                                                creationFormat, static_cast<GLsizei>(samples), &newRT));
    
        deleteRenderTarget(context);
        mImage        = nullptr;
        mRenderTarget = newRT;
    
        return gl::NoError();
    }
    
    gl::Error RenderbufferD3D::setStorageEGLImageTarget(const gl::Context *context, egl::Image *image)
    {
        mImage = GetImplAs<EGLImageD3D>(image);
        deleteRenderTarget(context);
    
        return gl::NoError();
    }
    
    gl::Error RenderbufferD3D::getRenderTarget(const gl::Context *context,
                                               RenderTargetD3D **outRenderTarget)
    {
        if (mImage)
        {
            return mImage->getRenderTarget(context, outRenderTarget);
        }
        else
        {
            *outRenderTarget = mRenderTarget;
            return gl::NoError();
        }
    }
    
    gl::Error RenderbufferD3D::getAttachmentRenderTarget(const gl::Context *context,
                                                         GLenum /*binding*/,
                                                         const gl::ImageIndex & /*imageIndex*/,
                                                         FramebufferAttachmentRenderTarget **rtOut)
    {
        return getRenderTarget(context, reinterpret_cast<RenderTargetD3D **>(rtOut));
    }
    
    void RenderbufferD3D::deleteRenderTarget(const gl::Context *context)
    {
        if (mRenderTarget)
        {
            mRenderTarget->signalDirty(context);
            SafeDelete(mRenderTarget);
        }
    }
    
    gl::Error RenderbufferD3D::initializeContents(const gl::Context *context,
                                                  const gl::ImageIndex &imageIndex)
    {
        RenderTargetD3D *renderTarget = nullptr;
        ANGLE_TRY(getRenderTarget(context, &renderTarget));
        return mRenderer->initRenderTarget(renderTarget);
    }
    
    }  // namespace rx