xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/VkImageImageSiblingVk.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // VkImageImageSiblingVk.cpp: Implements VkImageImageSiblingVk.
8 
9 #include "libANGLE/renderer/vulkan/VkImageImageSiblingVk.h"
10 
11 #include "libANGLE/Display.h"
12 #include "libANGLE/renderer/vulkan/DisplayVk.h"
13 #include "libANGLE/renderer/vulkan/vk_renderer.h"
14 
15 namespace rx
16 {
17 
VkImageImageSiblingVk(EGLClientBuffer buffer,const egl::AttributeMap & attribs)18 VkImageImageSiblingVk::VkImageImageSiblingVk(EGLClientBuffer buffer,
19                                              const egl::AttributeMap &attribs)
20 {
21     mVkImage.setHandle(*reinterpret_cast<VkImage *>(buffer));
22 
23     ASSERT(attribs.contains(EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE));
24     ASSERT(attribs.contains(EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE));
25     uint64_t hi = static_cast<uint64_t>(attribs.get(EGL_VULKAN_IMAGE_CREATE_INFO_HI_ANGLE));
26     uint64_t lo = static_cast<uint64_t>(attribs.get(EGL_VULKAN_IMAGE_CREATE_INFO_LO_ANGLE));
27     const VkImageCreateInfo *info =
28         reinterpret_cast<const VkImageCreateInfo *>((hi << 32) | (lo & 0xffffffff));
29     ASSERT(info->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
30     mVkImageInfo = *info;
31     // TODO(penghuang): support extensions.
32     mVkImageInfo.pNext = nullptr;
33     mInternalFormat = static_cast<GLenum>(attribs.get(EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, GL_NONE));
34 }
35 
36 VkImageImageSiblingVk::~VkImageImageSiblingVk() = default;
37 
initialize(const egl::Display * display)38 egl::Error VkImageImageSiblingVk::initialize(const egl::Display *display)
39 {
40     DisplayVk *displayVk = vk::GetImpl(display);
41     return angle::ToEGL(initImpl(displayVk), EGL_BAD_PARAMETER);
42 }
43 
initImpl(DisplayVk * displayVk)44 angle::Result VkImageImageSiblingVk::initImpl(DisplayVk *displayVk)
45 {
46     vk::Renderer *renderer = displayVk->getRenderer();
47 
48     const angle::FormatID formatID = vk::GetFormatIDFromVkFormat(mVkImageInfo.format);
49     ANGLE_VK_CHECK(displayVk, formatID != angle::FormatID::NONE, VK_ERROR_FORMAT_NOT_SUPPORTED);
50 
51     const vk::Format &vkFormat = renderer->getFormat(formatID);
52     const vk::ImageAccess imageAccess =
53         isRenderable(nullptr) ? vk::ImageAccess::Renderable : vk::ImageAccess::SampleOnly;
54     const angle::FormatID actualImageFormatID = vkFormat.getActualImageFormatID(imageAccess);
55     const angle::Format &format               = angle::Format::Get(actualImageFormatID);
56 
57     angle::FormatID intendedFormatID;
58     if (mInternalFormat != GL_NONE)
59     {
60         // If EGL_TEXTURE_INTERNAL_FORMAT_ANGLE is provided for eglCreateImageKHR(),
61         // the provided format will be used for mFormat and intendedFormat.
62         GLenum type      = gl::GetSizedInternalFormatInfo(format.glInternalFormat).type;
63         mFormat          = gl::Format(mInternalFormat, type);
64         intendedFormatID = angle::Format::InternalFormatToID(mFormat.info->sizedInternalFormat);
65     }
66     else
67     {
68         intendedFormatID = vkFormat.getIntendedFormatID();
69         mFormat          = gl::Format(format.glInternalFormat);
70     }
71 
72     // Create the image
73     constexpr bool kIsRobustInitEnabled = false;
74     mImage                              = new vk::ImageHelper();
75     mImage->init2DWeakReference(displayVk, mVkImage.release(), getSize(), false, intendedFormatID,
76                                 actualImageFormatID, mVkImageInfo.flags, mVkImageInfo.usage, 1,
77                                 kIsRobustInitEnabled);
78 
79     return angle::Result::Continue;
80 }
81 
onDestroy(const egl::Display * display)82 void VkImageImageSiblingVk::onDestroy(const egl::Display *display)
83 {
84     ASSERT(mImage == nullptr);
85 }
86 
getFormat() const87 gl::Format VkImageImageSiblingVk::getFormat() const
88 {
89     return mFormat;
90 }
91 
isRenderable(const gl::Context * context) const92 bool VkImageImageSiblingVk::isRenderable(const gl::Context *context) const
93 {
94     return mVkImageInfo.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
95 }
96 
isTexturable(const gl::Context * context) const97 bool VkImageImageSiblingVk::isTexturable(const gl::Context *context) const
98 {
99     return mVkImageInfo.usage & VK_IMAGE_USAGE_SAMPLED_BIT;
100 }
101 
isYUV() const102 bool VkImageImageSiblingVk::isYUV() const
103 {
104     return false;
105 }
106 
hasProtectedContent() const107 bool VkImageImageSiblingVk::hasProtectedContent() const
108 {
109     return false;
110 }
111 
getSize() const112 gl::Extents VkImageImageSiblingVk::getSize() const
113 {
114     return gl::Extents(mVkImageInfo.extent.width, mVkImageInfo.extent.height,
115                        mVkImageInfo.extent.depth);
116 }
117 
getSamples() const118 size_t VkImageImageSiblingVk::getSamples() const
119 {
120     return 0;
121 }
122 
123 // ExternalImageSiblingVk interface
getImage() const124 vk::ImageHelper *VkImageImageSiblingVk::getImage() const
125 {
126     return mImage;
127 }
128 
release(vk::Renderer * renderer)129 void VkImageImageSiblingVk::release(vk::Renderer *renderer)
130 {
131     if (mImage != nullptr)
132     {
133         // TODO: Handle the case where the EGLImage is used in two contexts not in the same share
134         // group.  https://issuetracker.google.com/169868803
135         mImage->resetImageWeakReference();
136         mImage->destroy(renderer);
137         SafeDelete(mImage);
138     }
139 }
140 
141 }  // namespace rx
142