blob: 98cc78df087d018bdc339e3c79e08bc341c7dde5 [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
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +000019static ID3D11Texture2D *getTextureResource(ID3D11View *view)
20{
21 ID3D11Resource *textureResource = NULL;
22 view->GetResource(&textureResource);
23 if (!textureResource)
24 {
25 return NULL;
26 }
27
28 ID3D11Texture2D *texture = NULL;
29 HRESULT result = textureResource->QueryInterface(IID_ID3D11Texture2D, (void**)&texture);
30
31 textureResource->Release();
32 textureResource = NULL;
33
34 if (FAILED(result))
35 {
36 return NULL;
37 }
38
39 return texture;
40}
41
42static unsigned int getRTVSubresourceIndex(ID3D11RenderTargetView *view)
43{
44 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
45 view->GetDesc(&rtvDesc);
46
47 ID3D11Texture2D *texture = getTextureResource(view);
48 if (!texture)
49 {
50 ERR("Failed to extract the ID3D11Texture2D from the render target view.");
51 return 0;
52 }
53
54 D3D11_TEXTURE2D_DESC texDesc;
55 texture->GetDesc(&texDesc);
56
57 texture->Release();
58 texture = NULL;
59
60 unsigned int mipSlice = 0;
61 unsigned int arraySlice = 0;
62 unsigned int mipLevels = texDesc.MipLevels;
63
64 switch (rtvDesc.ViewDimension)
65 {
66 case D3D11_RTV_DIMENSION_TEXTURE1D:
67 mipSlice = rtvDesc.Texture1D.MipSlice;
68 arraySlice = 0;
69 break;
70
71 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
72 mipSlice = rtvDesc.Texture1DArray.MipSlice;
73 arraySlice = rtvDesc.Texture1DArray.FirstArraySlice;
74 break;
75
76 case D3D11_RTV_DIMENSION_TEXTURE2D:
77 mipSlice = rtvDesc.Texture2D.MipSlice;
78 arraySlice = 0;
79 break;
80
81 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
82 mipSlice = rtvDesc.Texture2DArray.MipSlice;
83 arraySlice = rtvDesc.Texture2DArray.FirstArraySlice;
84 break;
85
86 case D3D11_RTV_DIMENSION_TEXTURE2DMS:
87 mipSlice = 0;
88 arraySlice = 0;
89 break;
90
91 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
92 mipSlice = 0;
93 arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice;
94 break;
95
96 case D3D11_RTV_DIMENSION_TEXTURE3D:
97 mipSlice = rtvDesc.Texture3D.MipSlice;
98 arraySlice = 0;
99 break;
100
101 case D3D11_RTV_DIMENSION_UNKNOWN:
102 case D3D11_RTV_DIMENSION_BUFFER:
103 UNIMPLEMENTED();
104 break;
105
106 default:
107 UNREACHABLE();
108 break;
109 }
110
111 return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
112}
113
114static unsigned int getDSVSubresourceIndex(ID3D11DepthStencilView *view)
115{
116 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
117 view->GetDesc(&dsvDesc);
118
119 ID3D11Texture2D *texture = getTextureResource(view);
120 if (!texture)
121 {
122 ERR("Failed to extract the ID3D11Texture2D from the depth stencil view.");
123 return 0;
124 }
125
126 D3D11_TEXTURE2D_DESC texDesc;
127 texture->GetDesc(&texDesc);
128
129 texture->Release();
130 texture = NULL;
131
132 unsigned int mipSlice = 0;
133 unsigned int arraySlice = 0;
134 unsigned int mipLevels = texDesc.MipLevels;
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_RTV_DIMENSION_UNKNOWN:
169 UNIMPLEMENTED();
170 break;
171
172 default:
173 UNREACHABLE();
174 break;
175 }
176
177 return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
178}
179
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000180RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000181{
182 mRenderer = Renderer11::makeRenderer11(renderer);
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000183 mRenderTarget = rtv;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000184 mDepthStencil = NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000185 mShaderResource = srv;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000186
187 if (mRenderTarget)
188 {
189 D3D11_RENDER_TARGET_VIEW_DESC desc;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000190 mRenderTarget->GetDesc(&desc);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000191
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000192 mSubresourceIndex = getRTVSubresourceIndex(mRenderTarget);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000193 mWidth = width;
194 mHeight = height;
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000195
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000196 mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
197 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000198 mSamples = 1; // TEMP?
199 }
200}
201
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000202RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000203{
204 mRenderer = Renderer11::makeRenderer11(renderer);
205 mRenderTarget = NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000206 mDepthStencil = dsv;
207 mShaderResource = srv;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000208
209 if (mDepthStencil)
210 {
211 D3D11_DEPTH_STENCIL_VIEW_DESC desc;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000212 mDepthStencil->GetDesc(&desc);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000213
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000214 mSubresourceIndex = getDSVSubresourceIndex(mDepthStencil);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000215 mWidth = width;
216 mHeight = height;
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000217
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000218 mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
219 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000220 mSamples = 1; // TEMP?
221 }
222}
223
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000224RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth)
225{
226 mRenderer = Renderer11::makeRenderer11(renderer);
227 mRenderTarget = NULL;
228 mDepthStencil = NULL;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000229 mShaderResource = NULL;
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000230
231 DXGI_FORMAT requestedFormat = gl_d3d11::ConvertRenderbufferFormat(format);
daniel@transgaming.com168763a2013-01-11 04:09:56 +0000232 int supportedSamples = 0; // TODO - Multisample support query
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000233
234 if (supportedSamples == -1)
235 {
236 error(GL_OUT_OF_MEMORY);
237
238 return;
239 }
240
241 HRESULT result = D3DERR_INVALIDCALL;
242
243 if (width > 0 && height > 0)
244 {
245 // Create texture resource
246 D3D11_TEXTURE2D_DESC desc;
247 desc.Width = width;
248 desc.Height = height;
249 desc.MipLevels = 1;
250 desc.ArraySize = 1;
251 desc.Format = requestedFormat;
daniel@transgaming.com168763a2013-01-11 04:09:56 +0000252 desc.SampleDesc.Count = (supportedSamples == 0 ? 1 : supportedSamples);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000253 desc.SampleDesc.Quality = 0;
254 desc.Usage = D3D11_USAGE_DEFAULT;
255 desc.CPUAccessFlags = 0;
256 desc.MiscFlags = 0;
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000257 desc.BindFlags = (depth ? D3D11_BIND_DEPTH_STENCIL : (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE));
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000258 ID3D11Texture2D *rtTexture = NULL;
259
260 ID3D11Device *device = mRenderer->getDevice();
261 HRESULT result = device->CreateTexture2D(&desc, NULL, &rtTexture);
262
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000263 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
264 {
265 error(GL_OUT_OF_MEMORY);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000266 return;
267 }
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000268 ASSERT(SUCCEEDED(result));
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000269
270 if (depth)
271 {
272 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
273 dsvDesc.Format = requestedFormat;
274 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
275 dsvDesc.Texture2D.MipSlice = 0;
276 dsvDesc.Flags = 0;
277 result = device->CreateDepthStencilView(rtTexture, &dsvDesc, &mDepthStencil);
278
279 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
280 {
281 rtTexture->Release();
282 error(GL_OUT_OF_MEMORY);
283 return;
284 }
285 ASSERT(SUCCEEDED(result));
286 }
287 else
288 {
289 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
290 rtvDesc.Format = requestedFormat;
291 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
292 rtvDesc.Texture2D.MipSlice = 0;
293 result = device->CreateRenderTargetView(rtTexture, &rtvDesc, &mRenderTarget);
294
295 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
296 {
297 rtTexture->Release();
298 error(GL_OUT_OF_MEMORY);
299 return;
300 }
301 ASSERT(SUCCEEDED(result));
302
303 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
304 srvDesc.Format = requestedFormat;
305 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
306 srvDesc.Texture2D.MostDetailedMip = 0;
307 srvDesc.Texture2D.MipLevels = 1;
308 result = device->CreateShaderResourceView(rtTexture, &srvDesc, &mShaderResource);
309
310 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
311 {
312 rtTexture->Release();
313 mRenderTarget->Release();
314 error(GL_OUT_OF_MEMORY);
315 return;
316 }
317 ASSERT(SUCCEEDED(result));
318 }
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000319 }
320
321 mWidth = width;
322 mHeight = height;
323 mInternalFormat = format;
324 mSamples = supportedSamples;
325 mActualFormat = format;
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000326 mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000327}
328
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000329RenderTarget11::~RenderTarget11()
330{
331 if (mRenderTarget)
332 {
333 mRenderTarget->Release();
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000334 mRenderTarget = NULL;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000335 }
336
337 if (mDepthStencil)
338 {
339 mDepthStencil->Release();
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000340 mDepthStencil = NULL;
341 }
342
343 if (mShaderResource)
344 {
345 mShaderResource->Release();
346 mShaderResource = NULL;
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000347 }
348}
349
350RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
351{
352 ASSERT(dynamic_cast<rx::RenderTarget11*>(target) != NULL);
353 return static_cast<rx::RenderTarget11*>(target);
354}
355
daniel@transgaming.com816c7f32012-11-28 21:02:01 +0000356// Adds reference, caller must call Release
357ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
358{
359 if (mRenderTarget)
360 {
361 mRenderTarget->AddRef();
362 }
363
364 return mRenderTarget;
365}
366
367// Adds reference, caller must call Release
368ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
369{
370 if (mDepthStencil)
371 {
372 mDepthStencil->AddRef();
373 }
374
375 return mDepthStencil;
376}
377
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000378// Adds reference, caller must call Release
379ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const
380{
381 if (mShaderResource)
382 {
383 mShaderResource->AddRef();
384 }
385
386 return mShaderResource;
387}
388
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000389unsigned int RenderTarget11::getSubresourceIndex() const
390{
391 return mSubresourceIndex;
392}
393
shannon.woods@transgaming.com183408d2013-01-25 21:50:07 +0000394}