1 //
2 // Copyright 2012 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 // RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers
8 // retained by Renderbuffers.
9 
10 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
11 
12 #include "libANGLE/Context.h"
13 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
14 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
15 #include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
16 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
17 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
18 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
19 
20 namespace rx
21 {
22 
23 namespace
24 {
GetTextureProperties(ID3D11Resource * resource,unsigned int * mipLevels,unsigned int * samples)25 bool GetTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples)
26 {
27     ID3D11Texture1D *texture1D = d3d11::DynamicCastComObject<ID3D11Texture1D>(resource);
28     if (texture1D)
29     {
30         D3D11_TEXTURE1D_DESC texDesc;
31         texture1D->GetDesc(&texDesc);
32         SafeRelease(texture1D);
33 
34         *mipLevels = texDesc.MipLevels;
35         *samples   = 0;
36 
37         return true;
38     }
39 
40     ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource);
41     if (texture2D)
42     {
43         D3D11_TEXTURE2D_DESC texDesc;
44         texture2D->GetDesc(&texDesc);
45         SafeRelease(texture2D);
46 
47         *mipLevels = texDesc.MipLevels;
48         *samples   = texDesc.SampleDesc.Count > 1 ? texDesc.SampleDesc.Count : 0;
49 
50         return true;
51     }
52 
53     ID3D11Texture3D *texture3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(resource);
54     if (texture3D)
55     {
56         D3D11_TEXTURE3D_DESC texDesc;
57         texture3D->GetDesc(&texDesc);
58         SafeRelease(texture3D);
59 
60         *mipLevels = texDesc.MipLevels;
61         *samples   = 0;
62 
63         return true;
64     }
65 
66     return false;
67 }
68 
GetRTVSubresourceIndex(ID3D11Resource * resource,ID3D11RenderTargetView * view)69 unsigned int GetRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view)
70 {
71     D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
72     view->GetDesc(&rtvDesc);
73 
74     unsigned int mipSlice   = 0;
75     unsigned int arraySlice = 0;
76 
77     switch (rtvDesc.ViewDimension)
78     {
79         case D3D11_RTV_DIMENSION_TEXTURE1D:
80             mipSlice   = rtvDesc.Texture1D.MipSlice;
81             arraySlice = 0;
82             break;
83 
84         case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
85             mipSlice   = rtvDesc.Texture1DArray.MipSlice;
86             arraySlice = rtvDesc.Texture1DArray.FirstArraySlice;
87             break;
88 
89         case D3D11_RTV_DIMENSION_TEXTURE2D:
90             mipSlice   = rtvDesc.Texture2D.MipSlice;
91             arraySlice = 0;
92             break;
93 
94         case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
95             mipSlice   = rtvDesc.Texture2DArray.MipSlice;
96             arraySlice = rtvDesc.Texture2DArray.FirstArraySlice;
97             break;
98 
99         case D3D11_RTV_DIMENSION_TEXTURE2DMS:
100             mipSlice   = 0;
101             arraySlice = 0;
102             break;
103 
104         case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
105             mipSlice   = 0;
106             arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice;
107             break;
108 
109         case D3D11_RTV_DIMENSION_TEXTURE3D:
110             mipSlice   = rtvDesc.Texture3D.MipSlice;
111             arraySlice = 0;
112             break;
113 
114         case D3D11_RTV_DIMENSION_UNKNOWN:
115         case D3D11_RTV_DIMENSION_BUFFER:
116             UNIMPLEMENTED();
117             break;
118 
119         default:
120             UNREACHABLE();
121             break;
122     }
123 
124     unsigned int mipLevels, samples;
125     GetTextureProperties(resource, &mipLevels, &samples);
126 
127     return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
128 }
129 
GetDSVSubresourceIndex(ID3D11Resource * resource,ID3D11DepthStencilView * view)130 unsigned int GetDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view)
131 {
132     D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
133     view->GetDesc(&dsvDesc);
134 
135     unsigned int mipSlice   = 0;
136     unsigned int arraySlice = 0;
137 
138     switch (dsvDesc.ViewDimension)
139     {
140         case D3D11_DSV_DIMENSION_TEXTURE1D:
141             mipSlice   = dsvDesc.Texture1D.MipSlice;
142             arraySlice = 0;
143             break;
144 
145         case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
146             mipSlice   = dsvDesc.Texture1DArray.MipSlice;
147             arraySlice = dsvDesc.Texture1DArray.FirstArraySlice;
148             break;
149 
150         case D3D11_DSV_DIMENSION_TEXTURE2D:
151             mipSlice   = dsvDesc.Texture2D.MipSlice;
152             arraySlice = 0;
153             break;
154 
155         case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
156             mipSlice   = dsvDesc.Texture2DArray.MipSlice;
157             arraySlice = dsvDesc.Texture2DArray.FirstArraySlice;
158             break;
159 
160         case D3D11_DSV_DIMENSION_TEXTURE2DMS:
161             mipSlice   = 0;
162             arraySlice = 0;
163             break;
164 
165         case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
166             mipSlice   = 0;
167             arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice;
168             break;
169 
170         case D3D11_DSV_DIMENSION_UNKNOWN:
171             UNIMPLEMENTED();
172             break;
173 
174         default:
175             UNREACHABLE();
176             break;
177     }
178 
179     unsigned int mipLevels, samples;
180     GetTextureProperties(resource, &mipLevels, &samples);
181 
182     return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
183 }
184 
GetSurfaceRTFormat(bool depth,SwapChain11 * swapChain)185 GLenum GetSurfaceRTFormat(bool depth, SwapChain11 *swapChain)
186 {
187     return (depth ? swapChain->getDepthBufferInternalFormat()
188                   : swapChain->getRenderTargetInternalFormat());
189 }
190 
GetSurfaceFormatSet(bool depth,SwapChain11 * swapChain,Renderer11 * renderer)191 const d3d11::Format &GetSurfaceFormatSet(bool depth, SwapChain11 *swapChain, Renderer11 *renderer)
192 {
193     return d3d11::Format::Get(GetSurfaceRTFormat(depth, swapChain),
194                               renderer->getRenderer11DeviceCaps());
195 }
196 
197 }  // anonymous namespace
198 
RenderTarget11(const d3d11::Format & formatSet)199 RenderTarget11::RenderTarget11(const d3d11::Format &formatSet) : mFormatSet(formatSet) {}
200 
~RenderTarget11()201 RenderTarget11::~RenderTarget11() {}
202 
TextureRenderTarget11(d3d11::RenderTargetView && rtv,const TextureHelper11 & resource,const d3d11::SharedSRV & srv,const d3d11::SharedSRV & blitSRV,GLenum internalFormat,const d3d11::Format & formatSet,GLsizei width,GLsizei height,GLsizei depth,GLsizei samples)203 TextureRenderTarget11::TextureRenderTarget11(d3d11::RenderTargetView &&rtv,
204                                              const TextureHelper11 &resource,
205                                              const d3d11::SharedSRV &srv,
206                                              const d3d11::SharedSRV &blitSRV,
207                                              GLenum internalFormat,
208                                              const d3d11::Format &formatSet,
209                                              GLsizei width,
210                                              GLsizei height,
211                                              GLsizei depth,
212                                              GLsizei samples)
213     : RenderTarget11(formatSet),
214       mWidth(width),
215       mHeight(height),
216       mDepth(depth),
217       mInternalFormat(internalFormat),
218       mSamples(samples),
219       mSubresourceIndex(0),
220       mTexture(resource),
221       mRenderTarget(std::move(rtv)),
222       mDepthStencil(),
223       mShaderResource(srv.makeCopy()),
224       mBlitShaderResource(blitSRV.makeCopy())
225 {
226     if (mRenderTarget.valid() && mTexture.valid())
227     {
228         mSubresourceIndex = GetRTVSubresourceIndex(mTexture.get(), mRenderTarget.get());
229     }
230     ASSERT(mFormatSet.formatID != angle::FormatID::NONE || mWidth == 0 || mHeight == 0);
231 }
232 
TextureRenderTarget11(d3d11::DepthStencilView && dsv,const TextureHelper11 & resource,const d3d11::SharedSRV & srv,GLenum internalFormat,const d3d11::Format & formatSet,GLsizei width,GLsizei height,GLsizei depth,GLsizei samples)233 TextureRenderTarget11::TextureRenderTarget11(d3d11::DepthStencilView &&dsv,
234                                              const TextureHelper11 &resource,
235                                              const d3d11::SharedSRV &srv,
236                                              GLenum internalFormat,
237                                              const d3d11::Format &formatSet,
238                                              GLsizei width,
239                                              GLsizei height,
240                                              GLsizei depth,
241                                              GLsizei samples)
242     : RenderTarget11(formatSet),
243       mWidth(width),
244       mHeight(height),
245       mDepth(depth),
246       mInternalFormat(internalFormat),
247       mSamples(samples),
248       mSubresourceIndex(0),
249       mTexture(resource),
250       mRenderTarget(),
251       mDepthStencil(std::move(dsv)),
252       mShaderResource(srv.makeCopy()),
253       mBlitShaderResource()
254 {
255     if (mDepthStencil.valid() && mTexture.valid())
256     {
257         mSubresourceIndex = GetDSVSubresourceIndex(mTexture.get(), mDepthStencil.get());
258     }
259     ASSERT(mFormatSet.formatID != angle::FormatID::NONE || mWidth == 0 || mHeight == 0);
260 }
261 
~TextureRenderTarget11()262 TextureRenderTarget11::~TextureRenderTarget11() {}
263 
getTexture() const264 const TextureHelper11 &TextureRenderTarget11::getTexture() const
265 {
266     return mTexture;
267 }
268 
getRenderTargetView() const269 const d3d11::RenderTargetView &TextureRenderTarget11::getRenderTargetView() const
270 {
271     return mRenderTarget;
272 }
273 
getDepthStencilView() const274 const d3d11::DepthStencilView &TextureRenderTarget11::getDepthStencilView() const
275 {
276     return mDepthStencil;
277 }
278 
getShaderResourceView(const gl::Context * context) const279 const d3d11::SharedSRV &TextureRenderTarget11::getShaderResourceView(
280     const gl::Context *context) const
281 {
282     return mShaderResource;
283 }
284 
getBlitShaderResourceView(const gl::Context * context) const285 const d3d11::SharedSRV &TextureRenderTarget11::getBlitShaderResourceView(
286     const gl::Context *context) const
287 {
288     return mBlitShaderResource;
289 }
290 
getWidth() const291 GLsizei TextureRenderTarget11::getWidth() const
292 {
293     return mWidth;
294 }
295 
getHeight() const296 GLsizei TextureRenderTarget11::getHeight() const
297 {
298     return mHeight;
299 }
300 
getDepth() const301 GLsizei TextureRenderTarget11::getDepth() const
302 {
303     return mDepth;
304 }
305 
getInternalFormat() const306 GLenum TextureRenderTarget11::getInternalFormat() const
307 {
308     return mInternalFormat;
309 }
310 
getSamples() const311 GLsizei TextureRenderTarget11::getSamples() const
312 {
313     return mSamples;
314 }
315 
getSubresourceIndex() const316 unsigned int TextureRenderTarget11::getSubresourceIndex() const
317 {
318     return mSubresourceIndex;
319 }
320 
SurfaceRenderTarget11(SwapChain11 * swapChain,Renderer11 * renderer,bool depth)321 SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain,
322                                              Renderer11 *renderer,
323                                              bool depth)
324     : RenderTarget11(GetSurfaceFormatSet(depth, swapChain, renderer)),
325       mSwapChain(swapChain),
326       mDepth(depth)
327 {
328     ASSERT(mSwapChain);
329 }
330 
~SurfaceRenderTarget11()331 SurfaceRenderTarget11::~SurfaceRenderTarget11() {}
332 
getWidth() const333 GLsizei SurfaceRenderTarget11::getWidth() const
334 {
335     return mSwapChain->getWidth();
336 }
337 
getHeight() const338 GLsizei SurfaceRenderTarget11::getHeight() const
339 {
340     return mSwapChain->getHeight();
341 }
342 
getDepth() const343 GLsizei SurfaceRenderTarget11::getDepth() const
344 {
345     return 1;
346 }
347 
getInternalFormat() const348 GLenum SurfaceRenderTarget11::getInternalFormat() const
349 {
350     return GetSurfaceRTFormat(mDepth, mSwapChain);
351 }
352 
getSamples() const353 GLsizei SurfaceRenderTarget11::getSamples() const
354 {
355     return mSwapChain->getSamples();
356 }
357 
getTexture() const358 const TextureHelper11 &SurfaceRenderTarget11::getTexture() const
359 {
360     return (mDepth ? mSwapChain->getDepthStencilTexture() : mSwapChain->getOffscreenTexture());
361 }
362 
getRenderTargetView() const363 const d3d11::RenderTargetView &SurfaceRenderTarget11::getRenderTargetView() const
364 {
365     ASSERT(!mDepth);
366     return mSwapChain->getRenderTarget();
367 }
368 
getDepthStencilView() const369 const d3d11::DepthStencilView &SurfaceRenderTarget11::getDepthStencilView() const
370 {
371     ASSERT(mDepth);
372     return mSwapChain->getDepthStencil();
373 }
374 
getShaderResourceView(const gl::Context * context) const375 const d3d11::SharedSRV &SurfaceRenderTarget11::getShaderResourceView(
376     const gl::Context *context) const
377 {
378     return (mDepth ? mSwapChain->getDepthStencilShaderResource()
379                    : mSwapChain->getRenderTargetShaderResource(GetImplAs<Context11>(context)));
380 }
381 
getBlitShaderResourceView(const gl::Context * context) const382 const d3d11::SharedSRV &SurfaceRenderTarget11::getBlitShaderResourceView(
383     const gl::Context *context) const
384 {
385     // The SurfaceRenderTargetView format should always be such that the normal SRV works for blits.
386     return getShaderResourceView(context);
387 }
388 
getSubresourceIndex() const389 unsigned int SurfaceRenderTarget11::getSubresourceIndex() const
390 {
391     return 0;
392 }
393 
394 }  // namespace rx
395