Hash :
052167bc
Author :
Date :
2019-08-13T14:09:04
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>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
//
// 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