Edit

kc3-lang/angle/src/libANGLE/renderer/vulkan/ImageVk.cpp

Branch :

  • Show log

    Commit

  • Author : Xinyi He
    Date : 2019-08-13 14:09:04
    Hash : 052167bc
    Message : Vulkan: Mipmap is unconditionally enabled in ANGLE ANGLE always enables the Mipmap. The fix does redefining the image with mipmaps and replace the origin one only when it is necessary. Bug: angleproject:3737 Change-Id: Ia33a16fd7feae303fb114988059c4eec58c4232d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1750627 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Cody Northrop <cnorthrop@google.com> Reviewed-by: Ian Elliott <ianelliott@google.com>

  • src/libANGLE/renderer/vulkan/ImageVk.cpp
  • //
    // Copyright 2016 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.
    //
    // ImageVk.cpp:
    //    Implements the class methods for ImageVk.
    //
    
    #include "libANGLE/renderer/vulkan/ImageVk.h"
    
    #include "common/debug.h"
    #include "libANGLE/Context.h"
    #include "libANGLE/Display.h"
    #include "libANGLE/renderer/vulkan/ContextVk.h"
    #include "libANGLE/renderer/vulkan/DisplayVk.h"
    #include "libANGLE/renderer/vulkan/RenderbufferVk.h"
    #include "libANGLE/renderer/vulkan/TextureVk.h"
    #include "libANGLE/renderer/vulkan/vk_utils.h"
    
    namespace rx
    {
    
    ImageVk::ImageVk(const egl::ImageState &state, const gl::Context *context)
        : ImageImpl(state), mImageLevel(0), mOwnsImage(false), mImage(nullptr), mContext(context)
    {}
    
    ImageVk::~ImageVk() {}
    
    void ImageVk::onDestroy(const egl::Display *display)
    {
        DisplayVk *displayVk = vk::GetImpl(display);
        RendererVk *renderer = displayVk->getRenderer();
    
        if (mImage != nullptr && mOwnsImage)
        {
            mImage->releaseImage(renderer);
            mImage->releaseStagingBuffer(renderer);
            SafeDelete(mImage);
        }
        else if (egl::IsExternalImageTarget(mState.target))
        {
            ASSERT(mState.source != nullptr);
            ExternalImageSiblingVk *externalImageSibling =
                GetImplAs<ExternalImageSiblingVk>(GetAs<egl::ExternalImageSibling>(mState.source));
            externalImageSibling->release(renderer);
            mImage = nullptr;
        }
    }
    
    egl::Error ImageVk::initialize(const egl::Display *display)
    {
        if (egl::IsTextureTarget(mState.target))
        {
            TextureVk *textureVk = GetImplAs<TextureVk>(GetAs<gl::Texture>(mState.source));
    
            // Make sure the texture has created its backing storage
            ASSERT(mContext != nullptr);
            ContextVk *contextVk = vk::GetImpl(mContext);
            ANGLE_TRY(ResultToEGL(
                textureVk->ensureImageInitialized(contextVk, ImageMipLevels::EnabledLevels)));
    
            mImage = &textureVk->getImage();
    
            // The staging buffer for a texture source should already be initialized
    
            mOwnsImage = false;
    
            mImageTextureType = mState.imageIndex.getType();
            mImageLevel       = mState.imageIndex.getLevelIndex();
            mImageLayer       = mState.imageIndex.hasLayer() ? mState.imageIndex.getLayerIndex() : 0;
        }
        else
        {
            RendererVk *renderer = nullptr;
            if (egl::IsRenderbufferTarget(mState.target))
            {
                RenderbufferVk *renderbufferVk =
                    GetImplAs<RenderbufferVk>(GetAs<gl::Renderbuffer>(mState.source));
                mImage = renderbufferVk->getImage();
    
                ASSERT(mContext != nullptr);
                renderer = vk::GetImpl(mContext)->getRenderer();
            }
            else if (egl::IsExternalImageTarget(mState.target))
            {
                const ExternalImageSiblingVk *externalImageSibling =
                    GetImplAs<ExternalImageSiblingVk>(GetAs<egl::ExternalImageSibling>(mState.source));
                mImage = externalImageSibling->getImage();
    
                ASSERT(mContext == nullptr);
                renderer = vk::GetImpl(display)->getRenderer();
            }
            else
            {
                UNREACHABLE();
                return egl::EglBadAccess();
            }
    
            // Make sure a staging buffer is ready to use to upload data
            mImage->initStagingBuffer(renderer, mImage->getFormat(), vk::kStagingBufferFlags,
                                      vk::kStagingBufferSize);
    
            mOwnsImage = false;
    
            mImageTextureType = gl::TextureType::_2D;
            mImageLevel       = 0;
            mImageLayer       = 0;
        }
    
        // mContext is no longer needed, make sure it's not used by accident.
        mContext = nullptr;
    
        return egl::NoError();
    }
    
    angle::Result ImageVk::orphan(const gl::Context *context, egl::ImageSibling *sibling)
    {
        if (sibling == mState.source)
        {
            if (egl::IsTextureTarget(mState.target))
            {
                TextureVk *textureVk = GetImplAs<TextureVk>(GetAs<gl::Texture>(mState.source));
                ASSERT(mImage == &textureVk->getImage());
                textureVk->releaseOwnershipOfImage(context);
                mOwnsImage = true;
            }
            else if (egl::IsRenderbufferTarget(mState.target))
            {
                RenderbufferVk *renderbufferVk =
                    GetImplAs<RenderbufferVk>(GetAs<gl::Renderbuffer>(mState.source));
                ASSERT(mImage == renderbufferVk->getImage());
                renderbufferVk->releaseOwnershipOfImage(context);
                mOwnsImage = true;
            }
            else
            {
                ANGLE_VK_UNREACHABLE(vk::GetImpl(context));
                return angle::Result::Stop;
            }
        }
    
        // Grab a fence from the releasing context to know when the image is no longer used
        ASSERT(context != nullptr);
        ContextVk *contextVk = vk::GetImpl(context);
    
        // Flush the context to make sure the fence has been submitted.
        ANGLE_TRY(contextVk->flushImpl(nullptr));
    
        return angle::Result::Continue;
    }
    
    }  // namespace rx