blob: 0e9778d55875e5a640526a85ca958d9deff60413 [file] [log] [blame]
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +00001//
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 "libGLESv2/renderer/RenderTarget11.h"
11#include "libGLESv2/renderer/Renderer11.h"
12
13#include "libGLESv2/renderer/renderer11_utils.h"
14#include "libGLESv2/main.h"
15
16namespace rx
17{
18
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +000019static unsigned int getRTVSubresourceIndex(ID3D11Texture2D *texture, ID3D11RenderTargetView *view)
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +000020{
21 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
22 view->GetDesc(&rtvDesc);
23
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +000024 D3D11_TEXTURE2D_DESC texDesc;
25 texture->GetDesc(&texDesc);
26
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +000027 unsigned int mipSlice = 0;
28 unsigned int arraySlice = 0;
29 unsigned int mipLevels = texDesc.MipLevels;
30
31 switch (rtvDesc.ViewDimension)
32 {
33 case D3D11_RTV_DIMENSION_TEXTURE1D:
34 mipSlice = rtvDesc.Texture1D.MipSlice;
35 arraySlice = 0;
36 break;
37
38 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
39 mipSlice = rtvDesc.Texture1DArray.MipSlice;
40 arraySlice = rtvDesc.Texture1DArray.FirstArraySlice;
41 break;
42
43 case D3D11_RTV_DIMENSION_TEXTURE2D:
44 mipSlice = rtvDesc.Texture2D.MipSlice;
45 arraySlice = 0;
46 break;
47
48 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
49 mipSlice = rtvDesc.Texture2DArray.MipSlice;
50 arraySlice = rtvDesc.Texture2DArray.FirstArraySlice;
51 break;
52
53 case D3D11_RTV_DIMENSION_TEXTURE2DMS:
54 mipSlice = 0;
55 arraySlice = 0;
56 break;
57
58 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
59 mipSlice = 0;
60 arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice;
61 break;
62
63 case D3D11_RTV_DIMENSION_TEXTURE3D:
64 mipSlice = rtvDesc.Texture3D.MipSlice;
65 arraySlice = 0;
66 break;
67
68 case D3D11_RTV_DIMENSION_UNKNOWN:
69 case D3D11_RTV_DIMENSION_BUFFER:
70 UNIMPLEMENTED();
71 break;
72
73 default:
74 UNREACHABLE();
75 break;
76 }
77
78 return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
79}
80
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +000081static unsigned int getDSVSubresourceIndex(ID3D11Texture2D *texture, ID3D11DepthStencilView *view)
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +000082{
83 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
84 view->GetDesc(&dsvDesc);
85
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +000086 D3D11_TEXTURE2D_DESC texDesc;
87 texture->GetDesc(&texDesc);
88
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +000089 unsigned int mipSlice = 0;
90 unsigned int arraySlice = 0;
91 unsigned int mipLevels = texDesc.MipLevels;
92
93 switch (dsvDesc.ViewDimension)
94 {
95 case D3D11_DSV_DIMENSION_TEXTURE1D:
96 mipSlice = dsvDesc.Texture1D.MipSlice;
97 arraySlice = 0;
98 break;
99
100 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
101 mipSlice = dsvDesc.Texture1DArray.MipSlice;
102 arraySlice = dsvDesc.Texture1DArray.FirstArraySlice;
103 break;
104
105 case D3D11_DSV_DIMENSION_TEXTURE2D:
106 mipSlice = dsvDesc.Texture2D.MipSlice;
107 arraySlice = 0;
108 break;
109
110 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
111 mipSlice = dsvDesc.Texture2DArray.MipSlice;
112 arraySlice = dsvDesc.Texture2DArray.FirstArraySlice;
113 break;
114
115 case D3D11_DSV_DIMENSION_TEXTURE2DMS:
116 mipSlice = 0;
117 arraySlice = 0;
118 break;
119
120 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
121 mipSlice = 0;
122 arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice;
123 break;
124
125 case D3D11_RTV_DIMENSION_UNKNOWN:
126 UNIMPLEMENTED();
127 break;
128
129 default:
130 UNREACHABLE();
131 break;
132 }
133
134 return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
135}
136
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000137RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000138{
139 mRenderer = Renderer11::makeRenderer11(renderer);
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000140 mTexture = tex;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000141 mRenderTarget = rtv;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000142 mDepthStencil = NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000143 mShaderResource = srv;
shannon.woods@transgaming.com3e3da582013-02-28 23:09:03 +0000144 mSubresourceIndex = 0;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000145
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000146 if (mRenderTarget && mTexture)
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000147 {
148 D3D11_RENDER_TARGET_VIEW_DESC desc;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000149 mRenderTarget->GetDesc(&desc);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000150
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000151 D3D11_TEXTURE2D_DESC texDesc;
152 mTexture->GetDesc(&texDesc);
153
154 mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000155 mWidth = width;
156 mHeight = height;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000157 mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0;
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000158
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000159 mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
160 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000161 }
162}
163
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000164RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000165{
166 mRenderer = Renderer11::makeRenderer11(renderer);
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000167 mTexture = tex;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000168 mRenderTarget = NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000169 mDepthStencil = dsv;
170 mShaderResource = srv;
shannon.woods@transgaming.com3e3da582013-02-28 23:09:03 +0000171 mSubresourceIndex = 0;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000172
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000173 if (mDepthStencil && mTexture)
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000174 {
175 D3D11_DEPTH_STENCIL_VIEW_DESC desc;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000176 mDepthStencil->GetDesc(&desc);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000177
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000178 D3D11_TEXTURE2D_DESC texDesc;
179 mTexture->GetDesc(&texDesc);
180
181 mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000182 mWidth = width;
183 mHeight = height;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000184 mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0;
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000185
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000186 mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
187 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000188 }
189}
190
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000191RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth)
192{
193 mRenderer = Renderer11::makeRenderer11(renderer);
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000194 mTexture = NULL;
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000195 mRenderTarget = NULL;
196 mDepthStencil = NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000197 mShaderResource = NULL;
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000198
199 DXGI_FORMAT requestedFormat = gl_d3d11::ConvertRenderbufferFormat(format);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000200
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000201 int supportedSamples = mRenderer->getNearestSupportedSamples(requestedFormat, samples);
202 if (supportedSamples < 0)
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000203 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000204 gl::error(GL_OUT_OF_MEMORY);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000205 return;
206 }
207
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000208 HRESULT result = D3DERR_INVALIDCALL;
209
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000210 if (width > 0 && height > 0)
211 {
212 // Create texture resource
213 D3D11_TEXTURE2D_DESC desc;
214 desc.Width = width;
215 desc.Height = height;
216 desc.MipLevels = 1;
217 desc.ArraySize = 1;
218 desc.Format = requestedFormat;
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000219 desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000220 desc.SampleDesc.Quality = 0;
221 desc.Usage = D3D11_USAGE_DEFAULT;
222 desc.CPUAccessFlags = 0;
223 desc.MiscFlags = 0;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000224 desc.BindFlags = (depth ? D3D11_BIND_DEPTH_STENCIL : (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE));
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000225
226 ID3D11Device *device = mRenderer->getDevice();
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000227 HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000228
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000229 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
230 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000231 gl::error(GL_OUT_OF_MEMORY);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000232 return;
233 }
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000234 ASSERT(SUCCEEDED(result));
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000235
236 if (depth)
237 {
238 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
239 dsvDesc.Format = requestedFormat;
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000240 dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000241 dsvDesc.Texture2D.MipSlice = 0;
242 dsvDesc.Flags = 0;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000243 result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000244
245 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
246 {
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000247 mTexture->Release();
248 mTexture = NULL;
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000249 gl::error(GL_OUT_OF_MEMORY);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000250 }
251 ASSERT(SUCCEEDED(result));
252 }
253 else
254 {
255 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
256 rtvDesc.Format = requestedFormat;
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000257 rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000258 rtvDesc.Texture2D.MipSlice = 0;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000259 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000260
261 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
262 {
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000263 mTexture->Release();
264 mTexture = NULL;
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000265 gl::error(GL_OUT_OF_MEMORY);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000266 return;
267 }
268 ASSERT(SUCCEEDED(result));
269
270 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
271 srvDesc.Format = requestedFormat;
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000272 srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000273 srvDesc.Texture2D.MostDetailedMip = 0;
274 srvDesc.Texture2D.MipLevels = 1;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000275 result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000276
277 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
278 {
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000279 mTexture->Release();
280 mTexture = NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000281 mRenderTarget->Release();
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000282 mRenderTarget = NULL;
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000283 gl::error(GL_OUT_OF_MEMORY);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000284 return;
285 }
286 ASSERT(SUCCEEDED(result));
287 }
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000288 }
289
290 mWidth = width;
291 mHeight = height;
292 mInternalFormat = format;
293 mSamples = supportedSamples;
shannon.woods@transgaming.comb3f4be02013-02-28 23:05:52 +0000294 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(requestedFormat);
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000295 mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000296}
297
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000298RenderTarget11::~RenderTarget11()
299{
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000300 if (mTexture)
301 {
302 mTexture->Release();
303 mTexture = NULL;
304 }
305
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000306 if (mRenderTarget)
307 {
308 mRenderTarget->Release();
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000309 mRenderTarget = NULL;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000310 }
311
312 if (mDepthStencil)
313 {
314 mDepthStencil->Release();
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000315 mDepthStencil = NULL;
316 }
317
318 if (mShaderResource)
319 {
320 mShaderResource->Release();
321 mShaderResource = NULL;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000322 }
323}
324
325RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
326{
apatrick@chromium.org8b400b12013-01-30 21:53:40 +0000327 ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target));
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000328 return static_cast<rx::RenderTarget11*>(target);
329}
330
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000331ID3D11Texture2D *RenderTarget11::getTexture() const
332{
333 if (mTexture)
334 {
335 mTexture->AddRef();
336 }
337
338 return mTexture;
339}
340
daniel@transgaming.com816c7f32012-11-28 21:02:01 +0000341// Adds reference, caller must call Release
342ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
343{
344 if (mRenderTarget)
345 {
346 mRenderTarget->AddRef();
347 }
348
349 return mRenderTarget;
350}
351
352// Adds reference, caller must call Release
353ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
354{
355 if (mDepthStencil)
356 {
357 mDepthStencil->AddRef();
358 }
359
360 return mDepthStencil;
361}
362
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000363// Adds reference, caller must call Release
364ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const
365{
366 if (mShaderResource)
367 {
368 mShaderResource->AddRef();
369 }
370
371 return mShaderResource;
372}
373
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000374unsigned int RenderTarget11::getSubresourceIndex() const
375{
376 return mSubresourceIndex;
377}
378
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000379}