Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / renderer / d3d / d3d11 / PixelTransfer11.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 // PixelTransfer11.cpp:
9 //   Implementation for buffer-to-texture and texture-to-buffer copies.
10 //   Used to implement pixel transfers from unpack and to pack buffers.
11 //
12
13 #include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h"
14 #include "libGLESv2/formatutils.h"
15 #include "libGLESv2/Texture.h"
16 #include "libGLESv2/Buffer.h"
17 #include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
18 #include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
19 #include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
20 #include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
21 #include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
22 #include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
23 #include "libGLESv2/Context.h"
24
25 // Precompiled shaders
26 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_vs.h"
27 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_gs.h"
28 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4f.h"
29 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4i.h"
30 #include "libGLESv2/renderer/d3d/d3d11/shaders/compiled/buffertotexture11_ps_4ui.h"
31
32 namespace rx
33 {
34
35 PixelTransfer11::PixelTransfer11(Renderer11 *renderer)
36     : mRenderer(renderer),
37       mBufferToTextureVS(NULL),
38       mBufferToTextureGS(NULL),
39       mParamsConstantBuffer(NULL),
40       mCopyRasterizerState(NULL),
41       mCopyDepthStencilState(NULL)
42 {
43     HRESULT result = S_OK;
44     ID3D11Device *device = mRenderer->getDevice();
45
46     D3D11_RASTERIZER_DESC rasterDesc;
47     rasterDesc.FillMode = D3D11_FILL_SOLID;
48     rasterDesc.CullMode = D3D11_CULL_NONE;
49     rasterDesc.FrontCounterClockwise = FALSE;
50     rasterDesc.DepthBias = 0;
51     rasterDesc.SlopeScaledDepthBias = 0.0f;
52     rasterDesc.DepthBiasClamp = 0.0f;
53     rasterDesc.DepthClipEnable = TRUE;
54     rasterDesc.ScissorEnable = FALSE;
55     rasterDesc.MultisampleEnable = FALSE;
56     rasterDesc.AntialiasedLineEnable = FALSE;
57
58     result = device->CreateRasterizerState(&rasterDesc, &mCopyRasterizerState);
59     ASSERT(SUCCEEDED(result));
60
61     D3D11_DEPTH_STENCIL_DESC depthStencilDesc;
62     depthStencilDesc.DepthEnable = true;
63     depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
64     depthStencilDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
65     depthStencilDesc.StencilEnable = FALSE;
66     depthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
67     depthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
68     depthStencilDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
69     depthStencilDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
70     depthStencilDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
71     depthStencilDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
72     depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
73     depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
74     depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
75     depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
76
77     result = device->CreateDepthStencilState(&depthStencilDesc, &mCopyDepthStencilState);
78     ASSERT(SUCCEEDED(result));
79
80     D3D11_BUFFER_DESC constantBufferDesc = { 0 };
81     constantBufferDesc.ByteWidth = rx::roundUp<UINT>(sizeof(CopyShaderParams), 32u);
82     constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
83     constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
84     constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
85     constantBufferDesc.MiscFlags = 0;
86     constantBufferDesc.StructureByteStride = 0;
87
88     result = device->CreateBuffer(&constantBufferDesc, NULL, &mParamsConstantBuffer);
89     ASSERT(SUCCEEDED(result));
90     d3d11::SetDebugName(mParamsConstantBuffer, "PixelTransfer11 constant buffer");
91
92     // init shaders
93     mBufferToTextureVS = d3d11::CompileVS(device, g_VS_BufferToTexture, "BufferToTexture VS");
94     mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS");
95
96     buildShaderMap();
97
98     StructZero(&mParamsData);
99 }
100
101 PixelTransfer11::~PixelTransfer11()
102 {
103     for (auto shaderMapIt = mBufferToTexturePSMap.begin(); shaderMapIt != mBufferToTexturePSMap.end(); shaderMapIt++)
104     {
105         SafeRelease(shaderMapIt->second);
106     }
107
108     mBufferToTexturePSMap.clear();
109
110     SafeRelease(mBufferToTextureVS);
111     SafeRelease(mBufferToTextureGS);
112     SafeRelease(mParamsConstantBuffer);
113     SafeRelease(mCopyRasterizerState);
114     SafeRelease(mCopyDepthStencilState);
115 }
116
117 void PixelTransfer11::setBufferToTextureCopyParams(const gl::Box &destArea, const gl::Extents &destSize, GLenum internalFormat,
118                                                    const gl::PixelUnpackState &unpack, unsigned int offset, CopyShaderParams *parametersOut)
119 {
120     StructZero(parametersOut);
121
122     float texelCenterX = 0.5f / static_cast<float>(destSize.width - 1);
123     float texelCenterY = 0.5f / static_cast<float>(destSize.height - 1);
124
125     unsigned int bytesPerPixel = gl::GetInternalFormatInfo(internalFormat).pixelBytes;
126     unsigned int alignmentBytes = static_cast<unsigned int>(unpack.alignment);
127     unsigned int alignmentPixels = (alignmentBytes <= bytesPerPixel ? 1 : alignmentBytes / bytesPerPixel);
128
129     parametersOut->FirstPixelOffset     = offset;
130     parametersOut->PixelsPerRow         = static_cast<unsigned int>(destArea.width);
131     parametersOut->RowStride            = roundUp(parametersOut->PixelsPerRow, alignmentPixels);
132     parametersOut->RowsPerSlice         = static_cast<unsigned int>(destArea.height);
133     parametersOut->PositionOffset[0]    = texelCenterX + (destArea.x / float(destSize.width)) * 2.0f - 1.0f;
134     parametersOut->PositionOffset[1]    = texelCenterY + ((destSize.height - destArea.y - 1) / float(destSize.height)) * 2.0f - 1.0f;
135     parametersOut->PositionScale[0]     = 2.0f / static_cast<float>(destSize.width);
136     parametersOut->PositionScale[1]     = -2.0f / static_cast<float>(destSize.height);
137 }
138
139 bool PixelTransfer11::copyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTarget *destRenderTarget,
140                                           GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea)
141 {
142     gl::Extents destSize = destRenderTarget->getExtents();
143
144     if (destArea.x   < 0 || destArea.x   + destArea.width    > destSize.width    ||
145         destArea.y   < 0 || destArea.y   + destArea.height   > destSize.height   ||
146         destArea.z   < 0 || destArea.z   + destArea.depth    > destSize.depth    )
147     {
148         return false;
149     }
150
151     const gl::Buffer &sourceBuffer = *unpack.pixelBuffer.get();
152
153     ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat));
154
155     ID3D11PixelShader *pixelShader = findBufferToTexturePS(destinationFormat);
156     ASSERT(pixelShader);
157
158     // The SRV must be in the proper read format, which may be different from the destination format
159     // EG: for half float data, we can load full precision floats with implicit conversion
160     GLenum unsizedFormat = gl::GetInternalFormatInfo(destinationFormat).format;
161     GLenum sourceFormat = gl::GetFormatTypeInfo(unsizedFormat, sourcePixelsType).internalFormat;
162
163     const d3d11::TextureFormat &sourceFormatInfo = d3d11::GetTextureFormatInfo(sourceFormat);
164     DXGI_FORMAT srvFormat = sourceFormatInfo.srvFormat;
165     ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN);
166     Buffer11 *bufferStorage11 = Buffer11::makeBuffer11(sourceBuffer.getImplementation());
167     ID3D11ShaderResourceView *bufferSRV = bufferStorage11->getSRV(srvFormat);
168     ASSERT(bufferSRV != NULL);
169
170     ID3D11RenderTargetView *textureRTV = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
171     ASSERT(textureRTV != NULL);
172
173     CopyShaderParams shaderParams;
174     setBufferToTextureCopyParams(destArea, destSize, sourceFormat, unpack, offset, &shaderParams);
175
176     ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
177
178     ID3D11ShaderResourceView *nullSRV = NULL;
179     ID3D11Buffer *nullBuffer = NULL;
180     UINT zero = 0;
181
182     // Are we doing a 2D or 3D copy?
183     ID3D11GeometryShader *geometryShader = ((destSize.depth > 1) ? mBufferToTextureGS : NULL);
184
185     deviceContext->VSSetShader(mBufferToTextureVS, NULL, 0);
186     deviceContext->GSSetShader(geometryShader, NULL, 0);
187     deviceContext->PSSetShader(pixelShader, NULL, 0);
188     deviceContext->PSSetShaderResources(0, 1, &bufferSRV);
189     deviceContext->IASetInputLayout(NULL);
190     deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
191
192     deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
193     deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF);
194     deviceContext->OMSetDepthStencilState(mCopyDepthStencilState, 0xFFFFFFFF);
195     deviceContext->RSSetState(mCopyRasterizerState);
196
197     mRenderer->setOneTimeRenderTarget(textureRTV);
198
199     if (!StructEquals(mParamsData, shaderParams))
200     {
201         d3d11::SetBufferData(deviceContext, mParamsConstantBuffer, shaderParams);
202         mParamsData = shaderParams;
203     }
204
205     deviceContext->VSSetConstantBuffers(0, 1, &mParamsConstantBuffer);
206
207     // Set the viewport
208     D3D11_VIEWPORT viewport;
209     viewport.TopLeftX = 0;
210     viewport.TopLeftY = 0;
211     viewport.Width = destSize.width;
212     viewport.Height = destSize.height;
213     viewport.MinDepth = 0.0f;
214     viewport.MaxDepth = 1.0f;
215     deviceContext->RSSetViewports(1, &viewport);
216
217     UINT numPixels = (destArea.width * destArea.height * destArea.depth);
218     deviceContext->Draw(numPixels, 0);
219
220     // Unbind textures and render targets and vertex buffer
221     deviceContext->PSSetShaderResources(0, 1, &nullSRV);
222     deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer);
223
224     mRenderer->markAllStateDirty();
225
226     return true;
227 }
228
229 void PixelTransfer11::buildShaderMap()
230 {
231     ID3D11Device *device = mRenderer->getDevice();
232
233     mBufferToTexturePSMap[GL_FLOAT]        = d3d11::CompilePS(device, g_PS_BufferToTexture_4F,  "BufferToTexture RGBA ps");
234     mBufferToTexturePSMap[GL_INT]          = d3d11::CompilePS(device, g_PS_BufferToTexture_4I,  "BufferToTexture RGBA-I ps");
235     mBufferToTexturePSMap[GL_UNSIGNED_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4UI, "BufferToTexture RGBA-UI ps");
236 }
237
238 ID3D11PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const
239 {
240     GLenum componentType = gl::GetInternalFormatInfo(internalFormat).componentType;
241     if (componentType == GL_SIGNED_NORMALIZED || componentType == GL_UNSIGNED_NORMALIZED)
242     {
243         componentType = GL_FLOAT;
244     }
245
246     auto shaderMapIt = mBufferToTexturePSMap.find(componentType);
247     return (shaderMapIt == mBufferToTexturePSMap.end() ? NULL : shaderMapIt->second);
248 }
249
250 }