1 //
2 // Copyright (c) 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/renderer/d3d/d3d11/formatutils11.h"
13 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
14 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
15 #include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
16 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
17 
18 namespace rx
19 {
20 
21 namespace
22 {
GetTextureProperties(ID3D11Resource * resource,unsigned int * mipLevels,unsigned int * samples)23 bool GetTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples)
24 {
25     ID3D11Texture1D *texture1D = d3d11::DynamicCastComObject<ID3D11Texture1D>(resource);
26     if (texture1D)
27     {
28         D3D11_TEXTURE1D_DESC texDesc;
29         texture1D->GetDesc(&texDesc);
30         SafeRelease(texture1D);
31 
32         *mipLevels = texDesc.MipLevels;
33         *samples = 0;
34 
35         return true;
36     }
37 
38     ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource);
39     if (texture2D)
40     {
41         D3D11_TEXTURE2D_DESC texDesc;
42         texture2D->GetDesc(&texDesc);
43         SafeRelease(texture2D);
44 
45         *mipLevels = texDesc.MipLevels;
46         *samples = texDesc.SampleDesc.Count > 1 ? texDesc.SampleDesc.Count : 0;
47 
48         return true;
49     }
50 
51     ID3D11Texture3D *texture3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(resource);
52     if (texture3D)
53     {
54         D3D11_TEXTURE3D_DESC texDesc;
55         texture3D->GetDesc(&texDesc);
56         SafeRelease(texture3D);
57 
58         *mipLevels = texDesc.MipLevels;
59         *samples = 0;
60 
61         return true;
62     }
63 
64     return false;
65 }
66 
GetRTVSubresourceIndex(ID3D11Resource * resource,ID3D11RenderTargetView * view)67 unsigned int GetRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view)
68 {
69     D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
70     view->GetDesc(&rtvDesc);
71 
72     unsigned int mipSlice = 0;
73     unsigned int arraySlice = 0;
74 
75     switch (rtvDesc.ViewDimension)
76     {
77         case D3D11_RTV_DIMENSION_TEXTURE1D:
78             mipSlice   = rtvDesc.Texture1D.MipSlice;
79             arraySlice = 0;
80             break;
81 
82         case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
83             mipSlice   = rtvDesc.Texture1DArray.MipSlice;
84             arraySlice = rtvDesc.Texture1DArray.FirstArraySlice;
85             break;
86 
87         case D3D11_RTV_DIMENSION_TEXTURE2D:
88             mipSlice   = rtvDesc.Texture2D.MipSlice;
89             arraySlice = 0;
90             break;
91 
92         case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
93             mipSlice   = rtvDesc.Texture2DArray.MipSlice;
94             arraySlice = rtvDesc.Texture2DArray.FirstArraySlice;
95             break;
96 
97         case D3D11_RTV_DIMENSION_TEXTURE2DMS:
98             mipSlice   = 0;
99             arraySlice = 0;
100             break;
101 
102         case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
103             mipSlice   = 0;
104             arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice;
105             break;
106 
107         case D3D11_RTV_DIMENSION_TEXTURE3D:
108             mipSlice   = rtvDesc.Texture3D.MipSlice;
109             arraySlice = 0;
110             break;
111 
112         case D3D11_RTV_DIMENSION_UNKNOWN:
113         case D3D11_RTV_DIMENSION_BUFFER:
114             UNIMPLEMENTED();
115             break;
116 
117         default:
118             UNREACHABLE();
119             break;
120     }
121 
122     unsigned int mipLevels, samples;
123     GetTextureProperties(resource, &mipLevels, &samples);
124 
125     return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
126 }
127 
GetDSVSubresourceIndex(ID3D11Resource * resource,ID3D11DepthStencilView * view)128 unsigned int GetDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view)
129 {
130     D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
131     view->GetDesc(&dsvDesc);
132 
133     unsigned int mipSlice = 0;
134     unsigned int arraySlice = 0;
135 
136     switch (dsvDesc.ViewDimension)
137     {
138         case D3D11_DSV_DIMENSION_TEXTURE1D:
139             mipSlice   = dsvDesc.Texture1D.MipSlice;
140             arraySlice = 0;
141             break;
142 
143         case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
144             mipSlice   = dsvDesc.Texture1DArray.MipSlice;
145             arraySlice = dsvDesc.Texture1DArray.FirstArraySlice;
146             break;
147 
148         case D3D11_DSV_DIMENSION_TEXTURE2D:
149             mipSlice   = dsvDesc.Texture2D.MipSlice;
150             arraySlice = 0;
151             break;
152 
153         case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
154             mipSlice   = dsvDesc.Texture2DArray.MipSlice;
155             arraySlice = dsvDesc.Texture2DArray.FirstArraySlice;
156             break;
157 
158         case D3D11_DSV_DIMENSION_TEXTURE2DMS:
159             mipSlice   = 0;
160             arraySlice = 0;
161             break;
162 
163         case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
164             mipSlice   = 0;
165             arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice;
166             break;
167 
168         case D3D11_DSV_DIMENSION_UNKNOWN:
169             UNIMPLEMENTED();
170             break;
171 
172         default:
173             UNREACHABLE();
174             break;
175     }
176 
177     unsigned int mipLevels, samples;
178     GetTextureProperties(resource, &mipLevels, &samples);
179 
180     return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
181 }
182 
GetSurfaceRTFormat(bool depth,SwapChain11 * swapChain)183 GLenum GetSurfaceRTFormat(bool depth, SwapChain11 *swapChain)
184 {
185     return (depth ? swapChain->getDepthBufferInternalFormat()
186                   : swapChain->getRenderTargetInternalFormat());
187 }
188 
GetSurfaceFormatSet(bool depth,SwapChain11 * swapChain,Renderer11 * renderer)189 const d3d11::Format &GetSurfaceFormatSet(bool depth, SwapChain11 *swapChain, Renderer11 *renderer)
190 {
191     return d3d11::Format::Get(GetSurfaceRTFormat(depth, swapChain),
192                               renderer->getRenderer11DeviceCaps());
193 }
194 
195 }  // anonymous namespace
196 
RenderTarget11(const d3d11::Format & formatSet)197 RenderTarget11::RenderTarget11(const d3d11::Format &formatSet) : mFormatSet(formatSet)
198 {
199 }
200 
~RenderTarget11()201 RenderTarget11::~RenderTarget11()
202 {
203     ASSERT(mBroadcastChannel.empty());
204 }
205 
signalDirty(const gl::Context * context)206 void RenderTarget11::signalDirty(const gl::Context *context)
207 {
208     mBroadcastChannel.signal(context);
209 
210     // Clear the list. We can't do this in the receiver because it would mutate during iteration.
211     mBroadcastChannel.reset();
212 }
213 
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)214 TextureRenderTarget11::TextureRenderTarget11(d3d11::RenderTargetView &&rtv,
215                                              const TextureHelper11 &resource,
216                                              const d3d11::SharedSRV &srv,
217                                              const d3d11::SharedSRV &blitSRV,
218                                              GLenum internalFormat,
219                                              const d3d11::Format &formatSet,
220                                              GLsizei width,
221                                              GLsizei height,
222                                              GLsizei depth,
223                                              GLsizei samples)
224     : RenderTarget11(formatSet),
225       mWidth(width),
226       mHeight(height),
227       mDepth(depth),
228       mInternalFormat(internalFormat),
229       mSamples(samples),
230       mSubresourceIndex(0),
231       mTexture(resource),
232       mRenderTarget(std::move(rtv)),
233       mDepthStencil(),
234       mShaderResource(srv.makeCopy()),
235       mBlitShaderResource(blitSRV.makeCopy())
236 {
237     if (mRenderTarget.valid() && mTexture.valid())
238     {
239         mSubresourceIndex = GetRTVSubresourceIndex(mTexture.get(), mRenderTarget.get());
240     }
241     ASSERT(mFormatSet.formatID != angle::Format::ID::NONE || mWidth == 0 || mHeight == 0);
242 }
243 
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)244 TextureRenderTarget11::TextureRenderTarget11(d3d11::DepthStencilView &&dsv,
245                                              const TextureHelper11 &resource,
246                                              const d3d11::SharedSRV &srv,
247                                              GLenum internalFormat,
248                                              const d3d11::Format &formatSet,
249                                              GLsizei width,
250                                              GLsizei height,
251                                              GLsizei depth,
252                                              GLsizei samples)
253     : RenderTarget11(formatSet),
254       mWidth(width),
255       mHeight(height),
256       mDepth(depth),
257       mInternalFormat(internalFormat),
258       mSamples(samples),
259       mSubresourceIndex(0),
260       mTexture(resource),
261       mRenderTarget(),
262       mDepthStencil(std::move(dsv)),
263       mShaderResource(srv.makeCopy()),
264       mBlitShaderResource()
265 {
266     if (mDepthStencil.valid() && mTexture.valid())
267     {
268         mSubresourceIndex = GetDSVSubresourceIndex(mTexture.get(), mDepthStencil.get());
269     }
270     ASSERT(mFormatSet.formatID != angle::Format::ID::NONE || mWidth == 0 || mHeight == 0);
271 }
272 
~TextureRenderTarget11()273 TextureRenderTarget11::~TextureRenderTarget11()
274 {
275 }
276 
getTexture() const277 const TextureHelper11 &TextureRenderTarget11::getTexture() const
278 {
279     return mTexture;
280 }
281 
getRenderTargetView() const282 const d3d11::RenderTargetView &TextureRenderTarget11::getRenderTargetView() const
283 {
284     return mRenderTarget;
285 }
286 
getDepthStencilView() const287 const d3d11::DepthStencilView &TextureRenderTarget11::getDepthStencilView() const
288 {
289     return mDepthStencil;
290 }
291 
getShaderResourceView() const292 const d3d11::SharedSRV &TextureRenderTarget11::getShaderResourceView() const
293 {
294     return mShaderResource;
295 }
296 
getBlitShaderResourceView() const297 const d3d11::SharedSRV &TextureRenderTarget11::getBlitShaderResourceView() const
298 {
299     return mBlitShaderResource;
300 }
301 
getWidth() const302 GLsizei TextureRenderTarget11::getWidth() const
303 {
304     return mWidth;
305 }
306 
getHeight() const307 GLsizei TextureRenderTarget11::getHeight() const
308 {
309     return mHeight;
310 }
311 
getDepth() const312 GLsizei TextureRenderTarget11::getDepth() const
313 {
314     return mDepth;
315 }
316 
getInternalFormat() const317 GLenum TextureRenderTarget11::getInternalFormat() const
318 {
319     return mInternalFormat;
320 }
321 
getSamples() const322 GLsizei TextureRenderTarget11::getSamples() const
323 {
324     return mSamples;
325 }
326 
getSubresourceIndex() const327 unsigned int TextureRenderTarget11::getSubresourceIndex() const
328 {
329     return mSubresourceIndex;
330 }
331 
SurfaceRenderTarget11(SwapChain11 * swapChain,Renderer11 * renderer,bool depth)332 SurfaceRenderTarget11::SurfaceRenderTarget11(SwapChain11 *swapChain,
333                                              Renderer11 *renderer,
334                                              bool depth)
335     : RenderTarget11(GetSurfaceFormatSet(depth, swapChain, renderer)),
336       mSwapChain(swapChain),
337       mDepth(depth)
338 {
339     ASSERT(mSwapChain);
340 }
341 
~SurfaceRenderTarget11()342 SurfaceRenderTarget11::~SurfaceRenderTarget11()
343 {
344 }
345 
getWidth() const346 GLsizei SurfaceRenderTarget11::getWidth() const
347 {
348     return mSwapChain->getWidth();
349 }
350 
getHeight() const351 GLsizei SurfaceRenderTarget11::getHeight() const
352 {
353     return mSwapChain->getHeight();
354 }
355 
getDepth() const356 GLsizei SurfaceRenderTarget11::getDepth() const
357 {
358     return 1;
359 }
360 
getInternalFormat() const361 GLenum SurfaceRenderTarget11::getInternalFormat() const
362 {
363     return GetSurfaceRTFormat(mDepth, mSwapChain);
364 }
365 
getSamples() const366 GLsizei SurfaceRenderTarget11::getSamples() const
367 {
368     return mSwapChain->getSamples();
369 }
370 
getTexture() const371 const TextureHelper11 &SurfaceRenderTarget11::getTexture() const
372 {
373     return (mDepth ? mSwapChain->getDepthStencilTexture() : mSwapChain->getOffscreenTexture());
374 }
375 
getRenderTargetView() const376 const d3d11::RenderTargetView &SurfaceRenderTarget11::getRenderTargetView() const
377 {
378     ASSERT(!mDepth);
379     return mSwapChain->getRenderTarget();
380 }
381 
getDepthStencilView() const382 const d3d11::DepthStencilView &SurfaceRenderTarget11::getDepthStencilView() const
383 {
384     ASSERT(mDepth);
385     return mSwapChain->getDepthStencil();
386 }
387 
getShaderResourceView() const388 const d3d11::SharedSRV &SurfaceRenderTarget11::getShaderResourceView() const
389 {
390     return (mDepth ? mSwapChain->getDepthStencilShaderResource()
391                    : mSwapChain->getRenderTargetShaderResource());
392 }
393 
getBlitShaderResourceView() const394 const d3d11::SharedSRV &SurfaceRenderTarget11::getBlitShaderResourceView() const
395 {
396     // The SurfaceRenderTargetView format should always be such that the normal SRV works for blits.
397     return getShaderResourceView();
398 }
399 
getSubresourceIndex() const400 unsigned int SurfaceRenderTarget11::getSubresourceIndex() const
401 {
402     return 0;
403 }
404 
405 }  // namespace rx
406