xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2019 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 #include "libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h"
8 
9 #include "libANGLE/Context.h"
10 #include "libANGLE/Error.h"
11 #include "libANGLE/angletypes.h"
12 #include "libANGLE/formatutils.h"
13 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
14 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
15 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
16 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
17 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
18 
19 namespace rx
20 {
ExternalImageSiblingImpl11(Renderer11 * renderer,EGLClientBuffer buffer,const egl::AttributeMap & attribs)21 ExternalImageSiblingImpl11::ExternalImageSiblingImpl11(Renderer11 *renderer,
22                                                        EGLClientBuffer buffer,
23                                                        const egl::AttributeMap &attribs)
24     : mRenderer(renderer), mBuffer(buffer), mAttribs(attribs)
25 {}
26 
~ExternalImageSiblingImpl11()27 ExternalImageSiblingImpl11::~ExternalImageSiblingImpl11() {}
28 
initialize(const egl::Display * display)29 egl::Error ExternalImageSiblingImpl11::initialize(const egl::Display *display)
30 {
31     const angle::Format *angleFormat = nullptr;
32     ANGLE_TRY(mRenderer->getD3DTextureInfo(nullptr, static_cast<IUnknown *>(mBuffer), mAttribs,
33                                            &mWidth, &mHeight, &mSamples, &mFormat, &angleFormat,
34                                            &mArraySlice));
35     ID3D11Texture2D *texture =
36         d3d11::DynamicCastComObject<ID3D11Texture2D>(static_cast<IUnknown *>(mBuffer));
37     ASSERT(texture != nullptr);
38 
39     D3D11_TEXTURE2D_DESC textureDesc = {};
40     texture->GetDesc(&textureDesc);
41 
42     if (d3d11::IsSupportedMultiplanarFormat(textureDesc.Format))
43     {
44         if (!mAttribs.contains(EGL_D3D11_TEXTURE_PLANE_ANGLE))
45         {
46             return egl::EglBadParameter()
47                    << "EGL_D3D11_TEXTURE_PLANE_ANGLE must be specified for YUV textures.";
48         }
49 
50         EGLint plane = mAttribs.getAsInt(EGL_D3D11_TEXTURE_PLANE_ANGLE);
51         if (plane < 0 || plane > 1)
52         {
53             return egl::EglBadParameter() << "Invalid client buffer texture plane: " << plane;
54         }
55 
56         mTexture.set(texture, d3d11::GetYUVPlaneFormat(textureDesc.Format, plane));
57     }
58     else
59     {
60         // TextureHelper11 will release texture on destruction.
61         mTexture.set(texture, d3d11::Format::Get(angleFormat->glInternalFormat,
62                                                  mRenderer->getRenderer11DeviceCaps()));
63     }
64 
65     IDXGIResource *resource = d3d11::DynamicCastComObject<IDXGIResource>(mTexture.get());
66     ASSERT(resource != nullptr);
67     DXGI_USAGE resourceUsage = 0;
68     resource->GetUsage(&resourceUsage);
69     SafeRelease(resource);
70 
71     mIsRenderable = (textureDesc.BindFlags & D3D11_BIND_RENDER_TARGET) &&
72                     (resourceUsage & DXGI_USAGE_RENDER_TARGET_OUTPUT) &&
73                     !(resourceUsage & DXGI_USAGE_READ_ONLY);
74 
75     mIsTexturable = (textureDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) &&
76                     (resourceUsage & DXGI_USAGE_SHADER_INPUT);
77 
78     mIsTextureArray = (textureDesc.ArraySize > 1);
79 
80     return egl::NoError();
81 }
82 
getFormat() const83 gl::Format ExternalImageSiblingImpl11::getFormat() const
84 {
85     return mFormat;
86 }
87 
isRenderable(const gl::Context * context) const88 bool ExternalImageSiblingImpl11::isRenderable(const gl::Context *context) const
89 {
90     return mIsRenderable;
91 }
92 
isTexturable(const gl::Context * context) const93 bool ExternalImageSiblingImpl11::isTexturable(const gl::Context *context) const
94 {
95     return mIsTexturable;
96 }
97 
isYUV() const98 bool ExternalImageSiblingImpl11::isYUV() const
99 {
100     return false;
101 }
102 
hasProtectedContent() const103 bool ExternalImageSiblingImpl11::hasProtectedContent() const
104 {
105     return false;
106 }
107 
getSize() const108 gl::Extents ExternalImageSiblingImpl11::getSize() const
109 {
110     return gl::Extents(mWidth, mHeight, 1);
111 }
112 
getSamples() const113 size_t ExternalImageSiblingImpl11::getSamples() const
114 {
115     return mSamples;
116 }
117 
getAttachmentRenderTarget(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex,GLsizei samples,FramebufferAttachmentRenderTarget ** rtOut)118 angle::Result ExternalImageSiblingImpl11::getAttachmentRenderTarget(
119     const gl::Context *context,
120     GLenum binding,
121     const gl::ImageIndex &imageIndex,
122     GLsizei samples,
123     FramebufferAttachmentRenderTarget **rtOut)
124 {
125     ANGLE_TRY(createRenderTarget(context));
126     *rtOut = mRenderTarget.get();
127     return angle::Result::Continue;
128 }
129 
initializeContents(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex)130 angle::Result ExternalImageSiblingImpl11::initializeContents(const gl::Context *context,
131                                                              GLenum binding,
132                                                              const gl::ImageIndex &imageIndex)
133 {
134     UNREACHABLE();
135     return angle::Result::Stop;
136 }
137 
createRenderTarget(const gl::Context * context)138 angle::Result ExternalImageSiblingImpl11::createRenderTarget(const gl::Context *context)
139 {
140     if (mRenderTarget)
141         return angle::Result::Continue;
142 
143     Context11 *context11            = GetImplAs<Context11>(context);
144     const d3d11::Format &formatInfo = mTexture.getFormatSet();
145 
146     d3d11::RenderTargetView rtv;
147     if (mIsRenderable)
148     {
149         D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
150         rtvDesc.Format = formatInfo.rtvFormat;
151         if (mIsTextureArray)
152         {
153             if (mSamples == 0)
154             {
155                 rtvDesc.ViewDimension                  = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
156                 rtvDesc.Texture2DArray.MipSlice        = 0;
157                 rtvDesc.Texture2DArray.FirstArraySlice = mArraySlice;
158                 rtvDesc.Texture2DArray.ArraySize       = 1;
159             }
160             else
161             {
162                 rtvDesc.ViewDimension                    = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
163                 rtvDesc.Texture2DMSArray.FirstArraySlice = mArraySlice;
164                 rtvDesc.Texture2DMSArray.ArraySize       = 1;
165             }
166         }
167         else
168         {
169             if (mSamples == 0)
170             {
171                 rtvDesc.ViewDimension      = D3D11_RTV_DIMENSION_TEXTURE2D;
172                 rtvDesc.Texture2D.MipSlice = 0;
173             }
174             else
175             {
176                 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
177             }
178         }
179 
180         ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, mTexture.get(), &rtv));
181         rtv.setInternalName("getAttachmentRenderTarget.RTV");
182     }
183 
184     d3d11::SharedSRV srv;
185     if (mIsTexturable)
186     {
187         D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
188         srvDesc.Format = formatInfo.srvFormat;
189         if (mIsTextureArray)
190         {
191             if (mSamples == 0)
192             {
193                 srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
194                 srvDesc.Texture2DArray.MostDetailedMip = 0;
195                 srvDesc.Texture2DArray.MipLevels       = 1;
196                 srvDesc.Texture2DArray.FirstArraySlice = mArraySlice;
197                 srvDesc.Texture2DArray.ArraySize       = 1;
198             }
199             else
200             {
201                 srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
202                 srvDesc.Texture2DArray.FirstArraySlice = mArraySlice;
203                 srvDesc.Texture2DArray.ArraySize       = 1;
204             }
205         }
206         else
207         {
208             if (mSamples == 0)
209             {
210                 srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE2D;
211                 srvDesc.Texture2D.MostDetailedMip = 0;
212                 srvDesc.Texture2D.MipLevels       = 1;
213             }
214             else
215             {
216                 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
217             }
218         }
219 
220         ANGLE_TRY(mRenderer->allocateResource(context11, srvDesc, mTexture.get(), &srv));
221         srv.setInternalName("getAttachmentRenderTarget.SRV");
222     }
223     d3d11::SharedSRV blitSrv = srv.makeCopy();
224 
225     mRenderTarget = std::make_unique<TextureRenderTarget11>(
226         std::move(rtv), mTexture, std::move(srv), std::move(blitSrv), mFormat.info->internalFormat,
227         formatInfo, mWidth, mHeight, 1, mSamples);
228     return angle::Result::Continue;
229 }
230 
231 }  // namespace rx
232