Commit b86b979d by Geoff Lang Committed by Shannon Woods

Refactored the Renderer11::copyTexture method into a Blit11 class.

TRAC #23256 Signed-off-by: Jamie Madill Signed-off-by: Shannon Woods Author: Geoff Lang
parent 7b7bc36a
...@@ -271,6 +271,8 @@ ...@@ -271,6 +271,8 @@
'libGLESv2/Renderbuffer.h', 'libGLESv2/Renderbuffer.h',
'libGLESv2/renderer/Blit9.cpp', 'libGLESv2/renderer/Blit9.cpp',
'libGLESv2/renderer/Blit9.h', 'libGLESv2/renderer/Blit9.h',
'libGLESv2/renderer/Blit11.cpp',
'libGLESv2/renderer/Blit11.h',
'libGLESv2/renderer/copyimage.cpp', 'libGLESv2/renderer/copyimage.cpp',
'libGLESv2/renderer/copyimage.h', 'libGLESv2/renderer/copyimage.h',
'libGLESv2/renderer/BufferStorage.h', 'libGLESv2/renderer/BufferStorage.h',
......
...@@ -267,6 +267,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\" ...@@ -267,6 +267,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\"
<ClCompile Include="Query.cpp" /> <ClCompile Include="Query.cpp" />
<ClCompile Include="..\common\RefCountObject.cpp" /> <ClCompile Include="..\common\RefCountObject.cpp" />
<ClCompile Include="Renderbuffer.cpp" /> <ClCompile Include="Renderbuffer.cpp" />
<ClCompile Include="renderer\Blit11.cpp" />
<ClCompile Include="renderer\Blit9.cpp" /> <ClCompile Include="renderer\Blit9.cpp" />
<ClCompile Include="renderer\copyimage.cpp" /> <ClCompile Include="renderer\copyimage.cpp" />
<ClCompile Include="renderer\Fence11.cpp" /> <ClCompile Include="renderer\Fence11.cpp" />
...@@ -342,6 +343,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\" ...@@ -342,6 +343,7 @@ copy "$(OutDir)libGLESv2.lib" "$(ProjectDir)..\..\lib\$(Configuration)\"
<ClInclude Include="Query.h" /> <ClInclude Include="Query.h" />
<ClInclude Include="..\common\RefCountObject.h" /> <ClInclude Include="..\common\RefCountObject.h" />
<ClInclude Include="Renderbuffer.h" /> <ClInclude Include="Renderbuffer.h" />
<ClInclude Include="renderer\Blit11.h" />
<ClInclude Include="renderer\Blit9.h" /> <ClInclude Include="renderer\Blit9.h" />
<ClInclude Include="renderer\copyimage.h" /> <ClInclude Include="renderer\copyimage.h" />
<ClInclude Include="renderer\Fence11.h" /> <ClInclude Include="renderer\Fence11.h" />
......
...@@ -236,6 +236,9 @@ ...@@ -236,6 +236,9 @@
<ClCompile Include="renderer\Blit9.cpp"> <ClCompile Include="renderer\Blit9.cpp">
<Filter>Source Files\Renderer9</Filter> <Filter>Source Files\Renderer9</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="renderer\Blit11.cpp">
<Filter>Source Files\Renderer11</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="BinaryStream.h"> <ClInclude Include="BinaryStream.h">
...@@ -550,6 +553,9 @@ ...@@ -550,6 +553,9 @@
<ClInclude Include="renderer\Blit9.h"> <ClInclude Include="renderer\Blit9.h">
<Filter>Header Files\Renderer9</Filter> <Filter>Header Files\Renderer9</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="renderer\Blit11.h">
<Filter>Header Files\Renderer11</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="renderer\shaders\Blit.ps"> <None Include="renderer\shaders\Blit.ps">
......
#include "precompiled.h"
//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Blit11.cpp: Texture copy utility class.
#include "libGLESv2/main.h"
#include "libGLESv2/formatutils.h"
#include "libGLESv2/renderer/Blit11.h"
#include "libGLESv2/renderer/Renderer11.h"
#include "libGLESv2/renderer/renderer11_utils.h"
#include "libGLESv2/renderer/shaders/compiled/passthrough2d11vs.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughrgba2d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughrgb2d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughlum2d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughlumalpha2d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/passthrough3d11vs.h"
#include "libGLESv2/renderer/shaders/compiled/passthrough3d11gs.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughrgba3d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughrgb3d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughlum3d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughlumalpha3d11ps.h"
namespace rx
{
Blit11::Blit11(rx::Renderer11 *renderer)
: mRenderer(renderer), mShaderMap(compareBlitParameters), mVertexBuffer(NULL),
mPointSampler(NULL), mLinearSampler(NULL), mQuad2DIL(NULL), mQuad2DVS(NULL),
mQuad3DIL(NULL), mQuad3DVS(NULL), mQuad3DGS(NULL)
{
HRESULT result;
ID3D11Device *device = mRenderer->getDevice();
D3D11_BUFFER_DESC vbDesc;
vbDesc.ByteWidth = std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex) * 6 * renderer->getMaxTextureDepth(),
sizeof(d3d11::PositionTexCoordVertex) * 4);
vbDesc.Usage = D3D11_USAGE_DYNAMIC;
vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
vbDesc.MiscFlags = 0;
vbDesc.StructureByteStride = 0;
result = device->CreateBuffer(&vbDesc, NULL, &mVertexBuffer);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mVertexBuffer, "Blit11 vertex buffer");
D3D11_SAMPLER_DESC pointSamplerDesc;
pointSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
pointSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
pointSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
pointSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
pointSamplerDesc.MipLODBias = 0.0f;
pointSamplerDesc.MaxAnisotropy = 0;
pointSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
pointSamplerDesc.BorderColor[0] = 0.0f;
pointSamplerDesc.BorderColor[1] = 0.0f;
pointSamplerDesc.BorderColor[2] = 0.0f;
pointSamplerDesc.BorderColor[3] = 0.0f;
pointSamplerDesc.MinLOD = 0.0f;
pointSamplerDesc.MaxLOD = 0.0f;
result = device->CreateSamplerState(&pointSamplerDesc, &mPointSampler);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mPointSampler, "Blit11 point sampler");
D3D11_SAMPLER_DESC linearSamplerDesc;
linearSamplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
linearSamplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
linearSamplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
linearSamplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
linearSamplerDesc.MipLODBias = 0.0f;
linearSamplerDesc.MaxAnisotropy = 0;
linearSamplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
linearSamplerDesc.BorderColor[0] = 0.0f;
linearSamplerDesc.BorderColor[1] = 0.0f;
linearSamplerDesc.BorderColor[2] = 0.0f;
linearSamplerDesc.BorderColor[3] = 0.0f;
linearSamplerDesc.MinLOD = 0.0f;
linearSamplerDesc.MaxLOD = 0.0f;
result = device->CreateSamplerState(&linearSamplerDesc, &mLinearSampler);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mLinearSampler, "Blit11 linear sampler");
D3D11_INPUT_ELEMENT_DESC quad2DLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
result = device->CreateInputLayout(quad2DLayout, ArraySize(quad2DLayout), g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), &mQuad2DIL);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mQuad2DIL, "Blit11 2D input layout");
result = device->CreateVertexShader(g_VS_Passthrough2D, ArraySize(g_VS_Passthrough2D), NULL, &mQuad2DVS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mQuad2DVS, "Blit11 2D vertex shader");
D3D11_INPUT_ELEMENT_DESC quad3DLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "LAYER", 0, DXGI_FORMAT_R32_UINT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
result = device->CreateInputLayout(quad3DLayout, ArraySize(quad3DLayout), g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), &mQuad3DIL);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mQuad3DIL, "Blit11 3D input layout");
result = device->CreateVertexShader(g_VS_Passthrough3D, ArraySize(g_VS_Passthrough3D), NULL, &mQuad3DVS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mQuad3DVS, "Blit11 3D vertex shader");
result = device->CreateGeometryShader(g_GS_Passthrough3D, ArraySize(g_GS_Passthrough3D), NULL, &mQuad3DGS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mQuad3DGS, "Renderer11 copy 3D texture geometry shader");
buildShaderMap();
}
Blit11::~Blit11()
{
SafeRelease(mVertexBuffer);
SafeRelease(mPointSampler);
SafeRelease(mLinearSampler);
SafeRelease(mQuad2DIL);
SafeRelease(mQuad2DVS);
SafeRelease(mQuad3DIL);
SafeRelease(mQuad3DVS);
SafeRelease(mQuad3DGS);
clearShaderMap();
}
bool Blit11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize,
GLenum destFormat, GLenum filter)
{
if(sourceArea.x < 0 || sourceArea.x + sourceArea.width > sourceSize.width ||
sourceArea.y < 0 || sourceArea.y + sourceArea.height > sourceSize.height ||
sourceArea.z < 0 || sourceArea.z + sourceArea.depth > sourceSize.depth ||
destArea.x < 0 || destArea.x + destArea.width > destSize.width ||
destArea.y < 0 || destArea.y + destArea.height > destSize.height ||
destArea.z < 0 || destArea.z + destArea.depth > destSize.depth )
{
return false;
}
HRESULT result;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
BlitParameters parameters = { 0 };
parameters.mDestinationFormat = destFormat;
parameters.mSignedInteger = false;
parameters.m3DBlit = sourceArea.depth > 1;
BlitShaderMap::const_iterator i = mShaderMap.find(parameters);
if (i == mShaderMap.end())
{
UNREACHABLE();
return false;
}
const BlitShader& shader = i->second;
// Set vertices
D3D11_MAPPED_SUBRESOURCE mappedResource;
result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result);
return false;
}
UINT stride = 0;
UINT startIdx = 0;
UINT drawCount = 0;
D3D11_PRIMITIVE_TOPOLOGY topology;
shader.mVertexWriteFunction(sourceArea, sourceSize, destArea, destSize, mappedResource.pData,
&stride, &drawCount, &topology);
deviceContext->Unmap(mVertexBuffer, 0);
// Apply vertex buffer
deviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &startIdx);
// Apply state
deviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF);
deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF);
deviceContext->RSSetState(NULL);
// Apply shaders
deviceContext->IASetInputLayout(shader.mInputLayout);
deviceContext->IASetPrimitiveTopology(topology);
deviceContext->VSSetShader(shader.mVertexShader, NULL, 0);
deviceContext->PSSetShader(shader.mPixelShader, NULL, 0);
deviceContext->GSSetShader(shader.mGeometryShader, NULL, 0);
// Unset the currently bound shader resource to avoid conflicts
ID3D11ShaderResourceView *const nullSRV = NULL;
deviceContext->PSSetShaderResources(0, 1, &nullSRV);
// Apply render target
mRenderer->setOneTimeRenderTarget(dest);
// Set the viewport
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = destSize.width;
viewport.Height = destSize.height;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
deviceContext->RSSetViewports(1, &viewport);
// Apply textures
deviceContext->PSSetShaderResources(0, 1, &source);
// Apply samplers
ID3D11SamplerState *sampler = NULL;
switch (filter)
{
case GL_NEAREST: sampler = mPointSampler; break;
case GL_LINEAR: sampler = mLinearSampler; break;
default: UNREACHABLE(); return false;
}
deviceContext->PSSetSamplers(0, 1, &sampler);
// Draw the quad
deviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer
deviceContext->PSSetShaderResources(0, 1, &nullSRV);
mRenderer->unapplyRenderTargets();
UINT zero = 0;
ID3D11Buffer *const nullBuffer = NULL;
deviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
mRenderer->markAllStateDirty();
return true;
}
bool Blit11::compareBlitParameters(const Blit11::BlitParameters &a, const Blit11::BlitParameters &b)
{
return memcmp(&a, &b, sizeof(Blit11::BlitParameters)) < 0;
}
template <unsigned int N>
static ID3D11PixelShader *compilePS(ID3D11Device *device, const BYTE (&byteCode)[N], const char *name)
{
ID3D11PixelShader *ps = NULL;
HRESULT result = device->CreatePixelShader(byteCode, N, NULL, &ps);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(ps, name);
return ps;
}
inline static void generateVertexCoords(const gl::Box &sourceArea, const gl::Extents &sourceSize,
const gl::Box &destArea, const gl::Extents &destSize,
float *x1, float *y1, float *x2, float *y2,
float *u1, float *v1, float *u2, float *v2)
{
*x1 = (destArea.x / float(destSize.width)) * 2.0f - 1.0f;
*y1 = ((destSize.height - destArea.y - destArea.height) / float(destSize.height)) * 2.0f - 1.0f;
*x2 = ((destArea.x + destArea.width) / float(destSize.width)) * 2.0f - 1.0f;
*y2 = ((destSize.height - destArea.y) / float(destSize.height)) * 2.0f - 1.0f;
*u1 = sourceArea.x / float(sourceSize.width);
*v1 = sourceArea.y / float(sourceSize.height);
*u2 = (sourceArea.x + sourceArea.width) / float(sourceSize.width);
*v2 = (sourceArea.y + sourceArea.height) / float(sourceSize.height);
}
static void write2DVertices(const gl::Box &sourceArea, const gl::Extents &sourceSize,
const gl::Box &destArea, const gl::Extents &destSize,
void *outVertices, unsigned int *outStride, unsigned int *outVertexCount,
D3D11_PRIMITIVE_TOPOLOGY *outTopology)
{
float x1, y1, x2, y2, u1, v1, u2, v2;
generateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1, &u2, &v2);
d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(outVertices);
d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2);
d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1);
d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2);
d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1);
*outStride = sizeof(d3d11::PositionTexCoordVertex);
*outVertexCount = 4;
*outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
}
static void write3DVertices(const gl::Box &sourceArea, const gl::Extents &sourceSize,
const gl::Box &destArea, const gl::Extents &destSize,
void *outVertices, unsigned int *outStride, unsigned int *outVertexCount,
D3D11_PRIMITIVE_TOPOLOGY *outTopology)
{
float x1, y1, x2, y2, u1, v1, u2, v2;
generateVertexCoords(sourceArea, sourceSize, destArea, destSize, &x1, &y1, &x2, &y2, &u1, &v1, &u2, &v2);
d3d11::PositionLayerTexCoord3DVertex *vertices = static_cast<d3d11::PositionLayerTexCoord3DVertex*>(outVertices);
for (int i = 0; i < destSize.depth; i++)
{
float readDepth = ((i * 2) + 0.5f) / (sourceSize.depth - 1);
d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 0], x1, y1, i, u1, v2, readDepth);
d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 1], x1, y2, i, u1, v1, readDepth);
d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 2], x2, y1, i, u2, v2, readDepth);
d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 3], x1, y2, i, u1, v1, readDepth);
d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 4], x2, y2, i, u2, v1, readDepth);
d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 5], x2, y1, i, u2, v2, readDepth);
}
*outStride = sizeof(d3d11::PositionLayerTexCoord3DVertex);
*outVertexCount = destSize.depth * 6;
*outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
}
void Blit11::add2DShaderToMap(GLenum destFormat, bool signedInteger, ID3D11PixelShader *ps)
{
BlitParameters params = { 0 };
params.mDestinationFormat = destFormat;
params.mSignedInteger = signedInteger;
params.m3DBlit = false;
ASSERT(mShaderMap.find(params) == mShaderMap.end());
ASSERT(ps);
BlitShader shader;
shader.mVertexWriteFunction = write2DVertices;
shader.mInputLayout = mQuad2DIL;
shader.mVertexShader = mQuad2DVS;
shader.mGeometryShader = NULL;
shader.mPixelShader = ps;
mShaderMap[params] = shader;
}
void Blit11::add3DShaderToMap(GLenum destFormat, bool signedInteger, ID3D11PixelShader *ps)
{
BlitParameters params = { 0 };
params.mDestinationFormat = destFormat;
params.mSignedInteger = signedInteger;
params.m3DBlit = true;
ASSERT(mShaderMap.find(params) == mShaderMap.end());
ASSERT(ps);
BlitShader shader;
shader.mVertexWriteFunction = write3DVertices;
shader.mInputLayout = mQuad3DIL;
shader.mVertexShader = mQuad3DVS;
shader.mGeometryShader = mQuad3DGS;
shader.mPixelShader = ps;
mShaderMap[params] = shader;
}
void Blit11::buildShaderMap()
{
ID3D11Device *device = mRenderer->getDevice();
add2DShaderToMap(GL_RGBA, false, compilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D RGBA pixel shader" ));
add2DShaderToMap(GL_BGRA_EXT, false, compilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D BGRA pixel shader" ));
add2DShaderToMap(GL_RGB, false, compilePS(device, g_PS_PassthroughRGB2D, "Blit11 2D RGB pixel shader" ));
add2DShaderToMap(GL_ALPHA, false, compilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D alpha pixel shader" ));
add2DShaderToMap(GL_LUMINANCE, false, compilePS(device, g_PS_PassthroughLum2D, "Blit11 2D lum pixel shader" ));
add2DShaderToMap(GL_LUMINANCE_ALPHA, false, compilePS(device, g_PS_PassthroughLumAlpha2D, "Blit11 2D luminance alpha pixel shader"));
add3DShaderToMap(GL_RGBA, false, compilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D RGBA pixel shader" ));
add3DShaderToMap(GL_BGRA_EXT, false, compilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader" ));
add3DShaderToMap(GL_RGB, false, compilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader" ));
add3DShaderToMap(GL_ALPHA, false, compilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader" ));
add3DShaderToMap(GL_LUMINANCE, false, compilePS(device, g_PS_PassthroughLum3D, "Blit11 3D luminance pixel shader" ));
add3DShaderToMap(GL_LUMINANCE_ALPHA, false, compilePS(device, g_PS_PassthroughLumAlpha3D, "Blit11 3D luminance alpha pixel shader"));
}
void Blit11::clearShaderMap()
{
for (BlitShaderMap::iterator i = mShaderMap.begin(); i != mShaderMap.end(); ++i)
{
BlitShader &shader = i->second;
SafeRelease(shader.mPixelShader);
}
mShaderMap.clear();
}
}
//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Blit11.cpp: Texture copy utility class.
#ifndef LIBGLESV2_BLIT11_H_
#define LIBGLESV2_BLIT11_H_
#include "common/angleutils.h"
#include "libGLESv2/angletypes.h"
namespace rx
{
class Renderer11;
enum Filter
{
Point,
Linear,
};
class Blit11
{
public:
explicit Blit11(Renderer11 *renderer);
~Blit11();
bool copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize,
ID3D11RenderTargetView *dest, const gl::Box &destArea, const gl::Extents &destSize,
GLenum destFormat, GLenum filter);
private:
rx::Renderer11 *mRenderer;
struct BlitParameters
{
GLenum mDestinationFormat;
bool mSignedInteger;
bool m3DBlit;
};
static bool compareBlitParameters(const BlitParameters &a, const BlitParameters &b);
typedef void (*WriteVertexFunction)(const gl::Box &sourceArea, const gl::Extents &sourceSize,
const gl::Box &destArea, const gl::Extents &destSize,
void *outVertices, unsigned int *outStride, unsigned int *outVertexCount,
D3D11_PRIMITIVE_TOPOLOGY *outTopology);
struct BlitShader
{
WriteVertexFunction mVertexWriteFunction;
ID3D11InputLayout *mInputLayout;
ID3D11VertexShader *mVertexShader;
ID3D11GeometryShader *mGeometryShader;
ID3D11PixelShader *mPixelShader;
};
typedef bool (*BlitParametersComparisonFunction)(const BlitParameters&, const BlitParameters &);
typedef std::map<BlitParameters, BlitShader, BlitParametersComparisonFunction> BlitShaderMap;
BlitShaderMap mShaderMap;
void add2DShaderToMap(GLenum destFormat, bool signedInteger, ID3D11PixelShader *ps);
void add3DShaderToMap(GLenum destFormat, bool signedInteger, ID3D11PixelShader *ps);
void buildShaderMap();
void clearShaderMap();
ID3D11Buffer *mVertexBuffer;
ID3D11SamplerState *mPointSampler;
ID3D11SamplerState *mLinearSampler;
ID3D11InputLayout *mQuad2DIL;
ID3D11VertexShader *mQuad2DVS;
ID3D11InputLayout *mQuad3DIL;
ID3D11VertexShader *mQuad3DVS;
ID3D11GeometryShader *mQuad3DGS;
DISALLOW_COPY_AND_ASSIGN(Blit11);
};
}
#endif // LIBGLESV2_BLIT11_H_
...@@ -28,19 +28,7 @@ ...@@ -28,19 +28,7 @@
#include "libGLESv2/renderer/TextureStorage11.h" #include "libGLESv2/renderer/TextureStorage11.h"
#include "libGLESv2/renderer/Query11.h" #include "libGLESv2/renderer/Query11.h"
#include "libGLESv2/renderer/Fence11.h" #include "libGLESv2/renderer/Fence11.h"
#include "libGLESv2/renderer/Blit11.h"
#include "libGLESv2/renderer/shaders/compiled/passthrough2d11vs.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughrgba2d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughrgb2d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughlum2d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughlumalpha2d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/passthrough3d11vs.h"
#include "libGLESv2/renderer/shaders/compiled/passthrough3d11gs.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughrgba3d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughrgb3d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughlum3d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/passthroughlumalpha3d11ps.h"
#include "libGLESv2/renderer/shaders/compiled/clear11vs.h" #include "libGLESv2/renderer/shaders/compiled/clear11vs.h"
#include "libGLESv2/renderer/shaders/compiled/clearsingle11ps.h" #include "libGLESv2/renderer/shaders/compiled/clearsingle11ps.h"
...@@ -82,22 +70,7 @@ Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc( ...@@ -82,22 +70,7 @@ Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(
mLineLoopIB = NULL; mLineLoopIB = NULL;
mTriangleFanIB = NULL; mTriangleFanIB = NULL;
mCopyResourcesInitialized = false; mBlit = NULL;
mCopyVB = NULL;
mCopySampler = NULL;
mCopy2DIL = NULL;
mCopy2DVS = NULL;
mCopyRGBA2DPS = NULL;
mCopyRGB2DPS = NULL;
mCopyLum2DPS = NULL;
mCopyLumAlpha2DPS = NULL;
mCopy3DIL = NULL;
mCopy3DVS = NULL;
mCopy3DGS = NULL;
mCopyRGBA3DPS = NULL;
mCopyRGB3DPS = NULL;
mCopyLum3DPS = NULL;
mCopyLumAlpha3DPS = NULL;
mClearResourcesInitialized = false; mClearResourcesInitialized = false;
mClearVB = NULL; mClearVB = NULL;
...@@ -424,6 +397,9 @@ void Renderer11::initializeDevice() ...@@ -424,6 +397,9 @@ void Renderer11::initializeDevice()
mVertexDataManager = new VertexDataManager(this); mVertexDataManager = new VertexDataManager(this);
mIndexDataManager = new IndexDataManager(this); mIndexDataManager = new IndexDataManager(this);
ASSERT(!mBlit);
mBlit = new Blit11(this);
markAllStateDirty(); markAllStateDirty();
} }
...@@ -1844,23 +1820,8 @@ void Renderer11::releaseDeviceResources() ...@@ -1844,23 +1820,8 @@ void Renderer11::releaseDeviceResources()
delete mTriangleFanIB; delete mTriangleFanIB;
mTriangleFanIB = NULL; mTriangleFanIB = NULL;
SafeRelease(mCopyVB); delete mBlit;
SafeRelease(mCopySampler); mBlit = NULL;
SafeRelease(mCopy2DIL);
SafeRelease(mCopy2DVS);
SafeRelease(mCopyRGBA2DPS);
SafeRelease(mCopyRGB2DPS);
SafeRelease(mCopyLum2DPS);
SafeRelease(mCopyLumAlpha2DPS);
SafeRelease(mCopy3DIL);
SafeRelease(mCopy3DVS);
SafeRelease(mCopy3DGS);
SafeRelease(mCopyRGBA3DPS);
SafeRelease(mCopyRGB3DPS);
SafeRelease(mCopyLum3DPS);
SafeRelease(mCopyLumAlpha3DPS);
mCopyResourcesInitialized = false;
SafeRelease(mClearVB); SafeRelease(mClearVB);
SafeRelease(mClearIL); SafeRelease(mClearIL);
...@@ -2639,24 +2600,16 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so ...@@ -2639,24 +2600,16 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so
return gl::error(GL_OUT_OF_MEMORY, false); return gl::error(GL_OUT_OF_MEMORY, false);
} }
gl::Box sourceArea; gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
sourceArea.x = sourceRect.x; gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
sourceArea.y = sourceRect.y;
sourceArea.z = 0;
sourceArea.width = sourceRect.width;
sourceArea.height = sourceRect.height;
sourceArea.depth = 1;
gl::Box destArea; gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
destArea.x = xoffset; gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
destArea.y = yoffset;
destArea.z = 0;
destArea.width = sourceRect.width;
destArea.height = sourceRect.height;
destArea.depth = 1;
bool ret = copyTexture(source, sourceArea, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1, // Use nearest filtering because source and destination are the same size for the direct
dest, destArea, destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1, destFormat); // copy
bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize,
destFormat, GL_NEAREST);
source->Release(); source->Release();
dest->Release(); dest->Release();
...@@ -2712,24 +2665,16 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so ...@@ -2712,24 +2665,16 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so
return gl::error(GL_OUT_OF_MEMORY, false); return gl::error(GL_OUT_OF_MEMORY, false);
} }
gl::Box sourceArea; gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
sourceArea.x = sourceRect.x; gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
sourceArea.y = sourceRect.y;
sourceArea.z = 0;
sourceArea.width = sourceRect.width;
sourceArea.height = sourceRect.height;
sourceArea.depth = 1;
gl::Box destArea; gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
destArea.x = xoffset; gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
destArea.y = yoffset;
destArea.z = 0;
destArea.width = sourceRect.width;
destArea.height = sourceRect.height;
destArea.depth = 1;
bool ret = copyTexture(source, sourceArea, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1, // Use nearest filtering because source and destination are the same size for the direct
dest, destArea, destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1, destFormat); // copy
bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize,
destFormat, GL_NEAREST);
source->Release(); source->Release();
dest->Release(); dest->Release();
...@@ -2785,24 +2730,16 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so ...@@ -2785,24 +2730,16 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so
return gl::error(GL_OUT_OF_MEMORY, false); return gl::error(GL_OUT_OF_MEMORY, false);
} }
gl::Box sourceArea; gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
sourceArea.x = sourceRect.x; gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
sourceArea.y = sourceRect.y;
sourceArea.z = 0;
sourceArea.width = sourceRect.width;
sourceArea.height = sourceRect.height;
sourceArea.depth = 1;
gl::Box destArea; gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
destArea.x = xoffset; gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
destArea.y = yoffset;
destArea.z = 0;
destArea.width = sourceRect.width;
destArea.height = sourceRect.height;
destArea.depth = 1;
bool ret = copyTexture(source, sourceArea, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1, // Use nearest filtering because source and destination are the same size for the direct
dest, destArea, destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1, destFormat); // copy
bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize,
destFormat, GL_NEAREST);
source->Release(); source->Release();
dest->Release(); dest->Release();
...@@ -2858,24 +2795,16 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so ...@@ -2858,24 +2795,16 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so
return gl::error(GL_OUT_OF_MEMORY, false); return gl::error(GL_OUT_OF_MEMORY, false);
} }
gl::Box sourceArea; gl::Box sourceArea(sourceRect.x, sourceRect.y, 0, sourceRect.width, sourceRect.height, 1);
sourceArea.x = sourceRect.x; gl::Extents sourceSize(sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1);
sourceArea.y = sourceRect.y;
sourceArea.z = 0;
sourceArea.width = sourceRect.width;
sourceArea.height = sourceRect.height;
sourceArea.depth = 1;
gl::Box destArea; gl::Box destArea(xoffset, yoffset, 0, sourceRect.width, sourceRect.height, 1);
destArea.x = xoffset; gl::Extents destSize(destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1);
destArea.y = yoffset;
destArea.z = 0;
destArea.width = sourceRect.width;
destArea.height = sourceRect.height;
destArea.depth = 1;
bool ret = copyTexture(source, sourceArea, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), 1, // Use nearest filtering because source and destination are the same size for the direct
dest, destArea, destRenderTarget->getWidth(), destRenderTarget->getHeight(), 1, destFormat); // copy
bool ret = mBlit->copyTexture(source, sourceArea, sourceSize, dest, destArea, destSize,
destFormat, GL_NEAREST);
source->Release(); source->Release();
dest->Release(); dest->Release();
...@@ -2883,287 +2812,6 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so ...@@ -2883,287 +2812,6 @@ bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &so
return ret; return ret;
} }
bool Renderer11::copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
ID3D11RenderTargetView *dest, const gl::Box &destArea, unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
GLenum destFormat)
{
HRESULT result;
if (!mCopyResourcesInitialized)
{
ASSERT(!mCopyVB && !mCopySampler && !mCopy2DIL && !mCopy2DVS && !mCopyRGBA2DPS && !mCopyRGB2DPS && !mCopyLum2DPS && !mCopyLumAlpha2DPS &&
!mCopy3DIL && !mCopy3DVS && !mCopy3DGS && !mCopyRGBA3DPS && !mCopyRGB3DPS && !mCopyLum3DPS && !mCopyLumAlpha3DPS);
D3D11_BUFFER_DESC vbDesc;
vbDesc.ByteWidth = std::max(sizeof(d3d11::PositionLayerTexCoord3DVertex) * 6 * getMaxTextureDepth(),
sizeof(d3d11::PositionTexCoordVertex) * 4);
vbDesc.Usage = D3D11_USAGE_DYNAMIC;
vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
vbDesc.MiscFlags = 0;
vbDesc.StructureByteStride = 0;
result = mDevice->CreateBuffer(&vbDesc, NULL, &mCopyVB);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopyVB, "Renderer11 copy texture vertex buffer");
D3D11_SAMPLER_DESC samplerDesc;
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
samplerDesc.MipLODBias = 0.0f;
samplerDesc.MaxAnisotropy = 0;
samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
samplerDesc.BorderColor[0] = 0.0f;
samplerDesc.BorderColor[1] = 0.0f;
samplerDesc.BorderColor[2] = 0.0f;
samplerDesc.BorderColor[3] = 0.0f;
samplerDesc.MinLOD = 0.0f;
samplerDesc.MaxLOD = 0.0f;
result = mDevice->CreateSamplerState(&samplerDesc, &mCopySampler);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopySampler, "Renderer11 copy sampler");
// Create 2D copy resources
D3D11_INPUT_ELEMENT_DESC quad2DLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
result = mDevice->CreateInputLayout(quad2DLayout, ArraySize(quad2DLayout), g_VS_Passthrough2D, sizeof(g_VS_Passthrough2D), &mCopy2DIL);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopy2DIL, "Renderer11 copy 2D texture input layout");
result = mDevice->CreateVertexShader(g_VS_Passthrough2D, sizeof(g_VS_Passthrough2D), NULL, &mCopy2DVS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopy2DVS, "Renderer11 copy 2D texture vertex shader");
result = mDevice->CreatePixelShader(g_PS_PassthroughRGBA2D, sizeof(g_PS_PassthroughRGBA2D), NULL, &mCopyRGBA2DPS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopyRGBA2DPS, "Renderer11 copy 2D texture RGBA pixel shader");
result = mDevice->CreatePixelShader(g_PS_PassthroughRGB2D, sizeof(g_PS_PassthroughRGB2D), NULL, &mCopyRGB2DPS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopyRGB2DPS, "Renderer11 copy 2D texture RGB pixel shader");
result = mDevice->CreatePixelShader(g_PS_PassthroughLum2D, sizeof(g_PS_PassthroughLum2D), NULL, &mCopyLum2DPS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopyLum2DPS, "Renderer11 copy 2D texture luminance pixel shader");
result = mDevice->CreatePixelShader(g_PS_PassthroughLumAlpha2D, sizeof(g_PS_PassthroughLumAlpha2D), NULL, &mCopyLumAlpha2DPS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopyLumAlpha2DPS, "Renderer11 2D copy texture luminance alpha pixel shader");
// Create 3D copy resources
D3D11_INPUT_ELEMENT_DESC quad3DLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "LAYER", 0, DXGI_FORMAT_R32_UINT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
result = mDevice->CreateInputLayout(quad3DLayout, ArraySize(quad3DLayout), g_VS_Passthrough3D, sizeof(g_VS_Passthrough3D), &mCopy3DIL);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopy3DIL, "Renderer11 copy 3D texture input layout");
result = mDevice->CreateVertexShader(g_VS_Passthrough3D, sizeof(g_VS_Passthrough3D), NULL, &mCopy3DVS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopy3DVS, "Renderer11 copy 3D texture vertex shader");
result = mDevice->CreateGeometryShader(g_GS_Passthrough3D, sizeof(g_GS_Passthrough3D), NULL, &mCopy3DGS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopy3DGS, "Renderer11 copy 3D texture geometry shader");
result = mDevice->CreatePixelShader(g_PS_PassthroughRGBA3D, sizeof(g_PS_PassthroughRGBA3D), NULL, &mCopyRGBA3DPS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopyRGBA3DPS, "Renderer11 copy 3D texture RGBA pixel shader");
result = mDevice->CreatePixelShader(g_PS_PassthroughRGB3D, sizeof(g_PS_PassthroughRGB3D), NULL, &mCopyRGB3DPS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopyRGB3DPS, "Renderer11 copy 3D texture RGB pixel shader");
result = mDevice->CreatePixelShader(g_PS_PassthroughLum3D, sizeof(g_PS_PassthroughLum3D), NULL, &mCopyLum3DPS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopyLum3DPS, "Renderer11 copy 3D texture luminance pixel shader");
result = mDevice->CreatePixelShader(g_PS_PassthroughLumAlpha3D, sizeof(g_PS_PassthroughLumAlpha3D), NULL, &mCopyLumAlpha3DPS);
ASSERT(SUCCEEDED(result));
d3d11::SetDebugName(mCopyLumAlpha3DPS, "Renderer11 3D copy texture luminance alpha pixel shader");
mCopyResourcesInitialized = true;
}
// Verify the source and destination area sizes
if (sourceArea.x < 0 || sourceArea.x + sourceArea.width > static_cast<int>(sourceWidth) ||
sourceArea.y < 0 || sourceArea.y + sourceArea.height > static_cast<int>(sourceHeight) ||
sourceArea.z < 0 || sourceArea.z + sourceArea.depth > static_cast<int>(sourceDepth) ||
destArea.x < 0 || destArea.x + destArea.width > static_cast<int>(destWidth) ||
destArea.y < 0 || destArea.y + destArea.height > static_cast<int>(destHeight) ||
destArea.z < 0 || destArea.z + destArea.depth > static_cast<int>(destDepth))
{
return gl::error(GL_INVALID_VALUE, false);
}
bool use3DCopy = sourceArea.depth > 1;
// Set vertices
D3D11_MAPPED_SUBRESOURCE mappedResource;
result = mDeviceContext->Map(mCopyVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result))
{
ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result);
return gl::error(GL_OUT_OF_MEMORY, false);
}
// Create a quad in homogeneous coordinates
float x1 = (destArea.x / float(destWidth)) * 2.0f - 1.0f;
float y1 = ((destHeight - destArea.y - destArea.height) / float(destHeight)) * 2.0f - 1.0f;
float x2 = ((destArea.x + destArea.width) / float(destWidth)) * 2.0f - 1.0f;
float y2 = ((destHeight - destArea.y) / float(destHeight)) * 2.0f - 1.0f;
float u1 = sourceArea.x / float(sourceWidth);
float v1 = sourceArea.y / float(sourceHeight);
float u2 = (sourceArea.x + sourceArea.width) / float(sourceWidth);
float v2 = (sourceArea.y + sourceArea.height) / float(sourceHeight);
UINT stride = 0;
UINT startIdx = 0;
UINT drawCount = 0;
D3D11_PRIMITIVE_TOPOLOGY topology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
if (use3DCopy)
{
d3d11::PositionLayerTexCoord3DVertex *vertices = static_cast<d3d11::PositionLayerTexCoord3DVertex*>(mappedResource.pData);
for (unsigned int i = 0; i < destDepth; i++)
{
float readDepth = ((i * 2) + 0.5f) / (sourceDepth - 1);
d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 0], x1, y1, i, u1, v2, readDepth);
d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 1], x1, y2, i, u1, v1, readDepth);
d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 2], x2, y1, i, u2, v2, readDepth);
d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 3], x1, y2, i, u1, v1, readDepth);
d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 4], x2, y2, i, u2, v1, readDepth);
d3d11::SetPositionLayerTexCoord3DVertex(&vertices[i * 6 + 5], x2, y1, i, u2, v2, readDepth);
}
stride = sizeof(d3d11::PositionLayerTexCoord3DVertex);
drawCount = destDepth * 6;
topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
}
else
{
d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2);
d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1);
d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2);
d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1);
stride = sizeof(d3d11::PositionTexCoordVertex);
drawCount = 4;
topology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
}
mDeviceContext->Unmap(mCopyVB, 0);
mDeviceContext->IASetVertexBuffers(0, 1, &mCopyVB, &stride, &startIdx);
// Apply state
mDeviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF);
mDeviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF);
mDeviceContext->RSSetState(NULL);
// Apply shaders
ID3D11InputLayout *il = NULL;
ID3D11VertexShader *vs = NULL;
ID3D11GeometryShader *gs = NULL;
ID3D11PixelShader *ps = NULL;
if (use3DCopy)
{
il = mCopy3DIL;
vs = mCopy3DVS;
gs = mCopy3DGS;
switch(destFormat)
{
case GL_RGBA: ps = mCopyRGBA3DPS; break;
case GL_RGB: ps = mCopyRGB3DPS; break;
case GL_ALPHA: ps = mCopyRGBA3DPS; break;
case GL_BGRA_EXT: ps = mCopyRGBA3DPS; break;
case GL_LUMINANCE: ps = mCopyLum3DPS; break;
case GL_LUMINANCE_ALPHA: ps = mCopyLumAlpha3DPS; break;
default: UNREACHABLE(); ps = NULL; break;
}
}
else
{
il = mCopy2DIL;
vs = mCopy2DVS;
gs = NULL;
switch(destFormat)
{
case GL_RGBA: ps = mCopyRGBA2DPS; break;
case GL_RGB: ps = mCopyRGB2DPS; break;
case GL_ALPHA: ps = mCopyRGBA2DPS; break;
case GL_BGRA_EXT: ps = mCopyRGBA2DPS; break;
case GL_LUMINANCE: ps = mCopyLum2DPS; break;
case GL_LUMINANCE_ALPHA: ps = mCopyLumAlpha2DPS; break;
default: UNREACHABLE(); ps = NULL; break;
}
}
mDeviceContext->IASetInputLayout(il);
mDeviceContext->IASetPrimitiveTopology(topology);
mDeviceContext->VSSetShader(vs, NULL, 0);
mDeviceContext->PSSetShader(ps, NULL, 0);
mDeviceContext->GSSetShader(gs, NULL, 0);
// Unset the currently bound shader resource to avoid conflicts
static ID3D11ShaderResourceView *const nullSRV = NULL;
mDeviceContext->PSSetShaderResources(0, 1, &nullSRV);
// Apply render target
setOneTimeRenderTarget(dest);
// Set the viewport
D3D11_VIEWPORT viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = destWidth;
viewport.Height = destHeight;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
mDeviceContext->RSSetViewports(1, &viewport);
// Apply textures
mDeviceContext->PSSetShaderResources(0, 1, &source);
mDeviceContext->PSSetSamplers(0, 1, &mCopySampler);
// Draw the quad
mDeviceContext->Draw(drawCount, 0);
// Unbind textures and render targets and vertex buffer
mDeviceContext->PSSetShaderResources(0, 1, &nullSRV);
unapplyRenderTargets();
UINT zero = 0;
ID3D11Buffer *const nullBuffer = NULL;
mDeviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
markAllStateDirty();
return true;
}
void Renderer11::unapplyRenderTargets() void Renderer11::unapplyRenderTargets()
{ {
setOneTimeRenderTarget(NULL); setOneTimeRenderTarget(NULL);
......
...@@ -29,6 +29,7 @@ namespace rx ...@@ -29,6 +29,7 @@ namespace rx
class VertexDataManager; class VertexDataManager;
class IndexDataManager; class IndexDataManager;
class StreamingIndexBufferInterface; class StreamingIndexBufferInterface;
class Blit11;
enum enum
{ {
...@@ -163,10 +164,6 @@ class Renderer11 : public Renderer ...@@ -163,10 +164,6 @@ class Renderer11 : public Renderer
virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level); GLint xoffset, GLint yoffset, GLint zOffset, TextureStorageInterface2DArray *storage, GLint level);
bool copyTexture(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
ID3D11RenderTargetView *dest, const gl::Box &destArea, unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
GLenum destFormat);
virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
bool blitRenderTarget, bool blitDepthStencil); bool blitRenderTarget, bool blitDepthStencil);
virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
...@@ -203,6 +200,8 @@ class Renderer11 : public Renderer ...@@ -203,6 +200,8 @@ class Renderer11 : public Renderer
ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; }; ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
IDXGIFactory *getDxgiFactory() { return mDxgiFactory; }; IDXGIFactory *getDxgiFactory() { return mDxgiFactory; };
Blit11 *getBlitter() { return mBlit; }
bool getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource); bool getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource);
void unapplyRenderTargets(); void unapplyRenderTargets();
void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView); void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView);
...@@ -339,24 +338,7 @@ class Renderer11 : public Renderer ...@@ -339,24 +338,7 @@ class Renderer11 : public Renderer
StreamingIndexBufferInterface *mTriangleFanIB; StreamingIndexBufferInterface *mTriangleFanIB;
// Texture copy resources // Texture copy resources
bool mCopyResourcesInitialized; Blit11 *mBlit;
ID3D11Buffer *mCopyVB;
ID3D11SamplerState *mCopySampler;
ID3D11InputLayout *mCopy2DIL;
ID3D11VertexShader *mCopy2DVS;
ID3D11PixelShader *mCopyRGBA2DPS;
ID3D11PixelShader *mCopyRGB2DPS;
ID3D11PixelShader *mCopyLum2DPS;
ID3D11PixelShader *mCopyLumAlpha2DPS;
ID3D11InputLayout *mCopy3DIL;
ID3D11VertexShader *mCopy3DVS;
ID3D11GeometryShader *mCopy3DGS;
ID3D11PixelShader *mCopyRGBA3DPS;
ID3D11PixelShader *mCopyRGB3DPS;
ID3D11PixelShader *mCopyLum3DPS;
ID3D11PixelShader *mCopyLumAlpha3DPS;
// Masked clear resources // Masked clear resources
bool mClearResourcesInitialized; bool mClearResourcesInitialized;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "libGLESv2/renderer/RenderTarget11.h" #include "libGLESv2/renderer/RenderTarget11.h"
#include "libGLESv2/renderer/SwapChain11.h" #include "libGLESv2/renderer/SwapChain11.h"
#include "libGLESv2/renderer/renderer11_utils.h" #include "libGLESv2/renderer/renderer11_utils.h"
#include "libGLESv2/renderer/Blit11.h"
#include "libGLESv2/renderer/formatutils11.h" #include "libGLESv2/renderer/formatutils11.h"
#include "common/utilities.h" #include "common/utilities.h"
...@@ -142,25 +143,16 @@ void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget1 ...@@ -142,25 +143,16 @@ void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget1
if (sourceSRV && destRTV) if (sourceSRV && destRTV)
{ {
gl::Box sourceArea; gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
sourceArea.x = 0; gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
sourceArea.y = 0;
sourceArea.z = 0; gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
sourceArea.width = source->getWidth(); gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
sourceArea.height = source->getHeight();
sourceArea.depth = source->getDepth(); Blit11 *blitter = mRenderer->getBlitter();
gl::Box destArea; blitter->copyTexture(sourceSRV, sourceArea, sourceSize, destRTV, destArea, destSize,
destArea.x = 0; GL_RGBA, GL_LINEAR);
destArea.y = 0;
destArea.z = 0;
destArea.width = dest->getWidth();
destArea.height = dest->getHeight();
destArea.depth = dest->getDepth();
mRenderer->copyTexture(sourceSRV, sourceArea, source->getWidth(), source->getHeight(), source->getDepth(),
destRTV, destArea, dest->getWidth(), dest->getHeight(), dest->getDepth(),
GL_RGBA);
} }
if (sourceSRV) if (sourceSRV)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment