blob: cf226de17b154c9fa56402c7a7fe76ba5224a35c [file] [log] [blame]
shannon.woods@transgaming.combdf2d802013-02-28 23:16:20 +00001#include "precompiled.h"
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +00002//
3// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers
9// retained by Renderbuffers.
10
11#include "libGLESv2/renderer/RenderTarget11.h"
12#include "libGLESv2/renderer/Renderer11.h"
13
14#include "libGLESv2/renderer/renderer11_utils.h"
15#include "libGLESv2/main.h"
16
17namespace rx
18{
19
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +000020static unsigned int getRTVSubresourceIndex(ID3D11Texture2D *texture, ID3D11RenderTargetView *view)
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +000021{
22 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
23 view->GetDesc(&rtvDesc);
24
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +000025 D3D11_TEXTURE2D_DESC texDesc;
26 texture->GetDesc(&texDesc);
27
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +000028 unsigned int mipSlice = 0;
29 unsigned int arraySlice = 0;
30 unsigned int mipLevels = texDesc.MipLevels;
31
32 switch (rtvDesc.ViewDimension)
33 {
34 case D3D11_RTV_DIMENSION_TEXTURE1D:
35 mipSlice = rtvDesc.Texture1D.MipSlice;
36 arraySlice = 0;
37 break;
38
39 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
40 mipSlice = rtvDesc.Texture1DArray.MipSlice;
41 arraySlice = rtvDesc.Texture1DArray.FirstArraySlice;
42 break;
43
44 case D3D11_RTV_DIMENSION_TEXTURE2D:
45 mipSlice = rtvDesc.Texture2D.MipSlice;
46 arraySlice = 0;
47 break;
48
49 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
50 mipSlice = rtvDesc.Texture2DArray.MipSlice;
51 arraySlice = rtvDesc.Texture2DArray.FirstArraySlice;
52 break;
53
54 case D3D11_RTV_DIMENSION_TEXTURE2DMS:
55 mipSlice = 0;
56 arraySlice = 0;
57 break;
58
59 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
60 mipSlice = 0;
61 arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice;
62 break;
63
64 case D3D11_RTV_DIMENSION_TEXTURE3D:
65 mipSlice = rtvDesc.Texture3D.MipSlice;
66 arraySlice = 0;
67 break;
68
69 case D3D11_RTV_DIMENSION_UNKNOWN:
70 case D3D11_RTV_DIMENSION_BUFFER:
71 UNIMPLEMENTED();
72 break;
73
74 default:
75 UNREACHABLE();
76 break;
77 }
78
79 return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
80}
81
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +000082static unsigned int getDSVSubresourceIndex(ID3D11Texture2D *texture, ID3D11DepthStencilView *view)
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +000083{
84 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
85 view->GetDesc(&dsvDesc);
86
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +000087 D3D11_TEXTURE2D_DESC texDesc;
88 texture->GetDesc(&texDesc);
89
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +000090 unsigned int mipSlice = 0;
91 unsigned int arraySlice = 0;
92 unsigned int mipLevels = texDesc.MipLevels;
93
94 switch (dsvDesc.ViewDimension)
95 {
96 case D3D11_DSV_DIMENSION_TEXTURE1D:
97 mipSlice = dsvDesc.Texture1D.MipSlice;
98 arraySlice = 0;
99 break;
100
101 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
102 mipSlice = dsvDesc.Texture1DArray.MipSlice;
103 arraySlice = dsvDesc.Texture1DArray.FirstArraySlice;
104 break;
105
106 case D3D11_DSV_DIMENSION_TEXTURE2D:
107 mipSlice = dsvDesc.Texture2D.MipSlice;
108 arraySlice = 0;
109 break;
110
111 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
112 mipSlice = dsvDesc.Texture2DArray.MipSlice;
113 arraySlice = dsvDesc.Texture2DArray.FirstArraySlice;
114 break;
115
116 case D3D11_DSV_DIMENSION_TEXTURE2DMS:
117 mipSlice = 0;
118 arraySlice = 0;
119 break;
120
121 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
122 mipSlice = 0;
123 arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice;
124 break;
125
126 case D3D11_RTV_DIMENSION_UNKNOWN:
127 UNIMPLEMENTED();
128 break;
129
130 default:
131 UNREACHABLE();
132 break;
133 }
134
135 return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
136}
137
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000138RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000139{
140 mRenderer = Renderer11::makeRenderer11(renderer);
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000141 mTexture = tex;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000142 mRenderTarget = rtv;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000143 mDepthStencil = NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000144 mShaderResource = srv;
shannon.woods@transgaming.com3e3da582013-02-28 23:09:03 +0000145 mSubresourceIndex = 0;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000146
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000147 if (mRenderTarget && mTexture)
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000148 {
149 D3D11_RENDER_TARGET_VIEW_DESC desc;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000150 mRenderTarget->GetDesc(&desc);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000151
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000152 D3D11_TEXTURE2D_DESC texDesc;
153 mTexture->GetDesc(&texDesc);
154
155 mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000156 mWidth = width;
157 mHeight = height;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000158 mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0;
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000159
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000160 mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
161 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000162 }
163}
164
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000165RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000166{
167 mRenderer = Renderer11::makeRenderer11(renderer);
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000168 mTexture = tex;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000169 mRenderTarget = NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000170 mDepthStencil = dsv;
171 mShaderResource = srv;
shannon.woods@transgaming.com3e3da582013-02-28 23:09:03 +0000172 mSubresourceIndex = 0;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000173
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000174 if (mDepthStencil && mTexture)
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000175 {
176 D3D11_DEPTH_STENCIL_VIEW_DESC desc;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000177 mDepthStencil->GetDesc(&desc);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000178
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000179 D3D11_TEXTURE2D_DESC texDesc;
180 mTexture->GetDesc(&texDesc);
181
182 mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000183 mWidth = width;
184 mHeight = height;
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000185 mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0;
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000186
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000187 mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
188 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000189 }
190}
191
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000192RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth)
193{
194 mRenderer = Renderer11::makeRenderer11(renderer);
shannon.woods@transgaming.com7e232852013-02-28 23:06:15 +0000195 mTexture = NULL;
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000196 mRenderTarget = NULL;
197 mDepthStencil = NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000198 mShaderResource = NULL;
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000199
200 DXGI_FORMAT requestedFormat = gl_d3d11::ConvertRenderbufferFormat(format);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000201
shannon.woods@transgaming.comae84f732013-02-28 23:05:57 +0000202 int supportedSamples = mRenderer->getNearestSupportedSamples(requestedFormat, samples);
203 if (supportedSamples < 0)
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000204 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000205 gl::error(GL_OUT_OF_MEMORY);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000206 return;
207 }
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
shannon.woods@transgaming.com8d8814b2013-02-28 23:10:53 +0000228 if (result == E_OUTOFMEMORY)
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000229 {
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
shannon.woods@transgaming.com8d8814b2013-02-28 23:10:53 +0000244 if (result == E_OUTOFMEMORY)
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000245 {
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
shannon.woods@transgaming.com8d8814b2013-02-28 23:10:53 +0000260 if (result == E_OUTOFMEMORY)
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000261 {
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
shannon.woods@transgaming.com8d8814b2013-02-28 23:10:53 +0000276 if (result == E_OUTOFMEMORY)
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000277 {
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}