blob: 1ca456c345eb4c6bd8b33c5df8ef230153f645ad [file] [log] [blame]
Jamie Madill89a0bf52013-09-18 14:36:24 -04001#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
Brandon Jonesc7a41042014-06-23 12:03:25 -070013#include "libGLESv2/renderer/d3d/d3d11/PixelTransfer11.h"
Jamie Madill89a0bf52013-09-18 14:36:24 -040014#include "libGLESv2/formatutils.h"
15#include "libGLESv2/Texture.h"
16#include "libGLESv2/Buffer.h"
Brandon Jonesc7a41042014-06-23 12:03:25 -070017#include "libGLESv2/renderer/d3d/d3d11/Renderer11.h"
18#include "libGLESv2/renderer/d3d/d3d11/renderer11_utils.h"
19#include "libGLESv2/renderer/d3d/d3d11/formatutils11.h"
Brandon Jonesd38f9262014-06-18 16:26:45 -070020#include "libGLESv2/renderer/d3d/d3d11/Buffer11.h"
Brandon Jonesc7a41042014-06-23 12:03:25 -070021#include "libGLESv2/renderer/d3d/d3d11/TextureStorage11.h"
22#include "libGLESv2/renderer/d3d/d3d11/RenderTarget11.h"
Jamie Madill89a0bf52013-09-18 14:36:24 -040023#include "libGLESv2/Context.h"
24
Jamie Madill851a4f62013-10-10 15:15:36 -040025// Precompiled shaders
Brandon Jonesc7a41042014-06-23 12:03:25 -070026#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"
Jamie Madill851a4f62013-10-10 15:15:36 -040031
Jamie Madill89a0bf52013-09-18 14:36:24 -040032namespace rx
33{
34
Jamie Madill89a0bf52013-09-18 14:36:24 -040035PixelTransfer11::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 };
Geoff Lang036aa492013-10-09 16:23:30 -040081 constantBufferDesc.ByteWidth = rx::roundUp<UINT>(sizeof(CopyShaderParams), 32u);
Jamie Madill89a0bf52013-09-18 14:36:24 -040082 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
Jamie Madill851a4f62013-10-10 15:15:36 -040092 // init shaders
93 mBufferToTextureVS = d3d11::CompileVS(device, g_VS_BufferToTexture, "BufferToTexture VS");
Jamie Madill53683052013-10-10 15:30:15 -040094 mBufferToTextureGS = d3d11::CompileGS(device, g_GS_BufferToTexture, "BufferToTexture GS");
Jamie Madill89a0bf52013-09-18 14:36:24 -040095
96 buildShaderMap();
97
98 StructZero(&mParamsData);
99}
100
101PixelTransfer11::~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
117void 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
Geoff Lange4a492b2014-06-19 14:14:41 -0400125 unsigned int bytesPerPixel = gl::GetPixelBytes(internalFormat);
Jamie Madill89a0bf52013-09-18 14:36:24 -0400126 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
139bool 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
Jamie Madill89a0bf52013-09-18 14:36:24 -0400151 const gl::Buffer &sourceBuffer = *unpack.pixelBuffer.get();
152
Jamie Madill0e0510f2013-10-10 15:46:23 -0400153 ASSERT(mRenderer->supportsFastCopyBufferToTexture(destinationFormat));
Jamie Madill89a0bf52013-09-18 14:36:24 -0400154
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
Geoff Lange4a492b2014-06-19 14:14:41 -0400160 GLenum unsizedFormat = gl::GetFormat(destinationFormat);
161 GLenum sourceFormat = gl::GetSizedInternalFormat(unsizedFormat, sourcePixelsType);
Jamie Madill89a0bf52013-09-18 14:36:24 -0400162
Geoff Lange4a492b2014-06-19 14:14:41 -0400163 DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(sourceFormat);
Jamie Madill89a0bf52013-09-18 14:36:24 -0400164 ASSERT(srvFormat != DXGI_FORMAT_UNKNOWN);
Brandon Jonesd38f9262014-06-18 16:26:45 -0700165 Buffer11 *bufferStorage11 = Buffer11::makeBuffer11(sourceBuffer.getImplementation());
Jamie Madill89a0bf52013-09-18 14:36:24 -0400166 ID3D11ShaderResourceView *bufferSRV = bufferStorage11->getSRV(srvFormat);
167 ASSERT(bufferSRV != NULL);
168
169 ID3D11RenderTargetView *textureRTV = RenderTarget11::makeRenderTarget11(destRenderTarget)->getRenderTargetView();
170 ASSERT(textureRTV != NULL);
171
172 CopyShaderParams shaderParams;
173 setBufferToTextureCopyParams(destArea, destSize, sourceFormat, unpack, offset, &shaderParams);
174
175 ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
176
177 ID3D11ShaderResourceView *nullSRV = NULL;
178 ID3D11Buffer *nullBuffer = NULL;
179 UINT zero = 0;
180
181 // Are we doing a 2D or 3D copy?
182 ID3D11GeometryShader *geometryShader = ((destSize.depth > 1) ? mBufferToTextureGS : NULL);
183
184 deviceContext->VSSetShader(mBufferToTextureVS, NULL, 0);
185 deviceContext->GSSetShader(geometryShader, NULL, 0);
186 deviceContext->PSSetShader(pixelShader, NULL, 0);
187 deviceContext->PSSetShaderResources(0, 1, &bufferSRV);
188 deviceContext->IASetInputLayout(NULL);
189 deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST);
190
191 deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
192 deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF);
193 deviceContext->OMSetDepthStencilState(mCopyDepthStencilState, 0xFFFFFFFF);
194 deviceContext->RSSetState(mCopyRasterizerState);
195
196 mRenderer->setOneTimeRenderTarget(textureRTV);
197
198 if (!StructEquals(mParamsData, shaderParams))
199 {
200 d3d11::SetBufferData(deviceContext, mParamsConstantBuffer, shaderParams);
201 mParamsData = shaderParams;
202 }
203
204 deviceContext->VSSetConstantBuffers(0, 1, &mParamsConstantBuffer);
205
206 // Set the viewport
207 D3D11_VIEWPORT viewport;
208 viewport.TopLeftX = 0;
209 viewport.TopLeftY = 0;
210 viewport.Width = destSize.width;
211 viewport.Height = destSize.height;
212 viewport.MinDepth = 0.0f;
213 viewport.MaxDepth = 1.0f;
214 deviceContext->RSSetViewports(1, &viewport);
215
216 UINT numPixels = (destArea.width * destArea.height * destArea.depth);
217 deviceContext->Draw(numPixels, 0);
218
219 // Unbind textures and render targets and vertex buffer
220 deviceContext->PSSetShaderResources(0, 1, &nullSRV);
221 deviceContext->VSSetConstantBuffers(0, 1, &nullBuffer);
222
223 mRenderer->markAllStateDirty();
224
225 return true;
226}
227
Jamie Madill89a0bf52013-09-18 14:36:24 -0400228void PixelTransfer11::buildShaderMap()
229{
Jamie Madill851a4f62013-10-10 15:15:36 -0400230 ID3D11Device *device = mRenderer->getDevice();
231
Jamie Madill24112d62014-01-21 16:39:19 -0500232 mBufferToTexturePSMap[GL_FLOAT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4F, "BufferToTexture RGBA ps");
233 mBufferToTexturePSMap[GL_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4I, "BufferToTexture RGBA-I ps");
234 mBufferToTexturePSMap[GL_UNSIGNED_INT] = d3d11::CompilePS(device, g_PS_BufferToTexture_4UI, "BufferToTexture RGBA-UI ps");
Jamie Madill89a0bf52013-09-18 14:36:24 -0400235}
236
237ID3D11PixelShader *PixelTransfer11::findBufferToTexturePS(GLenum internalFormat) const
238{
Geoff Lange4a492b2014-06-19 14:14:41 -0400239 GLenum componentType = gl::GetComponentType(internalFormat);
Jamie Madill89a0bf52013-09-18 14:36:24 -0400240
Jamie Madill24112d62014-01-21 16:39:19 -0500241 if (componentType == GL_SIGNED_NORMALIZED || componentType == GL_UNSIGNED_NORMALIZED)
242 {
243 componentType = GL_FLOAT;
244 }
Jamie Madill89a0bf52013-09-18 14:36:24 -0400245
Jamie Madill24112d62014-01-21 16:39:19 -0500246 auto shaderMapIt = mBufferToTexturePSMap.find(componentType);
Jamie Madill89a0bf52013-09-18 14:36:24 -0400247 return (shaderMapIt == mBufferToTexturePSMap.end() ? NULL : shaderMapIt->second);
248}
249
250}