Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / renderer / d3d / d3d11 / RenderTarget11.cpp
1 #include "precompiled.h"
2 //
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/d3d/d3d11/RenderTarget11.h"
12 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
13
14 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
15 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
16 #include "libGLESv2/main.h"
17
18 namespace rx
19 {
20
21 static bool getTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples)
22 {
23     ID3D11Texture1D *texture1D = d3d11::DynamicCastComObject<ID3D11Texture1D>(resource);
24     if (texture1D)
25     {
26         D3D11_TEXTURE1D_DESC texDesc;
27         texture1D->GetDesc(&texDesc);
28         SafeRelease(texture1D);
29
30         *mipLevels = texDesc.MipLevels;
31         *samples = 0;
32
33         return true;
34     }
35
36     ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource);
37     if (texture2D)
38     {
39         D3D11_TEXTURE2D_DESC texDesc;
40         texture2D->GetDesc(&texDesc);
41         SafeRelease(texture2D);
42
43         *mipLevels = texDesc.MipLevels;
44         *samples = texDesc.SampleDesc.Count > 1 ? texDesc.SampleDesc.Count : 0;
45
46         return true;
47     }
48
49     ID3D11Texture3D *texture3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(resource);
50     if (texture3D)
51     {
52         D3D11_TEXTURE3D_DESC texDesc;
53         texture3D->GetDesc(&texDesc);
54         SafeRelease(texture3D);
55
56         *mipLevels = texDesc.MipLevels;
57         *samples = 0;
58
59         return true;
60     }
61
62     return false;
63 }
64
65 static unsigned int getRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view)
66 {
67     D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
68     view->GetDesc(&rtvDesc);
69
70     unsigned int mipSlice = 0;
71     unsigned int arraySlice = 0;
72
73     switch (rtvDesc.ViewDimension)
74     {
75       case D3D11_RTV_DIMENSION_TEXTURE1D:
76         mipSlice = rtvDesc.Texture1D.MipSlice;
77         arraySlice = 0;
78         break;
79
80       case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
81         mipSlice = rtvDesc.Texture1DArray.MipSlice;
82         arraySlice = rtvDesc.Texture1DArray.FirstArraySlice;
83         break;
84
85       case D3D11_RTV_DIMENSION_TEXTURE2D:
86         mipSlice = rtvDesc.Texture2D.MipSlice;
87         arraySlice = 0;
88         break;
89
90       case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
91         mipSlice = rtvDesc.Texture2DArray.MipSlice;
92         arraySlice = rtvDesc.Texture2DArray.FirstArraySlice;
93         break;
94
95       case D3D11_RTV_DIMENSION_TEXTURE2DMS:
96         mipSlice = 0;
97         arraySlice = 0;
98         break;
99
100       case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
101         mipSlice = 0;
102         arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice;
103         break;
104
105       case D3D11_RTV_DIMENSION_TEXTURE3D:
106         mipSlice = rtvDesc.Texture3D.MipSlice;
107         arraySlice = 0;
108         break;
109
110       case D3D11_RTV_DIMENSION_UNKNOWN:
111       case D3D11_RTV_DIMENSION_BUFFER:
112         UNIMPLEMENTED();
113         break;
114
115       default:
116         UNREACHABLE();
117         break;
118     }
119
120     unsigned int mipLevels, samples;
121     getTextureProperties(resource,  &mipLevels, &samples);
122
123     return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
124 }
125
126 static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view)
127 {
128     D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
129     view->GetDesc(&dsvDesc);
130
131     unsigned int mipSlice = 0;
132     unsigned int arraySlice = 0;
133
134     switch (dsvDesc.ViewDimension)
135     {
136       case D3D11_DSV_DIMENSION_TEXTURE1D:
137         mipSlice = dsvDesc.Texture1D.MipSlice;
138         arraySlice = 0;
139         break;
140
141       case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
142         mipSlice = dsvDesc.Texture1DArray.MipSlice;
143         arraySlice = dsvDesc.Texture1DArray.FirstArraySlice;
144         break;
145
146       case D3D11_DSV_DIMENSION_TEXTURE2D:
147         mipSlice = dsvDesc.Texture2D.MipSlice;
148         arraySlice = 0;
149         break;
150
151       case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
152         mipSlice = dsvDesc.Texture2DArray.MipSlice;
153         arraySlice = dsvDesc.Texture2DArray.FirstArraySlice;
154         break;
155
156       case D3D11_DSV_DIMENSION_TEXTURE2DMS:
157         mipSlice = 0;
158         arraySlice = 0;
159         break;
160
161       case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
162         mipSlice = 0;
163         arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice;
164         break;
165
166       case D3D11_DSV_DIMENSION_UNKNOWN:
167         UNIMPLEMENTED();
168         break;
169
170       default:
171         UNREACHABLE();
172         break;
173     }
174
175     unsigned int mipLevels, samples;
176     getTextureProperties(resource, &mipLevels, &samples);
177
178     return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
179 }
180
181 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource,
182                                ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth)
183 {
184     mRenderer = Renderer11::makeRenderer11(renderer);
185
186     mTexture = resource;
187     if (mTexture)
188     {
189         mTexture->AddRef();
190     }
191
192     mRenderTarget = rtv;
193     if (mRenderTarget)
194     {
195         mRenderTarget->AddRef();
196     }
197
198     mDepthStencil = NULL;
199
200     mShaderResource = srv;
201     if (mShaderResource)
202     {
203         mShaderResource->AddRef();
204     }
205
206     mSubresourceIndex = 0;
207
208     if (mRenderTarget && mTexture)
209     {
210         D3D11_RENDER_TARGET_VIEW_DESC desc;
211         mRenderTarget->GetDesc(&desc);
212
213         unsigned int mipLevels, samples;
214         getTextureProperties(mTexture, &mipLevels, &samples);
215
216         mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
217         mWidth = width;
218         mHeight = height;
219         mDepth = depth;
220         mSamples = samples;
221
222         const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format);
223         mInternalFormat = dxgiFormatInfo.internalFormat;
224         mActualFormat = dxgiFormatInfo.internalFormat;
225     }
226 }
227
228 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource,
229                                ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth)
230 {
231     mRenderer = Renderer11::makeRenderer11(renderer);
232
233     mTexture = resource;
234     if (mTexture)
235     {
236         mTexture->AddRef();
237     }
238
239     mRenderTarget = NULL;
240
241     mDepthStencil = dsv;
242     if (mDepthStencil)
243     {
244         mDepthStencil->AddRef();
245     }
246
247     mShaderResource = srv;
248     if (mShaderResource)
249     {
250         mShaderResource->AddRef();
251     }
252
253     mSubresourceIndex = 0;
254
255     if (mDepthStencil && mTexture)
256     {
257         D3D11_DEPTH_STENCIL_VIEW_DESC desc;
258         mDepthStencil->GetDesc(&desc);
259
260         unsigned int mipLevels, samples;
261         getTextureProperties(mTexture, &mipLevels, &samples);
262
263         mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
264         mWidth = width;
265         mHeight = height;
266         mDepth = depth;
267         mSamples = samples;
268
269         const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(desc.Format);
270         mInternalFormat = dxgiFormatInfo.internalFormat;
271         mActualFormat = dxgiFormatInfo.internalFormat;
272     }
273 }
274
275 RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples)
276 {
277     mRenderer = Renderer11::makeRenderer11(renderer);
278     mTexture = NULL;
279     mRenderTarget = NULL;
280     mDepthStencil = NULL;
281     mShaderResource = NULL;
282
283     const d3d11::TextureFormat &formatInfo = d3d11::GetTextureFormatInfo(internalFormat);
284     const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(formatInfo.texFormat);
285
286     const gl::TextureCaps &textureCaps = mRenderer->getRendererTextureCaps().get(internalFormat);
287     GLuint supportedSamples = textureCaps.getNearestSamples(samples);
288
289     if (width > 0 && height > 0)
290     {
291         // Create texture resource
292         D3D11_TEXTURE2D_DESC desc;
293         desc.Width = width; 
294         desc.Height = height;
295         desc.MipLevels = 1;
296         desc.ArraySize = 1;
297         desc.Format = formatInfo.texFormat;
298         desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
299         desc.SampleDesc.Quality = 0;
300         desc.Usage = D3D11_USAGE_DEFAULT;
301         desc.CPUAccessFlags = 0;
302         desc.MiscFlags = 0;
303
304         // If a rendertarget or depthstencil format exists for this texture format,
305         // we'll flag it to allow binding that way. Shader resource views are a little
306         // more complicated.
307         bool bindRTV = false, bindDSV = false, bindSRV = false;
308         bindRTV = (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
309         bindDSV = (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
310         if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
311         {
312             // Multisample targets flagged for binding as depth stencil cannot also be
313             // flagged for binding as SRV, so make certain not to add the SRV flag for
314             // these targets.
315             bindSRV = !(formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1);
316         }
317
318         desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET   : 0) |
319                          (bindDSV ? D3D11_BIND_DEPTH_STENCIL   : 0) |
320                          (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0);
321
322         ID3D11Device *device = mRenderer->getDevice();
323         ID3D11Texture2D *texture = NULL;
324         HRESULT result = device->CreateTexture2D(&desc, NULL, &texture);
325         mTexture = texture;
326
327         if (result == E_OUTOFMEMORY)
328         {
329             gl::error(GL_OUT_OF_MEMORY);
330             return;
331         }
332         ASSERT(SUCCEEDED(result));
333
334         if (bindSRV)
335         {
336             D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
337             srvDesc.Format = formatInfo.srvFormat;
338             srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
339             srvDesc.Texture2D.MostDetailedMip = 0;
340             srvDesc.Texture2D.MipLevels = 1;
341             result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource);
342
343             if (result == E_OUTOFMEMORY)
344             {
345                 SafeRelease(mTexture);
346                 gl::error(GL_OUT_OF_MEMORY);
347                 return;
348             }
349             ASSERT(SUCCEEDED(result));
350         }
351
352         if (bindDSV)
353         {
354             D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
355             dsvDesc.Format = formatInfo.dsvFormat;
356             dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
357             dsvDesc.Texture2D.MipSlice = 0;
358             dsvDesc.Flags = 0;
359             result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil);
360
361             if (result == E_OUTOFMEMORY)
362             {
363                 SafeRelease(mTexture);
364                 SafeRelease(mShaderResource);
365                 gl::error(GL_OUT_OF_MEMORY);
366                 return;
367             }
368             ASSERT(SUCCEEDED(result));
369         }
370
371         if (bindRTV)
372         {
373             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
374             rtvDesc.Format = formatInfo.rtvFormat;
375             rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
376             rtvDesc.Texture2D.MipSlice = 0;
377             result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget);
378
379             if (result == E_OUTOFMEMORY)
380             {
381                 SafeRelease(mTexture);
382                 SafeRelease(mShaderResource);
383                 SafeRelease(mDepthStencil);
384                 gl::error(GL_OUT_OF_MEMORY);
385                 return;
386             }
387             ASSERT(SUCCEEDED(result));
388
389             if (formatInfo.dataInitializerFunction != NULL)
390             {
391                 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
392
393                 const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
394                 context->ClearRenderTargetView(mRenderTarget, clearValues);
395             }
396         }
397     }
398
399
400     mWidth = width;
401     mHeight = height;
402     mDepth = 1;
403     mInternalFormat = internalFormat;
404     mSamples = supportedSamples;
405     mActualFormat = dxgiFormatInfo.internalFormat;
406     mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
407 }
408
409 RenderTarget11::~RenderTarget11()
410 {
411     SafeRelease(mTexture);
412     SafeRelease(mRenderTarget);
413     SafeRelease(mDepthStencil);
414     SafeRelease(mShaderResource);
415 }
416
417 RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
418 {
419     ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target));
420     return static_cast<rx::RenderTarget11*>(target);
421 }
422
423 void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
424 {
425     // Currently a no-op
426 }
427
428 ID3D11Resource *RenderTarget11::getTexture() const
429 {
430     return mTexture;
431 }
432
433 ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
434 {
435     return mRenderTarget;
436 }
437
438 ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
439 {
440     return mDepthStencil;
441 }
442
443 ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const
444 {
445     return mShaderResource;
446 }
447
448 unsigned int RenderTarget11::getSubresourceIndex() const
449 {
450     return mSubresourceIndex;
451 }
452
453 }