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