1d20fd9e650e5329833af48ce0c850229c415c70
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / renderer / d3d / d3d11 / Clear11.cpp
1 #include "precompiled.h"
2 //
3 // Copyright (c) 2013 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 // Clear11.cpp: Framebuffer clear utility class.
9
10 #include "libGLESv2/renderer/d3d/d3d11/Clear11.h"
11 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
12 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
13 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
14
15 #include "libGLESv2/formatutils.h"
16 #include "libGLESv2/Framebuffer.h"
17 #include "libGLESv2/FramebufferAttachment.h"
18
19 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11vs.h"
20 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearfloat11ps.h"
21
22 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuint11vs.h"
23 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearuint11ps.h"
24
25 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsint11vs.h"
26 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/clearsint11ps.h"
27
28 namespace rx
29 {
30
31 template <typename T>
32 static void ApplyVertices(const gl::Extents &framebufferSize, const gl::Rectangle *scissor, const gl::Color<T> &color, float depth, void *buffer)
33 {
34     d3d11::PositionDepthColorVertex<T> *vertices = reinterpret_cast<d3d11::PositionDepthColorVertex<T>*>(buffer);
35
36     float depthClear = gl::clamp01(depth);
37     float left = -1.0f;
38     float right = 1.0f;
39     float top = -1.0f;
40     float bottom = 1.0f;
41
42     // Clip the quad coordinates to the scissor if needed
43     if (scissor != NULL)
44     {
45         left = std::max(left, (scissor->x / float(framebufferSize.width)) * 2.0f - 1.0f);
46         right = std::min(right, ((scissor->x + scissor->width) / float(framebufferSize.width)) * 2.0f - 1.0f);
47         top = std::max(top, ((framebufferSize.height - scissor->y - scissor->height) / float(framebufferSize.height)) * 2.0f - 1.0f);
48         bottom = std::min(bottom, ((framebufferSize.height - scissor->y) / float(framebufferSize.height)) * 2.0f - 1.0f);
49     }
50
51     d3d11::SetPositionDepthColorVertex<T>(vertices + 0, left,  bottom, depthClear, color);
52     d3d11::SetPositionDepthColorVertex<T>(vertices + 1, left,  top,    depthClear, color);
53     d3d11::SetPositionDepthColorVertex<T>(vertices + 2, right, bottom, depthClear, color);
54     d3d11::SetPositionDepthColorVertex<T>(vertices + 3, right, top,    depthClear, color);
55 }
56
57 template <unsigned int vsSize, unsigned int psSize>
58 Clear11::ClearShader Clear11::CreateClearShader(ID3D11Device *device, DXGI_FORMAT colorType, const BYTE (&vsByteCode)[vsSize], const BYTE (&psByteCode)[psSize])
59 {
60     HRESULT result;
61
62     ClearShader shader = { 0 };
63
64     D3D11_INPUT_ELEMENT_DESC quadLayout[] =
65     {
66         { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
67         { "COLOR",    0, colorType,                   0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
68     };
69
70     result = device->CreateInputLayout(quadLayout, ArraySize(quadLayout), vsByteCode, vsSize, &shader.inputLayout);
71     ASSERT(SUCCEEDED(result));
72
73     result = device->CreateVertexShader(vsByteCode, vsSize, NULL, &shader.vertexShader);
74     ASSERT(SUCCEEDED(result));
75
76     result = device->CreatePixelShader(psByteCode, psSize, NULL, &shader.pixelShader);
77     ASSERT(SUCCEEDED(result));
78
79     return shader;
80 }
81
82 Clear11::Clear11(Renderer11 *renderer)
83     : mRenderer(renderer), mClearBlendStates(StructLessThan<ClearBlendInfo>), mClearDepthStencilStates(StructLessThan<ClearDepthStencilInfo>),
84       mVertexBuffer(NULL), mRasterizerState(NULL)
85 {
86     HRESULT result;
87     ID3D11Device *device = renderer->getDevice();
88
89     D3D11_BUFFER_DESC vbDesc;
90     vbDesc.ByteWidth = sizeof(d3d11::PositionDepthColorVertex<float>) * 4;
91     vbDesc.Usage = D3D11_USAGE_DYNAMIC;
92     vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
93     vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
94     vbDesc.MiscFlags = 0;
95     vbDesc.StructureByteStride = 0;
96
97     result = device->CreateBuffer(&vbDesc, NULL, &mVertexBuffer);
98     ASSERT(SUCCEEDED(result));
99     d3d11::SetDebugName(mVertexBuffer, "Clear11 masked clear vertex buffer");
100
101     D3D11_RASTERIZER_DESC rsDesc;
102     rsDesc.FillMode = D3D11_FILL_SOLID;
103     rsDesc.CullMode = D3D11_CULL_NONE;
104     rsDesc.FrontCounterClockwise = FALSE;
105     rsDesc.DepthBias = 0;
106     rsDesc.DepthBiasClamp = 0.0f;
107     rsDesc.SlopeScaledDepthBias = 0.0f;
108     rsDesc.DepthClipEnable = FALSE;
109     rsDesc.ScissorEnable = FALSE;
110     rsDesc.MultisampleEnable = FALSE;
111     rsDesc.AntialiasedLineEnable = FALSE;
112
113     result = device->CreateRasterizerState(&rsDesc, &mRasterizerState);
114     ASSERT(SUCCEEDED(result));
115     d3d11::SetDebugName(mRasterizerState, "Clear11 masked clear rasterizer state");
116
117     mFloatClearShader = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_FLOAT, g_VS_ClearFloat, g_PS_ClearFloat);
118     mUintClearShader  = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_UINT,  g_VS_ClearUint,  g_PS_ClearUint );
119     mIntClearShader   = CreateClearShader(device, DXGI_FORMAT_R32G32B32A32_SINT,  g_VS_ClearSint,  g_PS_ClearSint );
120 }
121
122 Clear11::~Clear11()
123 {
124     for (ClearBlendStateMap::iterator i = mClearBlendStates.begin(); i != mClearBlendStates.end(); i++)
125     {
126         SafeRelease(i->second);
127     }
128     mClearBlendStates.clear();
129
130     SafeRelease(mFloatClearShader.inputLayout);
131     SafeRelease(mFloatClearShader.vertexShader);
132     SafeRelease(mFloatClearShader.pixelShader);
133
134     SafeRelease(mUintClearShader.inputLayout);
135     SafeRelease(mUintClearShader.vertexShader);
136     SafeRelease(mUintClearShader.pixelShader);
137
138     SafeRelease(mIntClearShader.inputLayout);
139     SafeRelease(mIntClearShader.vertexShader);
140     SafeRelease(mIntClearShader.pixelShader);
141
142     for (ClearDepthStencilStateMap::iterator i = mClearDepthStencilStates.begin(); i != mClearDepthStencilStates.end(); i++)
143     {
144         SafeRelease(i->second);
145     }
146     mClearDepthStencilStates.clear();
147
148     SafeRelease(mVertexBuffer);
149     SafeRelease(mRasterizerState);
150 }
151
152 void Clear11::clearFramebuffer(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
153 {
154     // First determine if a scissored clear is needed, this will always require drawing a quad.
155     //
156     // Otherwise, iterate over the color buffers which require clearing and determine if they can be
157     // cleared with ID3D11DeviceContext::ClearRenderTargetView... This requires:
158     // 1) The render target is being cleared to a float value (will be cast to integer when clearing integer
159     //    render targets as expected but does not work the other way around)
160     // 2) The format of the render target has no color channels that are currently masked out.
161     // Clear the easy-to-clear buffers on the spot and accumulate the ones that require special work.
162     //
163     // Also determine if the depth stencil can be cleared with ID3D11DeviceContext::ClearDepthStencilView
164     // by checking if the stencil write mask covers the entire stencil.
165     //
166     // To clear the remaining buffers, quads must be drawn containing an int, uint or float vertex color
167     // attribute.
168
169     gl::Extents framebufferSize;
170     if (frameBuffer->getFirstColorbuffer() != NULL)
171     {
172         gl::FramebufferAttachment *attachment = frameBuffer->getFirstColorbuffer();
173         framebufferSize.width = attachment->getWidth();
174         framebufferSize.height = attachment->getHeight();
175         framebufferSize.depth = 1;
176     }
177     else if (frameBuffer->getDepthOrStencilbuffer() != NULL)
178     {
179         gl::FramebufferAttachment *attachment = frameBuffer->getDepthOrStencilbuffer();
180         framebufferSize.width = attachment->getWidth();
181         framebufferSize.height = attachment->getHeight();
182         framebufferSize.depth = 1;
183     }
184     else
185     {
186         UNREACHABLE();
187         return;
188     }
189
190     if (clearParams.scissorEnabled && (clearParams.scissor.x >= framebufferSize.width || 
191                                        clearParams.scissor.y >= framebufferSize.height ||
192                                        clearParams.scissor.x + clearParams.scissor.width <= 0 ||
193                                        clearParams.scissor.y + clearParams.scissor.height <= 0))
194     {
195         // Scissor is enabled and the scissor rectangle is outside the renderbuffer
196         return;
197     }
198
199     bool needScissoredClear = clearParams.scissorEnabled && (clearParams.scissor.x > 0 || clearParams.scissor.y > 0 ||
200                                                              clearParams.scissor.x + clearParams.scissor.width < framebufferSize.width ||
201                                                              clearParams.scissor.y + clearParams.scissor.height < framebufferSize.height);
202
203     std::vector<MaskedRenderTarget> maskedClearRenderTargets;
204     RenderTarget11* maskedClearDepthStencil = NULL;
205
206     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
207
208     for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
209     {
210         if (clearParams.clearColor[colorAttachment] && frameBuffer->isEnabledColorAttachment(colorAttachment))
211         {
212             gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(colorAttachment);
213             if (attachment)
214             {
215                 RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(attachment->getRenderTarget());
216                 if (!renderTarget)
217                 {
218                     ERR("Render target pointer unexpectedly null.");
219                     return;
220                 }
221
222                 const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat());
223
224                 if (clearParams.colorClearType == GL_FLOAT &&
225                     !(formatInfo.componentType == GL_FLOAT || formatInfo.componentType == GL_UNSIGNED_NORMALIZED || formatInfo.componentType == GL_SIGNED_NORMALIZED))
226                 {
227                     ERR("It is undefined behaviour to clear a render buffer which is not normalized fixed point or floating-"
228                         "point to floating point values (color attachment %u has internal format 0x%X).", colorAttachment,
229                         attachment->getInternalFormat());
230                 }
231
232                 if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) &&
233                     (formatInfo.greenBits == 0 || !clearParams.colorMaskGreen) &&
234                     (formatInfo.blueBits == 0 || !clearParams.colorMaskBlue) &&
235                     (formatInfo.alphaBits == 0 || !clearParams.colorMaskAlpha))
236                 {
237                     // Every channel either does not exist in the render target or is masked out
238                     continue;
239                 }
240                 else if (needScissoredClear || clearParams.colorClearType != GL_FLOAT ||
241                          (formatInfo.redBits   > 0 && !clearParams.colorMaskRed)   ||
242                          (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) ||
243                          (formatInfo.blueBits  > 0 && !clearParams.colorMaskBlue) ||
244                          (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha))
245                 {
246                     // A scissored or masked clear is required
247                     MaskedRenderTarget maskAndRt;
248                     bool clearColor = clearParams.clearColor[colorAttachment];
249                     maskAndRt.colorMask[0] = (clearColor && clearParams.colorMaskRed);
250                     maskAndRt.colorMask[1] = (clearColor && clearParams.colorMaskGreen);
251                     maskAndRt.colorMask[2] = (clearColor && clearParams.colorMaskBlue);
252                     maskAndRt.colorMask[3] = (clearColor && clearParams.colorMaskAlpha);
253                     maskAndRt.renderTarget = renderTarget;
254                     maskedClearRenderTargets.push_back(maskAndRt);
255                 }
256                 else
257                 {
258                     // ID3D11DeviceContext::ClearRenderTargetView is possible
259
260                     ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView();
261                     if (!framebufferRTV)
262                     {
263                         ERR("Render target view pointer unexpectedly null.");
264                         return;
265                     }
266
267                     const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat());
268
269                     // Check if the actual format has a channel that the internal format does not and set them to the
270                     // default values
271                     const float clearValues[4] =
272                     {
273                         ((formatInfo.redBits == 0 && actualFormatInfo.redBits   > 0) ? 0.0f : clearParams.colorFClearValue.red),
274                         ((formatInfo.greenBits == 0 && actualFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green),
275                         ((formatInfo.blueBits == 0 && actualFormatInfo.blueBits  > 0) ? 0.0f : clearParams.colorFClearValue.blue),
276                         ((formatInfo.alphaBits == 0 && actualFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha),
277                     };
278
279                     deviceContext->ClearRenderTargetView(framebufferRTV, clearValues);
280                 }
281             }
282         }
283     }
284
285     if (clearParams.clearDepth || clearParams.clearStencil)
286     {
287         gl::FramebufferAttachment *attachment = frameBuffer->getDepthOrStencilbuffer();
288         if (attachment)
289         {
290             RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(attachment->getDepthStencil());
291             if (!renderTarget)
292             {
293                 ERR("Depth stencil render target pointer unexpectedly null.");
294                 return;
295             }
296
297             const gl::InternalFormat &actualFormatInfo = gl::GetInternalFormatInfo(attachment->getActualFormat());
298
299             unsigned int stencilUnmasked = frameBuffer->hasStencil() ? (1 << actualFormatInfo.stencilBits) - 1 : 0;
300             bool needMaskedStencilClear = clearParams.clearStencil && (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
301
302             if (needScissoredClear || needMaskedStencilClear)
303             {
304                 maskedClearDepthStencil = renderTarget;
305             }
306             else
307             {
308                 ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView();
309                 if (!framebufferDSV)
310                 {
311                     ERR("Depth stencil view pointer unexpectedly null.");
312                     return;
313                 }
314
315                 UINT clearFlags = (clearParams.clearDepth   ? D3D11_CLEAR_DEPTH   : 0) |
316                                   (clearParams.clearStencil ? D3D11_CLEAR_STENCIL : 0);
317                 FLOAT depthClear = gl::clamp01(clearParams.depthClearValue);
318                 UINT8 stencilClear = clearParams.stencilClearValue & 0xFF;
319
320                 deviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear);
321             }
322         }
323     }
324
325     if (maskedClearRenderTargets.size() > 0 || maskedClearDepthStencil)
326     {
327         // To clear the render targets and depth stencil in one pass:
328         //
329         // Render a quad clipped to the scissor rectangle which draws the clear color and a blend
330         // state that will perform the required color masking.
331         //
332         // The quad's depth is equal to the depth clear value with a depth stencil state that
333         // will enable or disable depth test/writes if the depth buffer should be cleared or not.
334         //
335         // The rasterizer state's stencil is set to always pass or fail based on if the stencil
336         // should be cleared or not with a stencil write mask of the stencil clear value.
337         //
338         // ======================================================================================
339         //
340         // Luckily, the gl spec (ES 3.0.2 pg 183) states that the results of clearing a render-
341         // buffer that is not normalized fixed point or floating point with floating point values
342         // are undefined so we can just write floats to them and D3D11 will bit cast them to
343         // integers.
344         //
345         // Also, we don't have to worry about attempting to clear a normalized fixed/floating point
346         // buffer with integer values because there is no gl API call which would allow it,
347         // glClearBuffer* calls only clear a single renderbuffer at a time which is verified to
348         // be a compatible clear type.
349
350         // Bind all the render targets which need clearing
351         ASSERT(maskedClearRenderTargets.size() <= mRenderer->getRendererCaps().maxDrawBuffers);
352         std::vector<ID3D11RenderTargetView*> rtvs(maskedClearRenderTargets.size());
353         for (unsigned int i = 0; i < maskedClearRenderTargets.size(); i++)
354         {
355             RenderTarget11 *renderTarget = maskedClearRenderTargets[i].renderTarget;
356             ID3D11RenderTargetView *rtv = renderTarget->getRenderTargetView();
357             if (!rtv)
358             {
359                 ERR("Render target view unexpectedly null.");
360                 return;
361             }
362
363             rtvs[i] = rtv;
364         }
365         ID3D11DepthStencilView *dsv = maskedClearDepthStencil ? maskedClearDepthStencil->getDepthStencilView() : NULL;
366
367         ID3D11BlendState *blendState = getBlendState(maskedClearRenderTargets);
368         const FLOAT blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
369         const UINT sampleMask = 0xFFFFFFFF;
370
371         ID3D11DepthStencilState *dsState = getDepthStencilState(clearParams);
372         const UINT stencilClear = clearParams.stencilClearValue & 0xFF;
373
374         // Set the vertices
375         UINT vertexStride = 0;
376         const UINT startIdx = 0;
377         const ClearShader* shader = NULL;
378         D3D11_MAPPED_SUBRESOURCE mappedResource;
379         HRESULT result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
380         if (FAILED(result))
381         {
382             ERR("Failed to map masked clear vertex buffer, HRESULT: 0x%X.", result);
383             return;
384         }
385
386         const gl::Rectangle *scissorPtr = clearParams.scissorEnabled ? &clearParams.scissor : NULL;
387         switch (clearParams.colorClearType)
388         {
389           case GL_FLOAT:
390             ApplyVertices(framebufferSize, scissorPtr, clearParams.colorFClearValue, clearParams.depthClearValue, mappedResource.pData);
391             vertexStride = sizeof(d3d11::PositionDepthColorVertex<float>);
392             shader = &mFloatClearShader;
393             break;
394
395           case GL_UNSIGNED_INT:
396             ApplyVertices(framebufferSize, scissorPtr, clearParams.colorUIClearValue, clearParams.depthClearValue, mappedResource.pData);
397             vertexStride = sizeof(d3d11::PositionDepthColorVertex<unsigned int>);
398             shader = &mUintClearShader;
399             break;
400
401           case GL_INT:
402             ApplyVertices(framebufferSize, scissorPtr, clearParams.colorIClearValue, clearParams.depthClearValue, mappedResource.pData);
403             vertexStride = sizeof(d3d11::PositionDepthColorVertex<int>);
404             shader = &mIntClearShader;
405             break;
406
407           default:
408             UNREACHABLE();
409             break;
410         }
411
412         deviceContext->Unmap(mVertexBuffer, 0);
413
414         // Set the viewport to be the same size as the framebuffer
415         D3D11_VIEWPORT viewport;
416         viewport.TopLeftX = 0;
417         viewport.TopLeftY = 0;
418         viewport.Width = framebufferSize.width;
419         viewport.Height = framebufferSize.height;
420         viewport.MinDepth = 0;
421         viewport.MaxDepth = 1;
422         deviceContext->RSSetViewports(1, &viewport);
423
424         // Apply state
425         deviceContext->OMSetBlendState(blendState, blendFactors, sampleMask);
426         deviceContext->OMSetDepthStencilState(dsState, stencilClear);
427         deviceContext->RSSetState(mRasterizerState);
428
429         // Apply shaders
430         deviceContext->IASetInputLayout(shader->inputLayout);
431         deviceContext->VSSetShader(shader->vertexShader, NULL, 0);
432         deviceContext->PSSetShader(shader->pixelShader, NULL, 0);
433         deviceContext->GSSetShader(NULL, NULL, 0);
434
435         // Apply vertex buffer
436         deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &vertexStride, &startIdx);
437         deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
438
439         // Apply render targets
440         deviceContext->OMSetRenderTargets(rtvs.size(), (rtvs.empty() ? NULL : &rtvs[0]), dsv);
441
442         // Draw the clear quad
443         deviceContext->Draw(4, 0);
444
445         // Clean up
446         mRenderer->markAllStateDirty();
447     }
448 }
449
450 ID3D11BlendState *Clear11::getBlendState(const std::vector<MaskedRenderTarget>& rts)
451 {
452     ClearBlendInfo blendKey = { 0 };
453     for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
454     {
455         if (i < rts.size())
456         {
457             RenderTarget11 *rt = rts[i].renderTarget;
458             const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(rt->getInternalFormat());
459
460             blendKey.maskChannels[i][0] = (rts[i].colorMask[0] && formatInfo.redBits   > 0);
461             blendKey.maskChannels[i][1] = (rts[i].colorMask[1] && formatInfo.greenBits > 0);
462             blendKey.maskChannels[i][2] = (rts[i].colorMask[2] && formatInfo.blueBits  > 0);
463             blendKey.maskChannels[i][3] = (rts[i].colorMask[3] && formatInfo.alphaBits > 0);
464         }
465         else
466         {
467             blendKey.maskChannels[i][0] = false;
468             blendKey.maskChannels[i][1] = false;
469             blendKey.maskChannels[i][2] = false;
470             blendKey.maskChannels[i][3] = false;
471         }
472     }
473
474     ClearBlendStateMap::const_iterator i = mClearBlendStates.find(blendKey);
475     if (i != mClearBlendStates.end())
476     {
477         return i->second;
478     }
479     else
480     {
481         D3D11_BLEND_DESC blendDesc = { 0 };
482         blendDesc.AlphaToCoverageEnable = FALSE;
483         blendDesc.IndependentBlendEnable = (rts.size() > 1) ? TRUE : FALSE;
484
485         for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
486         {
487             blendDesc.RenderTarget[i].BlendEnable = FALSE;
488             blendDesc.RenderTarget[i].RenderTargetWriteMask = gl_d3d11::ConvertColorMask(blendKey.maskChannels[i][0],
489                                                                                          blendKey.maskChannels[i][1],
490                                                                                          blendKey.maskChannels[i][2],
491                                                                                          blendKey.maskChannels[i][3]);
492         }
493
494         ID3D11Device *device = mRenderer->getDevice();
495         ID3D11BlendState* blendState = NULL;
496         HRESULT result = device->CreateBlendState(&blendDesc, &blendState);
497         if (FAILED(result) || !blendState)
498         {
499             ERR("Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result);
500             return NULL;
501         }
502
503         mClearBlendStates[blendKey] = blendState;
504
505         return blendState;
506     }
507 }
508
509 ID3D11DepthStencilState *Clear11::getDepthStencilState(const gl::ClearParameters &clearParams)
510 {
511     ClearDepthStencilInfo dsKey = { 0 };
512     dsKey.clearDepth = clearParams.clearDepth;
513     dsKey.clearStencil = clearParams.clearStencil;
514     dsKey.stencilWriteMask = clearParams.stencilWriteMask & 0xFF;
515
516     ClearDepthStencilStateMap::const_iterator i = mClearDepthStencilStates.find(dsKey);
517     if (i != mClearDepthStencilStates.end())
518     {
519         return i->second;
520     }
521     else
522     {
523         D3D11_DEPTH_STENCIL_DESC dsDesc = { 0 };
524         dsDesc.DepthEnable = dsKey.clearDepth ? TRUE : FALSE;
525         dsDesc.DepthWriteMask = dsKey.clearDepth ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
526         dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
527         dsDesc.StencilEnable = dsKey.clearStencil ? TRUE : FALSE;
528         dsDesc.StencilReadMask = 0;
529         dsDesc.StencilWriteMask = dsKey.stencilWriteMask;
530         dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_REPLACE;
531         dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE;
532         dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
533         dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
534         dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_REPLACE;
535         dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_REPLACE;
536         dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_REPLACE;
537         dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
538
539         ID3D11Device *device = mRenderer->getDevice();
540         ID3D11DepthStencilState* dsState = NULL;
541         HRESULT result = device->CreateDepthStencilState(&dsDesc, &dsState);
542         if (FAILED(result) || !dsState)
543         {
544             ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
545             return NULL;
546         }
547
548         mClearDepthStencilStates[dsKey] = dsState;
549
550         return dsState;
551     }
552 }
553
554 }