Hash :
c649979b
Author :
Date :
2022-05-17T20:53:16
Create EGLImage from VkImage correctly with non sized format Sometime, client may pass in non-sized internal formats (GL_BGRA, GL_RED and GL_RG) for creating EGLImage from VkImage. For those formats, angle::Format::InternalFormatToID(internalFormat) can not return valid result. Fix the problem, by converting internalFormat to sized format first. Bug: chromium:1326658 Change-Id: Id88e0614a2a9f55aabac116ea95ed8cec02672a3 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3652741 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Peng Huang <penghuang@chromium.org>
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
//
// Copyright 2021 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.
//
// VkImageImageSiblingVk.cpp: Implements VkImageImageSiblingVk.
#include "libANGLE/renderer/vulkan/VkImageImageSiblingVk.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h"
namespace rx
{
VkImageImageSiblingVk::VkImageImageSiblingVk(EGLClientBuffer buffer,
const egl::AttributeMap &attribs)
{
mVkImage.setHandle(*reinterpret_cast<VkImage *>(buffer));
ASSERT(attribs.contains(EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE));
ASSERT(attribs.contains(EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE));
uint64_t hi = static_cast<uint64_t>(attribs.get(EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE));
uint64_t lo = static_cast<uint64_t>(attribs.get(EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE));
const VkImageCreateInfo *info =
reinterpret_cast<const VkImageCreateInfo *>((hi << 32) | (lo & 0xffffffff));
ASSERT(info->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
mVkImageInfo = *info;
// TODO(penghuang): support extensions.
mVkImageInfo.pNext = nullptr;
mInternalFormat = static_cast<GLenum>(attribs.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_NONE));
}
VkImageImageSiblingVk::~VkImageImageSiblingVk() = default;
egl::Error VkImageImageSiblingVk::initialize(const egl::Display *display)
{
DisplayVk *displayVk = vk::GetImpl(display);
return angle::ToEGL(initImpl(displayVk), displayVk, EGL_BAD_PARAMETER);
}
angle::Result VkImageImageSiblingVk::initImpl(DisplayVk *displayVk)
{
RendererVk *renderer = displayVk->getRenderer();
const angle::FormatID formatID = vk::GetFormatIDFromVkFormat(mVkImageInfo.format);
ANGLE_VK_CHECK(displayVk, formatID != angle::FormatID::NONE, VK_ERROR_FORMAT_NOT_SUPPORTED);
const vk::Format &vkFormat = renderer->getFormat(formatID);
const vk::ImageAccess imageAccess =
isRenderable(nullptr) ? vk::ImageAccess::Renderable : vk::ImageAccess::SampleOnly;
const angle::FormatID actualImageFormatID = vkFormat.getActualImageFormatID(imageAccess);
const angle::Format &format = angle::Format::Get(actualImageFormatID);
angle::FormatID intendedFormatID;
if (mInternalFormat != GL_NONE)
{
// If EGL_TEXTURE_INTERNAL_FORMAT_ANGLE is provided for eglCreateImageKHR(),
// the provided format will be used for mFormat and intendedFormat.
GLenum type = gl::GetSizedInternalFormatInfo(format.glInternalFormat).type;
mFormat = gl::Format(mInternalFormat, type);
intendedFormatID = angle::Format::InternalFormatToID(mFormat.info->sizedInternalFormat);
}
else
{
intendedFormatID = vkFormat.getIntendedFormatID();
mFormat = gl::Format(format.glInternalFormat);
}
// Create the image
mImage = new vk::ImageHelper();
constexpr bool kIsRobustInitEnabled = false;
mImage->init2DWeakReference(displayVk, mVkImage.release(), getSize(), false, intendedFormatID,
actualImageFormatID, 1, kIsRobustInitEnabled);
return angle::Result::Continue;
}
void VkImageImageSiblingVk::onDestroy(const egl::Display *display)
{
ASSERT(mImage == nullptr);
}
gl::Format VkImageImageSiblingVk::getFormat() const
{
return mFormat;
}
bool VkImageImageSiblingVk::isRenderable(const gl::Context *context) const
{
return mVkImageInfo.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
}
bool VkImageImageSiblingVk::isTexturable(const gl::Context *context) const
{
return mVkImageInfo.usage & VK_IMAGE_USAGE_SAMPLED_BIT;
}
bool VkImageImageSiblingVk::isYUV() const
{
return false;
}
bool VkImageImageSiblingVk::hasProtectedContent() const
{
return false;
}
gl::Extents VkImageImageSiblingVk::getSize() const
{
return gl::Extents(mVkImageInfo.extent.width, mVkImageInfo.extent.height,
mVkImageInfo.extent.depth);
}
size_t VkImageImageSiblingVk::getSamples() const
{
return 0;
}
// ExternalImageSiblingVk interface
vk::ImageHelper *VkImageImageSiblingVk::getImage() const
{
return mImage;
}
void VkImageImageSiblingVk::release(RendererVk *renderer)
{
if (mImage != nullptr)
{
// TODO: Handle the case where the EGLImage is used in two contexts not in the same share
// group. https://issuetracker.google.com/169868803
mImage->releaseImageAndViewGarbage(renderer);
mImage->resetImageWeakReference();
mImage->destroy(renderer);
SafeDelete(mImage);
}
}
} // namespace rx