Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / renderer / 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/d3d11/RenderTarget11.h"
12 #include "libGLESv2/renderer/d3d11/Renderer11.h"
13
14 #include "libGLESv2/renderer/d3d11/renderer11_utils.h"
15 #include "libGLESv2/renderer/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         mInternalFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion());
223         mActualFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion());
224     }
225 }
226
227 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource,
228                                ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth)
229 {
230     mRenderer = Renderer11::makeRenderer11(renderer);
231
232     mTexture = resource;
233     if (mTexture)
234     {
235         mTexture->AddRef();
236     }
237
238     mRenderTarget = NULL;
239
240     mDepthStencil = dsv;
241     if (mDepthStencil)
242     {
243         mDepthStencil->AddRef();
244     }
245
246     mShaderResource = srv;
247     if (mShaderResource)
248     {
249         mShaderResource->AddRef();
250     }
251
252     mSubresourceIndex = 0;
253
254     if (mDepthStencil && mTexture)
255     {
256         D3D11_DEPTH_STENCIL_VIEW_DESC desc;
257         mDepthStencil->GetDesc(&desc);
258
259         unsigned int mipLevels, samples;
260         getTextureProperties(mTexture, &mipLevels, &samples);
261
262         mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
263         mWidth = width;
264         mHeight = height;
265         mDepth = depth;
266         mSamples = samples;
267
268         mInternalFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion());
269         mActualFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion());
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     GLuint clientVersion = mRenderer->getCurrentClientVersion();
282
283     DXGI_FORMAT texFormat = gl_d3d11::GetTexFormat(internalFormat, clientVersion);
284     DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(internalFormat, clientVersion);
285     DXGI_FORMAT rtvFormat = gl_d3d11::GetRTVFormat(internalFormat, clientVersion);
286     DXGI_FORMAT dsvFormat = gl_d3d11::GetDSVFormat(internalFormat, clientVersion);
287
288     DXGI_FORMAT multisampleFormat = (dsvFormat != DXGI_FORMAT_UNKNOWN ? dsvFormat : rtvFormat);
289     int supportedSamples = mRenderer->getNearestSupportedSamples(multisampleFormat, samples);
290     if (supportedSamples < 0)
291     {
292         gl::error(GL_OUT_OF_MEMORY);
293         return;
294     }
295
296     if (width > 0 && height > 0)
297     {
298         // Create texture resource
299         D3D11_TEXTURE2D_DESC desc;
300         desc.Width = width; 
301         desc.Height = height;
302         desc.MipLevels = 1;
303         desc.ArraySize = 1;
304         desc.Format = texFormat;
305         desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
306         desc.SampleDesc.Quality = 0;
307         desc.Usage = D3D11_USAGE_DEFAULT;
308         desc.CPUAccessFlags = 0;
309         desc.MiscFlags = 0;
310
311         // If a rendertarget or depthstencil format exists for this texture format,
312         // we'll flag it to allow binding that way. Shader resource views are a little
313         // more complicated.
314         bool bindRTV = false, bindDSV = false, bindSRV = false;
315         bindRTV = (rtvFormat != DXGI_FORMAT_UNKNOWN);
316         bindDSV = (dsvFormat != DXGI_FORMAT_UNKNOWN);
317         if (srvFormat != DXGI_FORMAT_UNKNOWN)
318         {
319             // Multisample targets flagged for binding as depth stencil cannot also be
320             // flagged for binding as SRV, so make certain not to add the SRV flag for
321             // these targets.
322             bindSRV = !(dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1);
323         }
324
325         desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET   : 0) |
326                          (bindDSV ? D3D11_BIND_DEPTH_STENCIL   : 0) |
327                          (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0);
328
329         ID3D11Device *device = mRenderer->getDevice();
330         ID3D11Texture2D *texture = NULL;
331         HRESULT result = device->CreateTexture2D(&desc, NULL, &texture);
332         mTexture = texture;
333
334         if (result == E_OUTOFMEMORY)
335         {
336             gl::error(GL_OUT_OF_MEMORY);
337             return;
338         }
339         ASSERT(SUCCEEDED(result));
340
341         if (bindSRV)
342         {
343             D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
344             srvDesc.Format = srvFormat;
345             srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
346             srvDesc.Texture2D.MostDetailedMip = 0;
347             srvDesc.Texture2D.MipLevels = 1;
348             result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource);
349
350             if (result == E_OUTOFMEMORY)
351             {
352                 SafeRelease(mTexture);
353                 gl::error(GL_OUT_OF_MEMORY);
354                 return;
355             }
356             ASSERT(SUCCEEDED(result));
357         }
358
359         if (bindDSV)
360         {
361             D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
362             dsvDesc.Format = dsvFormat;
363             dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
364             dsvDesc.Texture2D.MipSlice = 0;
365             dsvDesc.Flags = 0;
366             result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil);
367
368             if (result == E_OUTOFMEMORY)
369             {
370                 SafeRelease(mTexture);
371                 SafeRelease(mShaderResource);
372                 gl::error(GL_OUT_OF_MEMORY);
373                 return;
374             }
375             ASSERT(SUCCEEDED(result));
376         }
377
378         if (bindRTV)
379         {
380             D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
381             rtvDesc.Format = rtvFormat;
382             rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
383             rtvDesc.Texture2D.MipSlice = 0;
384             result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget);
385
386             if (result == E_OUTOFMEMORY)
387             {
388                 SafeRelease(mTexture);
389                 SafeRelease(mShaderResource);
390                 SafeRelease(mDepthStencil);
391                 gl::error(GL_OUT_OF_MEMORY);
392                 return;
393             }
394             ASSERT(SUCCEEDED(result));
395
396             if (gl_d3d11::RequiresTextureDataInitialization(internalFormat))
397             {
398                 ID3D11DeviceContext *context = mRenderer->getDeviceContext();
399
400                 const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
401                 context->ClearRenderTargetView(mRenderTarget, clearValues);
402             }
403         }
404     }
405
406     mWidth = width;
407     mHeight = height;
408     mDepth = 1;
409     mInternalFormat = internalFormat;
410     mSamples = supportedSamples;
411     mActualFormat = d3d11_gl::GetInternalFormat(texFormat, renderer->getCurrentClientVersion());
412     mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
413 }
414
415 RenderTarget11::~RenderTarget11()
416 {
417     SafeRelease(mTexture);
418     SafeRelease(mRenderTarget);
419     SafeRelease(mDepthStencil);
420     SafeRelease(mShaderResource);
421 }
422
423 RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
424 {
425     ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target));
426     return static_cast<rx::RenderTarget11*>(target);
427 }
428
429 void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height)
430 {
431     // Currently a no-op
432 }
433
434 ID3D11Resource *RenderTarget11::getTexture() const
435 {
436     return mTexture;
437 }
438
439 ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
440 {
441     return mRenderTarget;
442 }
443
444 ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
445 {
446     return mDepthStencil;
447 }
448
449 ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const
450 {
451     return mShaderResource;
452 }
453
454 unsigned int RenderTarget11::getSubresourceIndex() const
455 {
456     return mSubresourceIndex;
457 }
458
459 }