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/texture_format_table.h"
17 
18 namespace rx
19 {
ExternalImageSiblingImpl11(Renderer11 * renderer,EGLClientBuffer buffer,const egl::AttributeMap & attribs)20 ExternalImageSiblingImpl11::ExternalImageSiblingImpl11(Renderer11 *renderer,
21                                                        EGLClientBuffer buffer,
22                                                        const egl::AttributeMap &attribs)
23     : mRenderer(renderer), mBuffer(buffer), mAttribs(attribs)
24 {}
25 
~ExternalImageSiblingImpl11()26 ExternalImageSiblingImpl11::~ExternalImageSiblingImpl11() {}
27 
initialize(const egl::Display * display)28 egl::Error ExternalImageSiblingImpl11::initialize(const egl::Display *display)
29 {
30     const angle::Format *angleFormat = nullptr;
31     ANGLE_TRY(mRenderer->getD3DTextureInfo(nullptr, static_cast<IUnknown *>(mBuffer), mAttribs,
32                                            &mWidth, &mHeight, &mSamples, &mFormat, &angleFormat));
33     ID3D11Texture2D *texture =
34         d3d11::DynamicCastComObject<ID3D11Texture2D>(static_cast<IUnknown *>(mBuffer));
35     ASSERT(texture != nullptr);
36     // TextureHelper11 will release texture on destruction.
37     mTexture.set(texture, d3d11::Format::Get(angleFormat->glInternalFormat,
38                                              mRenderer->getRenderer11DeviceCaps()));
39     D3D11_TEXTURE2D_DESC textureDesc = {};
40     mTexture.getDesc(&textureDesc);
41 
42     IDXGIResource *resource = d3d11::DynamicCastComObject<IDXGIResource>(mTexture.get());
43     ASSERT(resource != nullptr);
44     DXGI_USAGE resourceUsage = 0;
45     resource->GetUsage(&resourceUsage);
46     SafeRelease(resource);
47 
48     mIsRenderable = (textureDesc.BindFlags & D3D11_BIND_RENDER_TARGET) &&
49                     (resourceUsage & DXGI_USAGE_RENDER_TARGET_OUTPUT) &&
50                     !(resourceUsage & DXGI_USAGE_READ_ONLY);
51 
52     mIsTexturable = (textureDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) &&
53                     (resourceUsage & DXGI_USAGE_SHADER_INPUT);
54 
55     return egl::NoError();
56 }
57 
getFormat() const58 gl::Format ExternalImageSiblingImpl11::getFormat() const
59 {
60     return mFormat;
61 }
62 
isRenderable(const gl::Context * context) const63 bool ExternalImageSiblingImpl11::isRenderable(const gl::Context *context) const
64 {
65     return mIsRenderable;
66 }
67 
isTexturable(const gl::Context * context) const68 bool ExternalImageSiblingImpl11::isTexturable(const gl::Context *context) const
69 {
70     return mIsTexturable;
71 }
72 
getSize() const73 gl::Extents ExternalImageSiblingImpl11::getSize() const
74 {
75     return gl::Extents(mWidth, mHeight, 1);
76 }
77 
getSamples() const78 size_t ExternalImageSiblingImpl11::getSamples() const
79 {
80     return mSamples;
81 }
82 
getAttachmentRenderTarget(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex,GLsizei samples,FramebufferAttachmentRenderTarget ** rtOut)83 angle::Result ExternalImageSiblingImpl11::getAttachmentRenderTarget(
84     const gl::Context *context,
85     GLenum binding,
86     const gl::ImageIndex &imageIndex,
87     GLsizei samples,
88     FramebufferAttachmentRenderTarget **rtOut)
89 {
90     ANGLE_TRY(createRenderTarget(context));
91     *rtOut = mRenderTarget.get();
92     return angle::Result::Continue;
93 }
94 
initializeContents(const gl::Context * context,const gl::ImageIndex & imageIndex)95 angle::Result ExternalImageSiblingImpl11::initializeContents(const gl::Context *context,
96                                                              const gl::ImageIndex &imageIndex)
97 {
98     UNREACHABLE();
99     return angle::Result::Stop;
100 }
101 
createRenderTarget(const gl::Context * context)102 angle::Result ExternalImageSiblingImpl11::createRenderTarget(const gl::Context *context)
103 {
104     if (mRenderTarget)
105         return angle::Result::Continue;
106 
107     Context11 *context11            = GetImplAs<Context11>(context);
108     const d3d11::Format &formatInfo = mTexture.getFormatSet();
109 
110     d3d11::RenderTargetView rtv;
111     if (mIsRenderable)
112     {
113         D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
114         rtvDesc.Format = formatInfo.rtvFormat;
115         rtvDesc.ViewDimension =
116             mSamples == 0 ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
117         rtvDesc.Texture2D.MipSlice = 0;
118 
119         ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, mTexture.get(), &rtv));
120         rtv.setDebugName("getAttachmentRenderTarget.RTV");
121     }
122 
123     d3d11::SharedSRV srv;
124     if (mIsTexturable)
125     {
126         D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
127         srvDesc.Format = formatInfo.srvFormat;
128         srvDesc.ViewDimension =
129             mSamples == 0 ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
130         srvDesc.Texture2D.MostDetailedMip = 0;
131         srvDesc.Texture2D.MipLevels       = 1;
132 
133         ANGLE_TRY(mRenderer->allocateResource(context11, srvDesc, mTexture.get(), &srv));
134         srv.setDebugName("getAttachmentRenderTarget.SRV");
135     }
136     d3d11::SharedSRV blitSrv = srv.makeCopy();
137 
138     mRenderTarget = std::make_unique<TextureRenderTarget11>(
139         std::move(rtv), mTexture, std::move(srv), std::move(blitSrv), mFormat.info->internalFormat,
140         formatInfo, mWidth, mHeight, 1, mSamples);
141     return angle::Result::Continue;
142 }
143 
144 }  // namespace rx
145