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 &mArraySlice));
34 ID3D11Texture2D *texture =
35 d3d11::DynamicCastComObject<ID3D11Texture2D>(static_cast<IUnknown *>(mBuffer));
36 ASSERT(texture != nullptr);
37 // TextureHelper11 will release texture on destruction.
38 mTexture.set(texture, d3d11::Format::Get(angleFormat->glInternalFormat,
39 mRenderer->getRenderer11DeviceCaps()));
40 D3D11_TEXTURE2D_DESC textureDesc = {};
41 mTexture.getDesc(&textureDesc);
42
43 IDXGIResource *resource = d3d11::DynamicCastComObject<IDXGIResource>(mTexture.get());
44 ASSERT(resource != nullptr);
45 DXGI_USAGE resourceUsage = 0;
46 resource->GetUsage(&resourceUsage);
47 SafeRelease(resource);
48
49 mIsRenderable = (textureDesc.BindFlags & D3D11_BIND_RENDER_TARGET) &&
50 (resourceUsage & DXGI_USAGE_RENDER_TARGET_OUTPUT) &&
51 !(resourceUsage & DXGI_USAGE_READ_ONLY);
52
53 mIsTexturable = (textureDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) &&
54 (resourceUsage & DXGI_USAGE_SHADER_INPUT);
55
56 mIsTextureArray = (textureDesc.ArraySize > 1);
57
58 mYUV = (textureDesc.Format == DXGI_FORMAT_NV12 || textureDesc.Format == DXGI_FORMAT_P010 ||
59 textureDesc.Format == DXGI_FORMAT_P016);
60
61 return egl::NoError();
62 }
63
getFormat() const64 gl::Format ExternalImageSiblingImpl11::getFormat() const
65 {
66 return mFormat;
67 }
68
isRenderable(const gl::Context * context) const69 bool ExternalImageSiblingImpl11::isRenderable(const gl::Context *context) const
70 {
71 return mIsRenderable;
72 }
73
isTexturable(const gl::Context * context) const74 bool ExternalImageSiblingImpl11::isTexturable(const gl::Context *context) const
75 {
76 return mIsTexturable;
77 }
78
isYUV() const79 bool ExternalImageSiblingImpl11::isYUV() const
80 {
81 return mYUV;
82 }
83
getSize() const84 gl::Extents ExternalImageSiblingImpl11::getSize() const
85 {
86 return gl::Extents(mWidth, mHeight, 1);
87 }
88
getSamples() const89 size_t ExternalImageSiblingImpl11::getSamples() const
90 {
91 return mSamples;
92 }
93
getAttachmentRenderTarget(const gl::Context * context,GLenum binding,const gl::ImageIndex & imageIndex,GLsizei samples,FramebufferAttachmentRenderTarget ** rtOut)94 angle::Result ExternalImageSiblingImpl11::getAttachmentRenderTarget(
95 const gl::Context *context,
96 GLenum binding,
97 const gl::ImageIndex &imageIndex,
98 GLsizei samples,
99 FramebufferAttachmentRenderTarget **rtOut)
100 {
101 ANGLE_TRY(createRenderTarget(context));
102 *rtOut = mRenderTarget.get();
103 return angle::Result::Continue;
104 }
105
initializeContents(const gl::Context * context,const gl::ImageIndex & imageIndex)106 angle::Result ExternalImageSiblingImpl11::initializeContents(const gl::Context *context,
107 const gl::ImageIndex &imageIndex)
108 {
109 UNREACHABLE();
110 return angle::Result::Stop;
111 }
112
createRenderTarget(const gl::Context * context)113 angle::Result ExternalImageSiblingImpl11::createRenderTarget(const gl::Context *context)
114 {
115 if (mRenderTarget)
116 return angle::Result::Continue;
117
118 Context11 *context11 = GetImplAs<Context11>(context);
119 const d3d11::Format &formatInfo = mTexture.getFormatSet();
120
121 d3d11::RenderTargetView rtv;
122 if (mIsRenderable)
123 {
124 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
125 rtvDesc.Format = formatInfo.rtvFormat;
126 if (mIsTextureArray)
127 {
128 if (mSamples == 0)
129 {
130 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
131 rtvDesc.Texture2DArray.MipSlice = 0;
132 rtvDesc.Texture2DArray.FirstArraySlice = mArraySlice;
133 rtvDesc.Texture2DArray.ArraySize = 1;
134 }
135 else
136 {
137 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
138 rtvDesc.Texture2DMSArray.FirstArraySlice = mArraySlice;
139 rtvDesc.Texture2DMSArray.ArraySize = 1;
140 }
141 }
142 else
143 {
144 if (mSamples == 0)
145 {
146 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
147 rtvDesc.Texture2D.MipSlice = 0;
148 }
149 else
150 {
151 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
152 }
153 }
154
155 ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, mTexture.get(), &rtv));
156 rtv.setDebugName("getAttachmentRenderTarget.RTV");
157 }
158
159 d3d11::SharedSRV srv;
160 if (mIsTexturable)
161 {
162 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
163 srvDesc.Format = formatInfo.srvFormat;
164 if (mIsTextureArray)
165 {
166 if (mSamples == 0)
167 {
168 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
169 srvDesc.Texture2DArray.MostDetailedMip = 0;
170 srvDesc.Texture2DArray.MipLevels = 1;
171 srvDesc.Texture2DArray.FirstArraySlice = mArraySlice;
172 srvDesc.Texture2DArray.ArraySize = 1;
173 }
174 else
175 {
176 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
177 srvDesc.Texture2DArray.FirstArraySlice = mArraySlice;
178 srvDesc.Texture2DArray.ArraySize = 1;
179 }
180 }
181 else
182 {
183 if (mSamples == 0)
184 {
185 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
186 srvDesc.Texture2D.MostDetailedMip = 0;
187 srvDesc.Texture2D.MipLevels = 1;
188 }
189 else
190 {
191 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
192 }
193 }
194
195 ANGLE_TRY(mRenderer->allocateResource(context11, srvDesc, mTexture.get(), &srv));
196 srv.setDebugName("getAttachmentRenderTarget.SRV");
197 }
198 d3d11::SharedSRV blitSrv = srv.makeCopy();
199
200 mRenderTarget = std::make_unique<TextureRenderTarget11>(
201 std::move(rtv), mTexture, std::move(srv), std::move(blitSrv), mFormat.info->internalFormat,
202 formatInfo, mWidth, mHeight, 1, mSamples);
203 return angle::Result::Continue;
204 }
205
206 } // namespace rx
207