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/RendererVk.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), displayVk, EGL_BAD_PARAMETER);
42 }
43
initImpl(DisplayVk * displayVk)44 angle::Result VkImageImageSiblingVk::initImpl(DisplayVk *displayVk)
45 {
46 RendererVk *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 intendedFormatID = angle::Format::InternalFormatToID(mInternalFormat);
63 GLenum type = gl::GetSizedInternalFormatInfo(format.glInternalFormat).type;
64 mFormat = gl::Format(mInternalFormat, type);
65 }
66 else
67 {
68 intendedFormatID = vkFormat.getIntendedFormatID();
69 mFormat = gl::Format(format.glInternalFormat);
70 }
71
72 // Create the image
73 mImage = new vk::ImageHelper();
74 constexpr bool kIsRobustInitEnabled = false;
75 mImage->init2DWeakReference(displayVk, mVkImage.release(), getSize(), false, intendedFormatID,
76 actualImageFormatID, 1, kIsRobustInitEnabled);
77
78 return angle::Result::Continue;
79 }
80
onDestroy(const egl::Display * display)81 void VkImageImageSiblingVk::onDestroy(const egl::Display *display)
82 {
83 ASSERT(mImage == nullptr);
84 }
85
getFormat() const86 gl::Format VkImageImageSiblingVk::getFormat() const
87 {
88 return mFormat;
89 }
90
isRenderable(const gl::Context * context) const91 bool VkImageImageSiblingVk::isRenderable(const gl::Context *context) const
92 {
93 return mVkImageInfo.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
94 }
95
isTexturable(const gl::Context * context) const96 bool VkImageImageSiblingVk::isTexturable(const gl::Context *context) const
97 {
98 return mVkImageInfo.usage & VK_IMAGE_USAGE_SAMPLED_BIT;
99 }
100
isYUV() const101 bool VkImageImageSiblingVk::isYUV() const
102 {
103 return false;
104 }
105
hasProtectedContent() const106 bool VkImageImageSiblingVk::hasProtectedContent() const
107 {
108 return false;
109 }
110
getSize() const111 gl::Extents VkImageImageSiblingVk::getSize() const
112 {
113 return gl::Extents(mVkImageInfo.extent.width, mVkImageInfo.extent.height,
114 mVkImageInfo.extent.depth);
115 }
116
getSamples() const117 size_t VkImageImageSiblingVk::getSamples() const
118 {
119 return 0;
120 }
121
122 // ExternalImageSiblingVk interface
getImage() const123 vk::ImageHelper *VkImageImageSiblingVk::getImage() const
124 {
125 return mImage;
126 }
127
release(RendererVk * renderer)128 void VkImageImageSiblingVk::release(RendererVk *renderer)
129 {
130 if (mImage != nullptr)
131 {
132 // TODO: Handle the case where the EGLImage is used in two contexts not in the same share
133 // group. https://issuetracker.google.com/169868803
134 mImage->releaseImageAndViewGarbage(renderer);
135 mImage->resetImageWeakReference();
136 mImage->destroy(renderer);
137 SafeDelete(mImage);
138 }
139 }
140
141 } // namespace rx
142