blob: bf16c6cec7effe56f296018b45db04d50449c141 [file] [log] [blame]
//
// 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;
}
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 angle::FormatID intendedFormatID = vkFormat.getIntendedFormatID();
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);
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->resetImageWeakReference();
mImage->destroy(renderer);
SafeDelete(mImage);
}
}
} // namespace rx