blob: ed44a41a97a881aff7e1261064f6db1d6395d2a8 [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;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000144
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000145 if (mRenderTarget && mTexture)
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000146 {
147 D3D11_RENDER_TARGET_VIEW_DESC desc;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000148 mRenderTarget->GetDesc(&desc);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000149
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000150 D3D11_TEXTURE2D_DESC texDesc;
151 mTexture->GetDesc(&texDesc);
152
153 mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000154 mWidth = width;
155 mHeight = height;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000156 mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0;
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000157
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000158 mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
159 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000160 }
161}
162
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000163RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000164{
165 mRenderer = Renderer11::makeRenderer11(renderer);
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000166 mTexture = tex;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000167 mRenderTarget = NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000168 mDepthStencil = dsv;
169 mShaderResource = srv;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000170 mTexture = tex;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000171
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000172 if (mDepthStencil && mTexture)
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000173 {
174 D3D11_DEPTH_STENCIL_VIEW_DESC desc;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000175 mDepthStencil->GetDesc(&desc);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000176
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000177 D3D11_TEXTURE2D_DESC texDesc;
178 mTexture->GetDesc(&texDesc);
179
180 mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000181 mWidth = width;
182 mHeight = height;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000183 mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0;
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000184
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000185 mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
186 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000187 }
188}
189
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000190RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth)
191{
192 mRenderer = Renderer11::makeRenderer11(renderer);
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000193 mTexture = NULL;
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000194 mRenderTarget = NULL;
195 mDepthStencil = NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000196 mShaderResource = NULL;
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000197
198 DXGI_FORMAT requestedFormat = gl_d3d11::ConvertRenderbufferFormat(format);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000199
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000200 int supportedSamples = mRenderer->getNearestSupportedSamples(requestedFormat, samples);
201 if (supportedSamples < 0)
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000202 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000203 gl::error(GL_OUT_OF_MEMORY);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000204 return;
205 }
206
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000207 HRESULT result = D3DERR_INVALIDCALL;
208
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000209 if (width > 0 && height > 0)
210 {
211 // Create texture resource
212 D3D11_TEXTURE2D_DESC desc;
213 desc.Width = width;
214 desc.Height = height;
215 desc.MipLevels = 1;
216 desc.ArraySize = 1;
217 desc.Format = requestedFormat;
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000218 desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000219 desc.SampleDesc.Quality = 0;
220 desc.Usage = D3D11_USAGE_DEFAULT;
221 desc.CPUAccessFlags = 0;
222 desc.MiscFlags = 0;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000223 desc.BindFlags = (depth ? D3D11_BIND_DEPTH_STENCIL : (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE));
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000224
225 ID3D11Device *device = mRenderer->getDevice();
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000226 HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000227
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000228 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
229 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000230 gl::error(GL_OUT_OF_MEMORY);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000231 return;
232 }
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000233 ASSERT(SUCCEEDED(result));
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000234
235 if (depth)
236 {
237 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
238 dsvDesc.Format = requestedFormat;
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000239 dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000240 dsvDesc.Texture2D.MipSlice = 0;
241 dsvDesc.Flags = 0;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000242 result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000243
244 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
245 {
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000246 mTexture->Release();
247 mTexture = NULL;
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000248 gl::error(GL_OUT_OF_MEMORY);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000249 }
250 ASSERT(SUCCEEDED(result));
251 }
252 else
253 {
254 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
255 rtvDesc.Format = requestedFormat;
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000256 rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000257 rtvDesc.Texture2D.MipSlice = 0;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000258 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000259
260 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
261 {
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000262 mTexture->Release();
263 mTexture = NULL;
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000264 gl::error(GL_OUT_OF_MEMORY);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000265 return;
266 }
267 ASSERT(SUCCEEDED(result));
268
269 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
270 srvDesc.Format = requestedFormat;
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000271 srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000272 srvDesc.Texture2D.MostDetailedMip = 0;
273 srvDesc.Texture2D.MipLevels = 1;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000274 result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000275
276 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
277 {
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000278 mTexture->Release();
279 mTexture = NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000280 mRenderTarget->Release();
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000281 mRenderTarget = NULL;
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000282 gl::error(GL_OUT_OF_MEMORY);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000283 return;
284 }
285 ASSERT(SUCCEEDED(result));
286 }
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000287 }
288
289 mWidth = width;
290 mHeight = height;
291 mInternalFormat = format;
292 mSamples = supportedSamples;
shannon.woods@transgaming.comb3f4be02013-02-28 23:05:52 +0000293 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(requestedFormat);
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000294 mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000295}
296
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000297RenderTarget11::~RenderTarget11()
298{
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000299 if (mTexture)
300 {
301 mTexture->Release();
302 mTexture = NULL;
303 }
304
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000305 if (mRenderTarget)
306 {
307 mRenderTarget->Release();
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000308 mRenderTarget = NULL;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000309 }
310
311 if (mDepthStencil)
312 {
313 mDepthStencil->Release();
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000314 mDepthStencil = NULL;
315 }
316
317 if (mShaderResource)
318 {
319 mShaderResource->Release();
320 mShaderResource = NULL;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000321 }
322}
323
324RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
325{
apatrick@chromium.org8b400b12013-01-30 21:53:40 +0000326 ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target));
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000327 return static_cast<rx::RenderTarget11*>(target);
328}
329
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000330ID3D11Texture2D *RenderTarget11::getTexture() const
331{
332 if (mTexture)
333 {
334 mTexture->AddRef();
335 }
336
337 return mTexture;
338}
339
daniel@transgaming.com816c7f32012-11-28 21:02:01 +0000340// Adds reference, caller must call Release
341ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
342{
343 if (mRenderTarget)
344 {
345 mRenderTarget->AddRef();
346 }
347
348 return mRenderTarget;
349}
350
351// Adds reference, caller must call Release
352ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
353{
354 if (mDepthStencil)
355 {
356 mDepthStencil->AddRef();
357 }
358
359 return mDepthStencil;
360}
361
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000362// Adds reference, caller must call Release
363ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const
364{
365 if (mShaderResource)
366 {
367 mShaderResource->AddRef();
368 }
369
370 return mShaderResource;
371}
372
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000373unsigned int RenderTarget11::getSubresourceIndex() const
374{
375 return mSubresourceIndex;
376}
377
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000378}