blob: 0fb50438b84ea3a1d175e2a2ea108d2366b9bb2b [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
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000180RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *view, GLsizei width, GLsizei height)
181{
182 mRenderer = Renderer11::makeRenderer11(renderer);
183 mRenderTarget = view;
184 mDepthStencil = NULL;
185
186 if (mRenderTarget)
187 {
188 D3D11_RENDER_TARGET_VIEW_DESC desc;
189 view->GetDesc(&desc);
190
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000191 mSubresourceIndex = getRTVSubresourceIndex(mRenderTarget);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000192 mWidth = width;
193 mHeight = height;
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000194
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000195 mInternalFormat = d3d11_gl::ConvertRenderbufferFormat(desc.Format);
196 mActualFormat = d3d11_gl::ConvertRenderbufferFormat(desc.Format);
197 mSamples = 1; // TEMP?
198 }
199}
200
201RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *view, GLsizei width, GLsizei height)
202{
203 mRenderer = Renderer11::makeRenderer11(renderer);
204 mRenderTarget = NULL;
205 mDepthStencil = view;
206
207 if (mDepthStencil)
208 {
209 D3D11_DEPTH_STENCIL_VIEW_DESC desc;
210 view->GetDesc(&desc);
211
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000212 mSubresourceIndex = getDSVSubresourceIndex(mDepthStencil);
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000213 mWidth = width;
214 mHeight = height;
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000215
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000216 mInternalFormat = d3d11_gl::ConvertRenderbufferFormat(desc.Format);
217 mActualFormat = d3d11_gl::ConvertRenderbufferFormat(desc.Format);
218 mSamples = 1; // TEMP?
219 }
220}
221
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000222RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth)
223{
224 mRenderer = Renderer11::makeRenderer11(renderer);
225 mRenderTarget = NULL;
226 mDepthStencil = NULL;
227
228 DXGI_FORMAT requestedFormat = gl_d3d11::ConvertRenderbufferFormat(format);
daniel@transgaming.com168763a2013-01-11 04:09:56 +0000229 int supportedSamples = 0; // TODO - Multisample support query
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000230
231 if (supportedSamples == -1)
232 {
233 error(GL_OUT_OF_MEMORY);
234
235 return;
236 }
237
238 HRESULT result = D3DERR_INVALIDCALL;
239
240 if (width > 0 && height > 0)
241 {
242 // Create texture resource
243 D3D11_TEXTURE2D_DESC desc;
244 desc.Width = width;
245 desc.Height = height;
246 desc.MipLevels = 1;
247 desc.ArraySize = 1;
248 desc.Format = requestedFormat;
daniel@transgaming.com168763a2013-01-11 04:09:56 +0000249 desc.SampleDesc.Count = (supportedSamples == 0 ? 1 : supportedSamples);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000250 desc.SampleDesc.Quality = 0;
251 desc.Usage = D3D11_USAGE_DEFAULT;
252 desc.CPUAccessFlags = 0;
253 desc.MiscFlags = 0;
254 desc.BindFlags = (depth ? D3D11_BIND_DEPTH_STENCIL : D3D11_BIND_RENDER_TARGET);
255 ID3D11Texture2D *rtTexture = NULL;
256
257 ID3D11Device *device = mRenderer->getDevice();
258 HRESULT result = device->CreateTexture2D(&desc, NULL, &rtTexture);
259
260 if (SUCCEEDED(result))
261 {
262 if (depth)
263 {
264 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
265 dsvDesc.Format = requestedFormat;
266 dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
267 dsvDesc.Texture2D.MipSlice = 0;
daniel@transgaming.com442cdc12013-01-11 04:09:49 +0000268 dsvDesc.Flags = 0;
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000269 result = device->CreateDepthStencilView(rtTexture, &dsvDesc, &mDepthStencil);
270 }
271 else
272 {
273 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
274 rtvDesc.Format = requestedFormat;
275 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
276 rtvDesc.Texture2D.MipSlice = 0;
277 result = device->CreateRenderTargetView(rtTexture, &rtvDesc, &mRenderTarget);
278 }
279
280 rtTexture->Release();
281 }
282
283 if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
284 {
285 error(GL_OUT_OF_MEMORY);
286
287 return;
288 }
289
290 ASSERT(SUCCEEDED(result));
291 }
292
293 mWidth = width;
294 mHeight = height;
295 mInternalFormat = format;
296 mSamples = supportedSamples;
297 mActualFormat = format;
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000298 mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
daniel@transgaming.comc9a501d2013-01-11 04:08:46 +0000299}
300
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000301RenderTarget11::~RenderTarget11()
302{
303 if (mRenderTarget)
304 {
305 mRenderTarget->Release();
306 }
307
308 if (mDepthStencil)
309 {
310 mDepthStencil->Release();
311 }
312}
313
314RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
315{
316 ASSERT(dynamic_cast<rx::RenderTarget11*>(target) != NULL);
317 return static_cast<rx::RenderTarget11*>(target);
318}
319
daniel@transgaming.com816c7f32012-11-28 21:02:01 +0000320// Adds reference, caller must call Release
321ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
322{
323 if (mRenderTarget)
324 {
325 mRenderTarget->AddRef();
326 }
327
328 return mRenderTarget;
329}
330
331// Adds reference, caller must call Release
332ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
333{
334 if (mDepthStencil)
335 {
336 mDepthStencil->AddRef();
337 }
338
339 return mDepthStencil;
340}
341
daniel@transgaming.comb68d2bb2013-01-11 04:10:15 +0000342unsigned int RenderTarget11::getSubresourceIndex() const
343{
344 return mSubresourceIndex;
345}
346
daniel@transgaming.comb6b27bc2012-11-28 20:54:30 +0000347}