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