blob: c9d8de6bcc8bd93e103fe099e3a1104bf3270800 [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
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000208 if (width > 0 && height > 0)
209 {
210 // Create texture resource
211 D3D11_TEXTURE2D_DESC desc;
212 desc.Width = width;
213 desc.Height = height;
214 desc.MipLevels = 1;
215 desc.ArraySize = 1;
216 desc.Format = requestedFormat;
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000217 desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000218 desc.SampleDesc.Quality = 0;
219 desc.Usage = D3D11_USAGE_DEFAULT;
220 desc.CPUAccessFlags = 0;
221 desc.MiscFlags = 0;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000222 desc.BindFlags = (depth ? D3D11_BIND_DEPTH_STENCIL : (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE));
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000223
224 ID3D11Device *device = mRenderer->getDevice();
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000225 HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000226
shannon.woods@transgaming.com8d8814b2013-02-28 23:10:53 +0000227 if (result == E_OUTOFMEMORY)
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000228 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000229 gl::error(GL_OUT_OF_MEMORY);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000230 return;
231 }
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000232 ASSERT(SUCCEEDED(result));
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000233
234 if (depth)
235 {
236 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
237 dsvDesc.Format = requestedFormat;
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000238 dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000239 dsvDesc.Texture2D.MipSlice = 0;
240 dsvDesc.Flags = 0;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000241 result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000242
shannon.woods@transgaming.com8d8814b2013-02-28 23:10:53 +0000243 if (result == E_OUTOFMEMORY)
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000244 {
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000245 mTexture->Release();
246 mTexture = NULL;
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000247 gl::error(GL_OUT_OF_MEMORY);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000248 }
249 ASSERT(SUCCEEDED(result));
250 }
251 else
252 {
253 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
254 rtvDesc.Format = requestedFormat;
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000255 rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000256 rtvDesc.Texture2D.MipSlice = 0;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000257 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000258
shannon.woods@transgaming.com8d8814b2013-02-28 23:10:53 +0000259 if (result == E_OUTOFMEMORY)
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000260 {
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000261 mTexture->Release();
262 mTexture = NULL;
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000263 gl::error(GL_OUT_OF_MEMORY);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000264 return;
265 }
266 ASSERT(SUCCEEDED(result));
267
268 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
269 srvDesc.Format = requestedFormat;
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000270 srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000271 srvDesc.Texture2D.MostDetailedMip = 0;
272 srvDesc.Texture2D.MipLevels = 1;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000273 result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000274
shannon.woods@transgaming.com8d8814b2013-02-28 23:10:53 +0000275 if (result == E_OUTOFMEMORY)
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000276 {
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000277 mTexture->Release();
278 mTexture = NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000279 mRenderTarget->Release();
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000280 mRenderTarget = NULL;
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000281 gl::error(GL_OUT_OF_MEMORY);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000282 return;
283 }
284 ASSERT(SUCCEEDED(result));
285 }
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000286 }
287
288 mWidth = width;
289 mHeight = height;
290 mInternalFormat = format;
291 mSamples = supportedSamples;
shannon.woods@transgaming.comb3f4be02013-02-28 23:05:52 +0000292 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(requestedFormat);
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000293 mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000294}
295
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000296RenderTarget11::~RenderTarget11()
297{
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000298 if (mTexture)
299 {
300 mTexture->Release();
301 mTexture = NULL;
302 }
303
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000304 if (mRenderTarget)
305 {
306 mRenderTarget->Release();
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000307 mRenderTarget = NULL;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000308 }
309
310 if (mDepthStencil)
311 {
312 mDepthStencil->Release();
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000313 mDepthStencil = NULL;
314 }
315
316 if (mShaderResource)
317 {
318 mShaderResource->Release();
319 mShaderResource = NULL;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000320 }
321}
322
323RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
324{
apatrick@chromium.org8b400b12013-01-30 21:53:40 +0000325 ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target));
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000326 return static_cast<rx::RenderTarget11*>(target);
327}
328
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000329ID3D11Texture2D *RenderTarget11::getTexture() const
330{
331 if (mTexture)
332 {
333 mTexture->AddRef();
334 }
335
336 return mTexture;
337}
338
daniel@transgaming.com816c7f32012-11-28 21:02:01 +0000339// Adds reference, caller must call Release
340ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
341{
342 if (mRenderTarget)
343 {
344 mRenderTarget->AddRef();
345 }
346
347 return mRenderTarget;
348}
349
350// Adds reference, caller must call Release
351ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
352{
353 if (mDepthStencil)
354 {
355 mDepthStencil->AddRef();
356 }
357
358 return mDepthStencil;
359}
360
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000361// Adds reference, caller must call Release
362ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const
363{
364 if (mShaderResource)
365 {
366 mShaderResource->AddRef();
367 }
368
369 return mShaderResource;
370}
371
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000372unsigned int RenderTarget11::getSubresourceIndex() const
373{
374 return mSubresourceIndex;
375}
376
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000377}