Commit 5733801a by Jamie Madill Committed by Commit Bot

D3D11: Refactor depth/stencil blit code.

Blit11 refactorings enable re-using some code for multisample resolve blits. Also some Renderer11 refactorings to use TextureHelper11 make the code more flexible for the multisample resolve, to come later. BUG=angleproject:1246 Change-Id: Id0c168cef75b0f487cb3995a906f6473989edcd5 Reviewed-on: https://chromium-review.googlesource.com/354420Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 82a468af
...@@ -66,56 +66,131 @@ namespace rx ...@@ -66,56 +66,131 @@ namespace rx
namespace namespace
{ {
DXGI_FORMAT GetTextureFormat(ID3D11Resource *resource) void StretchedBlitNearest_RowByRow(const gl::Box &sourceArea,
const gl::Box &destArea,
const gl::Rectangle &clippedDestArea,
const gl::Extents &sourceSize,
unsigned int sourceRowPitch,
unsigned int destRowPitch,
size_t pixelSize,
const uint8_t *sourceData,
uint8_t *destData)
{ {
ID3D11Texture2D *texture = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource); int srcHeightSubOne = (sourceArea.height - 1);
if (!texture) size_t copySize = pixelSize * destArea.width;
{ size_t srcOffset = sourceArea.x * pixelSize;
return DXGI_FORMAT_UNKNOWN; size_t destOffset = destArea.x * pixelSize;
}
D3D11_TEXTURE2D_DESC desc; for (int y = clippedDestArea.y; y < clippedDestArea.y + clippedDestArea.height; y++)
texture->GetDesc(&desc); {
float yPerc = static_cast<float>(y - destArea.y) / (destArea.height - 1);
SafeRelease(texture); // Interpolate using the original source rectangle to determine which row to sample from
// while clamping to the edges
unsigned int readRow = static_cast<unsigned int>(
gl::clamp(sourceArea.y + floor(yPerc * srcHeightSubOne + 0.5f), 0, srcHeightSubOne));
unsigned int writeRow = y;
return desc.Format; const uint8_t *sourceRow = sourceData + readRow * sourceRowPitch + srcOffset;
uint8_t *destRow = destData + writeRow * destRowPitch + destOffset;
memcpy(destRow, sourceRow, copySize);
}
} }
ID3D11Resource *CreateStagingTexture(ID3D11Device *device, ID3D11DeviceContext *context, void StretchedBlitNearest_PixelByPixel(const gl::Box &sourceArea,
ID3D11Resource *source, unsigned int subresource, const gl::Box &destArea,
const gl::Extents &size, unsigned int cpuAccessFlags) const gl::Rectangle &clippedDestArea,
const gl::Extents &sourceSize,
unsigned int sourceRowPitch,
unsigned int destRowPitch,
ptrdiff_t readOffset,
ptrdiff_t writeOffset,
size_t copySize,
size_t srcPixelStride,
size_t destPixelStride,
const uint8_t *sourceData,
uint8_t *destData)
{ {
D3D11_TEXTURE2D_DESC stagingDesc; auto xMax = clippedDestArea.x + clippedDestArea.width;
stagingDesc.Width = size.width; auto yMax = clippedDestArea.y + clippedDestArea.height;
stagingDesc.Height = size.height;
stagingDesc.MipLevels = 1; for (int writeRow = clippedDestArea.y; writeRow < yMax; writeRow++)
stagingDesc.ArraySize = 1; {
stagingDesc.Format = GetTextureFormat(source); // Interpolate using the original source rectangle to determine which row to sample from
stagingDesc.SampleDesc.Count = 1; // while clamping to the edges
stagingDesc.SampleDesc.Quality = 0; float yPerc = static_cast<float>(writeRow - destArea.y) / (destArea.height - 1);
stagingDesc.Usage = D3D11_USAGE_STAGING; float yRounded = floor(yPerc * (sourceArea.height - 1) + 0.5f);
stagingDesc.CPUAccessFlags = cpuAccessFlags; unsigned int readRow =
stagingDesc.MiscFlags = 0; static_cast<unsigned int>(gl::clamp(sourceArea.y + yRounded, 0, sourceSize.height - 1));
stagingDesc.BindFlags = 0;
for (int writeColumn = clippedDestArea.x; writeColumn < xMax; writeColumn++)
ID3D11Texture2D *stagingTexture = nullptr;
HRESULT result = device->CreateTexture2D(&stagingDesc, nullptr, &stagingTexture);
if (FAILED(result))
{ {
ERR("Failed to create staging texture for depth stencil blit. HRESULT: 0x%X.", result); // Interpolate the original source rectangle to determine which column to sample
return nullptr; // from while clamping to the edges
float xPerc = static_cast<float>(writeColumn - destArea.x) / (destArea.width - 1);
float xRounded = floor(xPerc * (sourceArea.width - 1) + 0.5f);
unsigned int readColumn = static_cast<unsigned int>(
gl::clamp(sourceArea.x + xRounded, 0, sourceSize.height - 1));
const uint8_t *sourcePixel =
sourceData + readRow * sourceRowPitch + readColumn * srcPixelStride + readOffset;
uint8_t *destPixel =
destData + writeRow * destRowPitch + writeColumn * destPixelStride + writeOffset;
memcpy(destPixel, sourcePixel, copySize);
}
} }
}
context->CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, source, subresource, nullptr); void StretchedBlitNearest(const gl::Box &sourceArea,
const gl::Box &destArea,
const gl::Rectangle &clipRect,
const gl::Extents &sourceSize,
unsigned int sourceRowPitch,
unsigned int destRowPitch,
ptrdiff_t readOffset,
ptrdiff_t writeOffset,
size_t copySize,
size_t srcPixelStride,
size_t destPixelStride,
const uint8_t *sourceData,
uint8_t *destData)
{
gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height);
gl::ClipRectangle(clippedDestArea, clipRect, &clippedDestArea);
return stagingTexture; // Determine if entire rows can be copied at once instead of each individual pixel. There
// must be no out of bounds lookups, whole rows copies, and no scale.
if (sourceArea.width == clippedDestArea.width && sourceArea.x >= 0 &&
sourceArea.x + sourceArea.width <= sourceSize.width && copySize == srcPixelStride &&
copySize == destPixelStride)
{
StretchedBlitNearest_RowByRow(sourceArea, destArea, clippedDestArea, sourceSize,
sourceRowPitch, destRowPitch, srcPixelStride, sourceData,
destData);
}
else
{
StretchedBlitNearest_PixelByPixel(sourceArea, destArea, clippedDestArea, sourceSize,
sourceRowPitch, destRowPitch, readOffset, writeOffset,
copySize, srcPixelStride, destPixelStride, sourceData,
destData);
}
} }
inline void GenerateVertexCoords(const gl::Box &sourceArea, const gl::Extents &sourceSize, inline void GenerateVertexCoords(const gl::Box &sourceArea,
const gl::Box &destArea, const gl::Extents &destSize, const gl::Extents &sourceSize,
float *x1, float *y1, float *x2, float *y2, const gl::Box &destArea,
float *u1, float *v1, float *u2, float *v2) 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; *x1 = (destArea.x / float(destSize.width)) * 2.0f - 1.0f;
*y1 = ((destSize.height - destArea.y - destArea.height) / float(destSize.height)) * 2.0f - 1.0f; *y1 = ((destSize.height - destArea.y - destArea.height) / float(destSize.height)) * 2.0f - 1.0f;
...@@ -128,15 +203,21 @@ inline void GenerateVertexCoords(const gl::Box &sourceArea, const gl::Extents &s ...@@ -128,15 +203,21 @@ inline void GenerateVertexCoords(const gl::Box &sourceArea, const gl::Extents &s
*v2 = (sourceArea.y + sourceArea.height) / float(sourceSize.height); *v2 = (sourceArea.y + sourceArea.height) / float(sourceSize.height);
} }
void Write2DVertices(const gl::Box &sourceArea, const gl::Extents &sourceSize, void Write2DVertices(const gl::Box &sourceArea,
const gl::Box &destArea, const gl::Extents &destSize, const gl::Extents &sourceSize,
void *outVertices, unsigned int *outStride, unsigned int *outVertexCount, const gl::Box &destArea,
const gl::Extents &destSize,
void *outVertices,
unsigned int *outStride,
unsigned int *outVertexCount,
D3D11_PRIMITIVE_TOPOLOGY *outTopology) D3D11_PRIMITIVE_TOPOLOGY *outTopology)
{ {
float x1, y1, x2, y2, u1, v1, u2, v2; float x1, y1, x2, y2, u1, v1, u2, v2;
GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &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::PositionTexCoordVertex *vertices =
static_cast<d3d11::PositionTexCoordVertex *>(outVertices);
d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2); d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2);
d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1); d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1);
...@@ -148,17 +229,23 @@ void Write2DVertices(const gl::Box &sourceArea, const gl::Extents &sourceSize, ...@@ -148,17 +229,23 @@ void Write2DVertices(const gl::Box &sourceArea, const gl::Extents &sourceSize,
*outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; *outTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
} }
void Write3DVertices(const gl::Box &sourceArea, const gl::Extents &sourceSize, void Write3DVertices(const gl::Box &sourceArea,
const gl::Box &destArea, const gl::Extents &destSize, const gl::Extents &sourceSize,
void *outVertices, unsigned int *outStride, unsigned int *outVertexCount, const gl::Box &destArea,
const gl::Extents &destSize,
void *outVertices,
unsigned int *outStride,
unsigned int *outVertexCount,
D3D11_PRIMITIVE_TOPOLOGY *outTopology) D3D11_PRIMITIVE_TOPOLOGY *outTopology)
{ {
ASSERT(sourceSize.depth > 0 && destSize.depth > 0); ASSERT(sourceSize.depth > 0 && destSize.depth > 0);
float x1, y1, x2, y2, u1, v1, u2, v2; float x1, y1, x2, y2, u1, v1, u2, v2;
GenerateVertexCoords(sourceArea, sourceSize, destArea, destSize, &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); d3d11::PositionLayerTexCoord3DVertex *vertices =
static_cast<d3d11::PositionLayerTexCoord3DVertex *>(outVertices);
for (int i = 0; i < destSize.depth; i++) for (int i = 0; i < destSize.depth; i++)
{ {
...@@ -184,13 +271,27 @@ inline unsigned int GetSwizzleIndex(GLenum swizzle) ...@@ -184,13 +271,27 @@ inline unsigned int GetSwizzleIndex(GLenum swizzle)
switch (swizzle) switch (swizzle)
{ {
case GL_RED: colorIndex = 0; break; case GL_RED:
case GL_GREEN: colorIndex = 1; break; colorIndex = 0;
case GL_BLUE: colorIndex = 2; break; break;
case GL_ALPHA: colorIndex = 3; break; case GL_GREEN:
case GL_ZERO: colorIndex = 4; break; colorIndex = 1;
case GL_ONE: colorIndex = 5; break; break;
default: UNREACHABLE(); break; case GL_BLUE:
colorIndex = 2;
break;
case GL_ALPHA:
colorIndex = 3;
break;
case GL_ZERO:
colorIndex = 4;
break;
case GL_ONE:
colorIndex = 5;
break;
default:
UNREACHABLE();
break;
} }
return colorIndex; return colorIndex;
...@@ -213,17 +314,15 @@ D3D11_BLEND_DESC GetAlphaMaskBlendStateDesc() ...@@ -213,17 +314,15 @@ D3D11_BLEND_DESC GetAlphaMaskBlendStateDesc()
return desc; return desc;
} }
D3D11_INPUT_ELEMENT_DESC quad2DLayout[] = D3D11_INPUT_ELEMENT_DESC quad2DLayout[] = {
{ {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{ "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},
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
}; };
D3D11_INPUT_ELEMENT_DESC quad3DLayout[] = D3D11_INPUT_ELEMENT_DESC quad3DLayout[] = {
{ {"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{ "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},
{ "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},
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
}; };
} // namespace } // namespace
...@@ -455,7 +554,9 @@ void Blit11::freeResources() ...@@ -455,7 +554,9 @@ void Blit11::freeResources()
} }
// static // static
Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool isSigned, ShaderDimension dimension) Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat,
bool isSigned,
ShaderDimension dimension)
{ {
if (dimension == SHADER_3D) if (dimension == SHADER_3D)
{ {
...@@ -463,10 +564,14 @@ Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool ...@@ -463,10 +564,14 @@ Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool
{ {
switch (destinationFormat) switch (destinationFormat)
{ {
case GL_RGBA_INTEGER: return BLITSHADER_3D_RGBAI; case GL_RGBA_INTEGER:
case GL_RGB_INTEGER: return BLITSHADER_3D_RGBI; return BLITSHADER_3D_RGBAI;
case GL_RG_INTEGER: return BLITSHADER_3D_RGI; case GL_RGB_INTEGER:
case GL_RED_INTEGER: return BLITSHADER_3D_RI; return BLITSHADER_3D_RGBI;
case GL_RG_INTEGER:
return BLITSHADER_3D_RGI;
case GL_RED_INTEGER:
return BLITSHADER_3D_RI;
default: default:
UNREACHABLE(); UNREACHABLE();
return BLITSHADER_INVALID; return BLITSHADER_INVALID;
...@@ -476,18 +581,30 @@ Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool ...@@ -476,18 +581,30 @@ Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool
{ {
switch (destinationFormat) switch (destinationFormat)
{ {
case GL_RGBA: return BLITSHADER_3D_RGBAF; case GL_RGBA:
case GL_RGBA_INTEGER: return BLITSHADER_3D_RGBAUI; return BLITSHADER_3D_RGBAF;
case GL_BGRA_EXT: return BLITSHADER_3D_BGRAF; case GL_RGBA_INTEGER:
case GL_RGB: return BLITSHADER_3D_RGBF; return BLITSHADER_3D_RGBAUI;
case GL_RGB_INTEGER: return BLITSHADER_3D_RGBUI; case GL_BGRA_EXT:
case GL_RG: return BLITSHADER_3D_RGF; return BLITSHADER_3D_BGRAF;
case GL_RG_INTEGER: return BLITSHADER_3D_RGUI; case GL_RGB:
case GL_RED: return BLITSHADER_3D_RF; return BLITSHADER_3D_RGBF;
case GL_RED_INTEGER: return BLITSHADER_3D_RUI; case GL_RGB_INTEGER:
case GL_ALPHA: return BLITSHADER_3D_ALPHA; return BLITSHADER_3D_RGBUI;
case GL_LUMINANCE: return BLITSHADER_3D_LUMA; case GL_RG:
case GL_LUMINANCE_ALPHA: return BLITSHADER_3D_LUMAALPHA; return BLITSHADER_3D_RGF;
case GL_RG_INTEGER:
return BLITSHADER_3D_RGUI;
case GL_RED:
return BLITSHADER_3D_RF;
case GL_RED_INTEGER:
return BLITSHADER_3D_RUI;
case GL_ALPHA:
return BLITSHADER_3D_ALPHA;
case GL_LUMINANCE:
return BLITSHADER_3D_LUMA;
case GL_LUMINANCE_ALPHA:
return BLITSHADER_3D_LUMAALPHA;
default: default:
UNREACHABLE(); UNREACHABLE();
return BLITSHADER_INVALID; return BLITSHADER_INVALID;
...@@ -498,10 +615,14 @@ Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool ...@@ -498,10 +615,14 @@ Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool
{ {
switch (destinationFormat) switch (destinationFormat)
{ {
case GL_RGBA_INTEGER: return BLITSHADER_2D_RGBAI; case GL_RGBA_INTEGER:
case GL_RGB_INTEGER: return BLITSHADER_2D_RGBI; return BLITSHADER_2D_RGBAI;
case GL_RG_INTEGER: return BLITSHADER_2D_RGI; case GL_RGB_INTEGER:
case GL_RED_INTEGER: return BLITSHADER_2D_RI; return BLITSHADER_2D_RGBI;
case GL_RG_INTEGER:
return BLITSHADER_2D_RGI;
case GL_RED_INTEGER:
return BLITSHADER_2D_RI;
default: default:
UNREACHABLE(); UNREACHABLE();
return BLITSHADER_INVALID; return BLITSHADER_INVALID;
...@@ -511,18 +632,30 @@ Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool ...@@ -511,18 +632,30 @@ Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool
{ {
switch (destinationFormat) switch (destinationFormat)
{ {
case GL_RGBA: return BLITSHADER_2D_RGBAF; case GL_RGBA:
case GL_RGBA_INTEGER: return BLITSHADER_2D_RGBAUI; return BLITSHADER_2D_RGBAF;
case GL_BGRA_EXT: return BLITSHADER_2D_BGRAF; case GL_RGBA_INTEGER:
case GL_RGB: return BLITSHADER_2D_RGBF; return BLITSHADER_2D_RGBAUI;
case GL_RGB_INTEGER: return BLITSHADER_2D_RGBUI; case GL_BGRA_EXT:
case GL_RG: return BLITSHADER_2D_RGF; return BLITSHADER_2D_BGRAF;
case GL_RG_INTEGER: return BLITSHADER_2D_RGUI; case GL_RGB:
case GL_RED: return BLITSHADER_2D_RF; return BLITSHADER_2D_RGBF;
case GL_RED_INTEGER: return BLITSHADER_2D_RUI; case GL_RGB_INTEGER:
case GL_ALPHA: return BLITSHADER_2D_ALPHA; return BLITSHADER_2D_RGBUI;
case GL_LUMINANCE: return BLITSHADER_2D_LUMA; case GL_RG:
case GL_LUMINANCE_ALPHA: return BLITSHADER_2D_LUMAALPHA; return BLITSHADER_2D_RGF;
case GL_RG_INTEGER:
return BLITSHADER_2D_RGUI;
case GL_RED:
return BLITSHADER_2D_RF;
case GL_RED_INTEGER:
return BLITSHADER_2D_RUI;
case GL_ALPHA:
return BLITSHADER_2D_ALPHA;
case GL_LUMINANCE:
return BLITSHADER_2D_LUMA;
case GL_LUMINANCE_ALPHA:
return BLITSHADER_2D_LUMAALPHA;
default: default:
UNREACHABLE(); UNREACHABLE();
return BLITSHADER_INVALID; return BLITSHADER_INVALID;
...@@ -531,16 +664,20 @@ Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool ...@@ -531,16 +664,20 @@ Blit11::BlitShaderType Blit11::GetBlitShaderType(GLenum destinationFormat, bool
} }
// static // static
Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type, D3D11_SRV_DIMENSION dimensionality) Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type,
D3D11_SRV_DIMENSION dimensionality)
{ {
switch (dimensionality) switch (dimensionality)
{ {
case D3D11_SRV_DIMENSION_TEXTURE2D: case D3D11_SRV_DIMENSION_TEXTURE2D:
switch (type) switch (type)
{ {
case GL_FLOAT: return SWIZZLESHADER_2D_FLOAT; case GL_FLOAT:
case GL_UNSIGNED_INT: return SWIZZLESHADER_2D_UINT; return SWIZZLESHADER_2D_FLOAT;
case GL_INT: return SWIZZLESHADER_2D_INT; case GL_UNSIGNED_INT:
return SWIZZLESHADER_2D_UINT;
case GL_INT:
return SWIZZLESHADER_2D_INT;
default: default:
UNREACHABLE(); UNREACHABLE();
return SWIZZLESHADER_INVALID; return SWIZZLESHADER_INVALID;
...@@ -548,9 +685,12 @@ Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type, D3D11_SRV_DI ...@@ -548,9 +685,12 @@ Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type, D3D11_SRV_DI
case D3D11_SRV_DIMENSION_TEXTURECUBE: case D3D11_SRV_DIMENSION_TEXTURECUBE:
switch (type) switch (type)
{ {
case GL_FLOAT: return SWIZZLESHADER_CUBE_FLOAT; case GL_FLOAT:
case GL_UNSIGNED_INT: return SWIZZLESHADER_CUBE_UINT; return SWIZZLESHADER_CUBE_FLOAT;
case GL_INT: return SWIZZLESHADER_CUBE_INT; case GL_UNSIGNED_INT:
return SWIZZLESHADER_CUBE_UINT;
case GL_INT:
return SWIZZLESHADER_CUBE_INT;
default: default:
UNREACHABLE(); UNREACHABLE();
return SWIZZLESHADER_INVALID; return SWIZZLESHADER_INVALID;
...@@ -558,9 +698,12 @@ Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type, D3D11_SRV_DI ...@@ -558,9 +698,12 @@ Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type, D3D11_SRV_DI
case D3D11_SRV_DIMENSION_TEXTURE3D: case D3D11_SRV_DIMENSION_TEXTURE3D:
switch (type) switch (type)
{ {
case GL_FLOAT: return SWIZZLESHADER_3D_FLOAT; case GL_FLOAT:
case GL_UNSIGNED_INT: return SWIZZLESHADER_3D_UINT; return SWIZZLESHADER_3D_FLOAT;
case GL_INT: return SWIZZLESHADER_3D_INT; case GL_UNSIGNED_INT:
return SWIZZLESHADER_3D_UINT;
case GL_INT:
return SWIZZLESHADER_3D_INT;
default: default:
UNREACHABLE(); UNREACHABLE();
return SWIZZLESHADER_INVALID; return SWIZZLESHADER_INVALID;
...@@ -568,9 +711,12 @@ Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type, D3D11_SRV_DI ...@@ -568,9 +711,12 @@ Blit11::SwizzleShaderType Blit11::GetSwizzleShaderType(GLenum type, D3D11_SRV_DI
case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
switch (type) switch (type)
{ {
case GL_FLOAT: return SWIZZLESHADER_ARRAY_FLOAT; case GL_FLOAT:
case GL_UNSIGNED_INT: return SWIZZLESHADER_ARRAY_UINT; return SWIZZLESHADER_ARRAY_FLOAT;
case GL_INT: return SWIZZLESHADER_ARRAY_INT; case GL_UNSIGNED_INT:
return SWIZZLESHADER_ARRAY_UINT;
case GL_INT:
return SWIZZLESHADER_ARRAY_INT;
default: default:
UNREACHABLE(); UNREACHABLE();
return SWIZZLESHADER_INVALID; return SWIZZLESHADER_INVALID;
...@@ -610,11 +756,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ...@@ -610,11 +756,7 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source,
const gl::Extents &size, const gl::Extents &size,
const gl::SwizzleState &swizzleTarget) const gl::SwizzleState &swizzleTarget)
{ {
gl::Error error = initResources(); ANGLE_TRY(initResources());
if (error.isError())
{
return error;
}
HRESULT result; HRESULT result;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
...@@ -661,18 +803,16 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ...@@ -661,18 +803,16 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source,
} }
const Shader *shader = nullptr; const Shader *shader = nullptr;
error = getSwizzleShader(shaderType, sourceSRVDesc.ViewDimension, &shader); ANGLE_TRY(getSwizzleShader(shaderType, sourceSRVDesc.ViewDimension, &shader));
if (error.isError())
{
return error;
}
// Set vertices // Set vertices
D3D11_MAPPED_SUBRESOURCE mappedResource; D3D11_MAPPED_SUBRESOURCE mappedResource;
result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result)) if (FAILED(result))
{ {
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for swizzle, HRESULT: 0x%X.", result); return gl::Error(GL_OUT_OF_MEMORY,
"Failed to map internal vertex buffer for swizzle, HRESULT: 0x%X.",
result);
} }
const ShaderSupport &support = getShaderSupport(*shader); const ShaderSupport &support = getShaderSupport(*shader);
...@@ -683,7 +823,8 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ...@@ -683,7 +823,8 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source,
D3D11_PRIMITIVE_TOPOLOGY topology; D3D11_PRIMITIVE_TOPOLOGY topology;
gl::Box area(0, 0, 0, size.width, size.height, size.depth); gl::Box area(0, 0, 0, size.width, size.height, size.depth);
support.vertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount, &topology); support.vertexWriteFunction(area, size, area, size, mappedResource.pData, &stride, &drawCount,
&topology);
deviceContext->Unmap(mVertexBuffer, 0); deviceContext->Unmap(mVertexBuffer, 0);
...@@ -691,10 +832,12 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source, ...@@ -691,10 +832,12 @@ gl::Error Blit11::swizzleTexture(ID3D11ShaderResourceView *source,
result = deviceContext->Map(mSwizzleCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); result = deviceContext->Map(mSwizzleCB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result)) if (FAILED(result))
{ {
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal constant buffer for swizzle, HRESULT: 0x%X.", result); return gl::Error(GL_OUT_OF_MEMORY,
"Failed to map internal constant buffer for swizzle, HRESULT: 0x%X.",
result);
} }
unsigned int *swizzleIndices = reinterpret_cast<unsigned int*>(mappedResource.pData); unsigned int *swizzleIndices = reinterpret_cast<unsigned int *>(mappedResource.pData);
swizzleIndices[0] = GetSwizzleIndex(swizzleTarget.swizzleRed); swizzleIndices[0] = GetSwizzleIndex(swizzleTarget.swizzleRed);
swizzleIndices[1] = GetSwizzleIndex(swizzleTarget.swizzleGreen); swizzleIndices[1] = GetSwizzleIndex(swizzleTarget.swizzleGreen);
swizzleIndices[2] = GetSwizzleIndex(swizzleTarget.swizzleBlue); swizzleIndices[2] = GetSwizzleIndex(swizzleTarget.swizzleBlue);
...@@ -787,7 +930,8 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, ...@@ -787,7 +930,8 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source,
ASSERT(componentType != GL_SIGNED_NORMALIZED); ASSERT(componentType != GL_SIGNED_NORMALIZED);
bool isSigned = (componentType == GL_INT); bool isSigned = (componentType == GL_INT);
ShaderDimension dimension = (sourceSRVDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D) ? SHADER_3D : SHADER_2D; ShaderDimension dimension =
(sourceSRVDesc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D) ? SHADER_3D : SHADER_2D;
const Shader *shader = nullptr; const Shader *shader = nullptr;
ANGLE_TRY(getBlitShader(destFormat, isSigned, dimension, &shader)); ANGLE_TRY(getBlitShader(destFormat, isSigned, dimension, &shader));
...@@ -798,7 +942,9 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, ...@@ -798,7 +942,9 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source,
result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result)) if (FAILED(result))
{ {
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for texture copy, HRESULT: 0x%X.", result); return gl::Error(GL_OUT_OF_MEMORY,
"Failed to map internal vertex buffer for texture copy, HRESULT: 0x%X.",
result);
} }
UINT stride = 0; UINT stride = 0;
...@@ -875,8 +1021,12 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, ...@@ -875,8 +1021,12 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source,
ID3D11SamplerState *sampler = nullptr; ID3D11SamplerState *sampler = nullptr;
switch (filter) switch (filter)
{ {
case GL_NEAREST: sampler = mPointSampler; break; case GL_NEAREST:
case GL_LINEAR: sampler = mLinearSampler; break; sampler = mPointSampler;
break;
case GL_LINEAR:
sampler = mLinearSampler;
break;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -899,24 +1049,29 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source, ...@@ -899,24 +1049,29 @@ gl::Error Blit11::copyTexture(ID3D11ShaderResourceView *source,
return gl::NoError(); return gl::NoError();
} }
gl::Error Blit11::copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, gl::Error Blit11::copyStencil(const TextureHelper11 &source,
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, unsigned int sourceSubresource,
const gl::Box &sourceArea,
const gl::Extents &sourceSize,
const TextureHelper11 &dest,
unsigned int destSubresource,
const gl::Box &destArea,
const gl::Extents &destSize,
const gl::Rectangle *scissor) const gl::Rectangle *scissor)
{ {
return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize, return copyDepthStencilImpl(source, sourceSubresource, sourceArea, sourceSize, dest,
dest, destSubresource, destArea, destSize, destSubresource, destArea, destSize, scissor, true);
scissor, true);
} }
gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source,
ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, const gl::Box &sourceArea,
const gl::Extents &sourceSize,
ID3D11DepthStencilView *dest,
const gl::Box &destArea,
const gl::Extents &destSize,
const gl::Rectangle *scissor) const gl::Rectangle *scissor)
{ {
gl::Error error = initResources(); ANGLE_TRY(initResources());
if (error.isError())
{
return error;
}
HRESULT result; HRESULT result;
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
...@@ -926,7 +1081,9 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou ...@@ -926,7 +1081,9 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou
result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); result = deviceContext->Map(mVertexBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
if (FAILED(result)) if (FAILED(result))
{ {
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal vertex buffer for texture copy, HRESULT: 0x%X.", result); return gl::Error(GL_OUT_OF_MEMORY,
"Failed to map internal vertex buffer for texture copy, HRESULT: 0x%X.",
result);
} }
UINT stride = 0; UINT stride = 0;
...@@ -934,8 +1091,8 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou ...@@ -934,8 +1091,8 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou
UINT drawCount = 0; UINT drawCount = 0;
D3D11_PRIMITIVE_TOPOLOGY topology; D3D11_PRIMITIVE_TOPOLOGY topology;
Write2DVertices(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, Write2DVertices(sourceArea, sourceSize, destArea, destSize, mappedResource.pData, &stride,
&stride, &drawCount, &topology); &drawCount, &topology);
deviceContext->Unmap(mVertexBuffer, 0); deviceContext->Unmap(mVertexBuffer, 0);
...@@ -1015,45 +1172,36 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou ...@@ -1015,45 +1172,36 @@ gl::Error Blit11::copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sou
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, gl::Error Blit11::copyDepthStencil(const TextureHelper11 &source,
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, unsigned int sourceSubresource,
const gl::Box &sourceArea,
const gl::Extents &sourceSize,
const TextureHelper11 &dest,
unsigned int destSubresource,
const gl::Box &destArea,
const gl::Extents &destSize,
const gl::Rectangle *scissor) const gl::Rectangle *scissor)
{ {
return copyDepthStencil(source, sourceSubresource, sourceArea, sourceSize, return copyDepthStencilImpl(source, sourceSubresource, sourceArea, sourceSize, dest,
dest, destSubresource, destArea, destSize, destSubresource, destArea, destSize, scissor, false);
scissor, false);
} }
gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, gl::Error Blit11::copyDepthStencilImpl(const TextureHelper11 &source,
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, unsigned int sourceSubresource,
const gl::Rectangle *scissor, bool stencilOnly) const gl::Box &sourceArea,
const gl::Extents &sourceSize,
const TextureHelper11 &dest,
unsigned int destSubresource,
const gl::Box &destArea,
const gl::Extents &destSize,
const gl::Rectangle *scissor,
bool stencilOnly)
{ {
gl::Error error = initResources(); ASSERT(source.getANGLEFormat() == dest.getANGLEFormat());
if (error.isError())
{
return error;
}
ID3D11Device *device = mRenderer->getDevice(); auto format = source.getFormat();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); const auto &sizeInfo = d3d11::GetDXGIFormatSizeInfo(format);
unsigned int pixelSize = sizeInfo.pixelBytes;
ID3D11Resource *sourceStaging = CreateStagingTexture(device, deviceContext, source, sourceSubresource, sourceSize, D3D11_CPU_ACCESS_READ);
// HACK: Create the destination staging buffer as a read/write texture so ID3D11DevicContext::UpdateSubresource can be called
// using it's mapped data as a source
ID3D11Resource *destStaging = CreateStagingTexture(device, deviceContext, dest, destSubresource, destSize, D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE);
if (!sourceStaging || !destStaging)
{
SafeRelease(sourceStaging);
SafeRelease(destStaging);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal staging textures for depth stencil blit.");
}
DXGI_FORMAT format = GetTextureFormat(source);
ASSERT(format == GetTextureFormat(dest));
const d3d11::DXGIFormatSize &dxgiFormatSizeInfo = d3d11::GetDXGIFormatSizeInfo(format);
unsigned int pixelSize = dxgiFormatSizeInfo.pixelBytes;
unsigned int copyOffset = 0; unsigned int copyOffset = 0;
unsigned int copySize = pixelSize; unsigned int copySize = pixelSize;
if (stencilOnly) if (stencilOnly)
...@@ -1073,105 +1221,109 @@ gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSu ...@@ -1073,105 +1221,109 @@ gl::Error Blit11::copyDepthStencil(ID3D11Resource *source, unsigned int sourceSu
copySize = 1; copySize = 1;
} }
return copyAndConvert(source, sourceSubresource, sourceArea, sourceSize, dest, destSubresource,
destArea, destSize, scissor, copyOffset, copyOffset, copySize, pixelSize,
pixelSize, StretchedBlitNearest);
}
gl::Error Blit11::copyAndConvert(const TextureHelper11 &source,
unsigned int sourceSubresource,
const gl::Box &sourceArea,
const gl::Extents &sourceSize,
const TextureHelper11 &dest,
unsigned int destSubresource,
const gl::Box &destArea,
const gl::Extents &destSize,
const gl::Rectangle *scissor,
size_t readOffset,
size_t writeOffset,
size_t copySize,
size_t srcPixelStride,
size_t destPixelStride,
BlitConvertFunction *convertFunction)
{
ANGLE_TRY(initResources());
ID3D11Device *device = mRenderer->getDevice();
ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
TextureHelper11 sourceStaging;
ANGLE_TRY_RESULT(CreateStagingTexture(GL_TEXTURE_2D, source.getANGLEFormat(), sourceSize,
StagingAccess::READ, device),
sourceStaging);
deviceContext->CopySubresourceRegion(sourceStaging.getResource(), 0, 0, 0, 0,
source.getResource(), sourceSubresource, nullptr);
// HACK: Create the destination staging buffer as a read/write texture so
// ID3D11DevicContext::UpdateSubresource can be called
// using it's mapped data as a source
TextureHelper11 destStaging;
ANGLE_TRY_RESULT(CreateStagingTexture(GL_TEXTURE_2D, dest.getANGLEFormat(), destSize,
StagingAccess::READ_WRITE, device),
destStaging);
deviceContext->CopySubresourceRegion(destStaging.getResource(), 0, 0, 0, 0, dest.getResource(),
destSubresource, nullptr);
D3D11_MAPPED_SUBRESOURCE sourceMapping; D3D11_MAPPED_SUBRESOURCE sourceMapping;
HRESULT result = deviceContext->Map(sourceStaging, 0, D3D11_MAP_READ, 0, &sourceMapping); HRESULT result =
deviceContext->Map(sourceStaging.getResource(), 0, D3D11_MAP_READ, 0, &sourceMapping);
if (FAILED(result)) if (FAILED(result))
{ {
SafeRelease(sourceStaging); return gl::Error(
SafeRelease(destStaging); GL_OUT_OF_MEMORY,
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal source staging texture for depth stencil blit, HRESULT: 0x%X.", result); "Failed to map internal source staging texture for depth stencil blit, HRESULT: 0x%X.",
result);
} }
D3D11_MAPPED_SUBRESOURCE destMapping; D3D11_MAPPED_SUBRESOURCE destMapping;
result = deviceContext->Map(destStaging, 0, D3D11_MAP_WRITE, 0, &destMapping); result = deviceContext->Map(destStaging.getResource(), 0, D3D11_MAP_WRITE, 0, &destMapping);
if (FAILED(result)) if (FAILED(result))
{ {
deviceContext->Unmap(sourceStaging, 0); deviceContext->Unmap(sourceStaging.getResource(), 0);
SafeRelease(sourceStaging); return gl::Error(GL_OUT_OF_MEMORY,
SafeRelease(destStaging); "Failed to map internal destination staging texture for depth stencil "
return gl::Error(GL_OUT_OF_MEMORY, "Failed to map internal destination staging texture for depth stencil blit, HRESULT: 0x%X.", result); "blit, HRESULT: 0x%X.",
result);
} }
gl::Rectangle clippedDestArea(destArea.x, destArea.y, destArea.width, destArea.height);
// Clip dest area to the destination size // Clip dest area to the destination size
gl::ClipRectangle(clippedDestArea, gl::Rectangle(0, 0, destSize.width, destSize.height), &clippedDestArea); gl::Rectangle clipRect = gl::Rectangle(0, 0, destSize.width, destSize.height);
// Clip dest area to the scissor // Clip dest area to the scissor
if (scissor) if (scissor)
{ {
gl::ClipRectangle(clippedDestArea, *scissor, &clippedDestArea); gl::ClipRectangle(clipRect, *scissor, &clipRect);
}
// Determine if entire rows can be copied at once instead of each individual pixel, requires that there is
// no out of bounds lookups required, the entire pixel is copied and no stretching
bool wholeRowCopy = sourceArea.width == clippedDestArea.width &&
sourceArea.x >= 0 && sourceArea.x + sourceArea.width <= sourceSize.width &&
copySize == pixelSize;
for (int y = clippedDestArea.y; y < clippedDestArea.y + clippedDestArea.height; y++)
{
float yPerc = static_cast<float>(y - destArea.y) / (destArea.height - 1);
// Interpolate using the original source rectangle to determine which row to sample from while clamping to the edges
unsigned int readRow = static_cast<unsigned int>(gl::clamp(sourceArea.y + floor(yPerc * (sourceArea.height - 1) + 0.5f), 0, sourceSize.height - 1));
unsigned int writeRow = y;
if (wholeRowCopy)
{
void *sourceRow = reinterpret_cast<char*>(sourceMapping.pData) +
readRow * sourceMapping.RowPitch +
sourceArea.x * pixelSize;
void *destRow = reinterpret_cast<char*>(destMapping.pData) +
writeRow * destMapping.RowPitch +
destArea.x * pixelSize;
memcpy(destRow, sourceRow, pixelSize * destArea.width);
} }
else
{
for (int x = clippedDestArea.x; x < clippedDestArea.x + clippedDestArea.width; x++)
{
float xPerc = static_cast<float>(x - destArea.x) / (destArea.width - 1);
// Interpolate the original source rectangle to determine which column to sample from while clamping to the edges
unsigned int readColumn = static_cast<unsigned int>(gl::clamp(sourceArea.x + floor(xPerc * (sourceArea.width - 1) + 0.5f), 0, sourceSize.width - 1));
unsigned int writeColumn = x;
void *sourcePixel = reinterpret_cast<char*>(sourceMapping.pData) +
readRow * sourceMapping.RowPitch +
readColumn * pixelSize +
copyOffset;
void *destPixel = reinterpret_cast<char*>(destMapping.pData) +
writeRow * destMapping.RowPitch +
writeColumn * pixelSize +
copyOffset;
memcpy(destPixel, sourcePixel, copySize); convertFunction(sourceArea, destArea, clipRect, sourceSize, sourceMapping.RowPitch,
} destMapping.RowPitch, readOffset, writeOffset, copySize, srcPixelStride,
} destPixelStride, static_cast<const uint8_t *>(sourceMapping.pData),
} static_cast<uint8_t *>(destMapping.pData));
// HACK: Use ID3D11DevicContext::UpdateSubresource which causes an extra copy compared to ID3D11DevicContext::CopySubresourceRegion // HACK: Use ID3D11DevicContext::UpdateSubresource which causes an extra copy compared to
// ID3D11DevicContext::CopySubresourceRegion
// according to MSDN. // according to MSDN.
deviceContext->UpdateSubresource(dest, destSubresource, nullptr, destMapping.pData, destMapping.RowPitch, destMapping.DepthPitch); deviceContext->UpdateSubresource(dest.getResource(), destSubresource, nullptr,
destMapping.pData, destMapping.RowPitch,
destMapping.DepthPitch);
deviceContext->Unmap(sourceStaging, 0); deviceContext->Unmap(sourceStaging.getResource(), 0);
deviceContext->Unmap(destStaging, 0); deviceContext->Unmap(destStaging.getResource(), 0);
// TODO: Determine why this call to ID3D11DevicContext::CopySubresourceRegion causes a TDR timeout on some // TODO: Determine why this call to ID3D11DevicContext::CopySubresourceRegion causes a TDR
// timeout on some
// systems when called repeatedly. // systems when called repeatedly.
// deviceContext->CopySubresourceRegion(dest, destSubresource, 0, 0, 0, destStaging, 0, nullptr); // deviceContext->CopySubresourceRegion(dest, destSubresource, 0, 0, 0, destStaging, 0,
// nullptr);
SafeRelease(sourceStaging);
SafeRelease(destStaging);
return gl::Error(GL_NO_ERROR); return gl::NoError();
} }
void Blit11::addBlitShaderToMap(BlitShaderType blitShaderType, ShaderDimension dimension, ID3D11PixelShader *ps) void Blit11::addBlitShaderToMap(BlitShaderType blitShaderType,
ShaderDimension dimension,
ID3D11PixelShader *ps)
{ {
ASSERT(mBlitShaderMap.find(blitShaderType) == mBlitShaderMap.end()); ASSERT(mBlitShaderMap.find(blitShaderType) == mBlitShaderMap.end());
ASSERT(ps); ASSERT(ps);
...@@ -1183,7 +1335,9 @@ void Blit11::addBlitShaderToMap(BlitShaderType blitShaderType, ShaderDimension d ...@@ -1183,7 +1335,9 @@ void Blit11::addBlitShaderToMap(BlitShaderType blitShaderType, ShaderDimension d
mBlitShaderMap[blitShaderType] = shader; mBlitShaderMap[blitShaderType] = shader;
} }
void Blit11::addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType, ShaderDimension dimension, ID3D11PixelShader *ps) void Blit11::addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType,
ShaderDimension dimension,
ID3D11PixelShader *ps)
{ {
ASSERT(mSwizzleShaderMap.find(swizzleShaderType) == mSwizzleShaderMap.end()); ASSERT(mSwizzleShaderMap.find(swizzleShaderType) == mSwizzleShaderMap.end());
ASSERT(ps); ASSERT(ps);
...@@ -1210,7 +1364,10 @@ void Blit11::clearShaderMap() ...@@ -1210,7 +1364,10 @@ void Blit11::clearShaderMap()
mSwizzleShaderMap.clear(); mSwizzleShaderMap.clear();
} }
gl::Error Blit11::getBlitShader(GLenum destFormat, bool isSigned, ShaderDimension dimension, const Shader **shader) gl::Error Blit11::getBlitShader(GLenum destFormat,
bool isSigned,
ShaderDimension dimension,
const Shader **shader)
{ {
BlitShaderType blitShaderType = GetBlitShaderType(destFormat, isSigned, dimension); BlitShaderType blitShaderType = GetBlitShaderType(destFormat, isSigned, dimension);
...@@ -1233,100 +1390,164 @@ gl::Error Blit11::getBlitShader(GLenum destFormat, bool isSigned, ShaderDimensio ...@@ -1233,100 +1390,164 @@ gl::Error Blit11::getBlitShader(GLenum destFormat, bool isSigned, ShaderDimensio
switch (blitShaderType) switch (blitShaderType)
{ {
case BLITSHADER_2D_RGBAF: case BLITSHADER_2D_RGBAF:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D RGBA pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D RGBA pixel shader"));
break; break;
case BLITSHADER_2D_BGRAF: case BLITSHADER_2D_BGRAF:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D BGRA pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D BGRA pixel shader"));
break; break;
case BLITSHADER_2D_RGBF: case BLITSHADER_2D_RGBF:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGB2D, "Blit11 2D RGB pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughRGB2D, "Blit11 2D RGB pixel shader"));
break; break;
case BLITSHADER_2D_RGF: case BLITSHADER_2D_RGF:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRG2D, "Blit11 2D RG pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughRG2D, "Blit11 2D RG pixel shader"));
break; break;
case BLITSHADER_2D_RF: case BLITSHADER_2D_RF:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughR2D, "Blit11 2D R pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughR2D, "Blit11 2D R pixel shader"));
break; break;
case BLITSHADER_2D_ALPHA: case BLITSHADER_2D_ALPHA:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D alpha pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughRGBA2D, "Blit11 2D alpha pixel shader"));
break; break;
case BLITSHADER_2D_LUMA: case BLITSHADER_2D_LUMA:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughLum2D, "Blit11 2D lum pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughLum2D, "Blit11 2D lum pixel shader"));
break; break;
case BLITSHADER_2D_LUMAALPHA: case BLITSHADER_2D_LUMAALPHA:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha2D, "Blit11 2D luminance alpha pixel shader")); addBlitShaderToMap(blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughLumAlpha2D,
"Blit11 2D luminance alpha pixel shader"));
break; break;
case BLITSHADER_2D_RGBAUI: case BLITSHADER_2D_RGBAUI:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DUI, "Blit11 2D RGBA UI pixel shader")); addBlitShaderToMap(blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughRGBA2DUI,
"Blit11 2D RGBA UI pixel shader"));
break; break;
case BLITSHADER_2D_RGBAI: case BLITSHADER_2D_RGBAI:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGBA2DI, "Blit11 2D RGBA I pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughRGBA2DI, "Blit11 2D RGBA I pixel shader"));
break; break;
case BLITSHADER_2D_RGBUI: case BLITSHADER_2D_RGBUI:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGB2DUI, "Blit11 2D RGB UI pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughRGB2DUI, "Blit11 2D RGB UI pixel shader"));
break; break;
case BLITSHADER_2D_RGBI: case BLITSHADER_2D_RGBI:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRGB2DI, "Blit11 2D RGB I pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughRGB2DI, "Blit11 2D RGB I pixel shader"));
break; break;
case BLITSHADER_2D_RGUI: case BLITSHADER_2D_RGUI:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRG2DUI, "Blit11 2D RG UI pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughRG2DUI, "Blit11 2D RG UI pixel shader"));
break; break;
case BLITSHADER_2D_RGI: case BLITSHADER_2D_RGI:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughRG2DI, "Blit11 2D RG I pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughRG2DI, "Blit11 2D RG I pixel shader"));
break; break;
case BLITSHADER_2D_RUI: case BLITSHADER_2D_RUI:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughR2DUI, "Blit11 2D R UI pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughR2DUI, "Blit11 2D R UI pixel shader"));
break; break;
case BLITSHADER_2D_RI: case BLITSHADER_2D_RI:
addBlitShaderToMap(blitShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_PassthroughR2DI, "Blit11 2D R I pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_PassthroughR2DI, "Blit11 2D R I pixel shader"));
break; break;
case BLITSHADER_3D_RGBAF: case BLITSHADER_3D_RGBAF:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D RGBA pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D RGBA pixel shader"));
break; break;
case BLITSHADER_3D_RGBAUI: case BLITSHADER_3D_RGBAUI:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DUI, "Blit11 3D UI RGBA pixel shader")); addBlitShaderToMap(blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughRGBA3DUI,
"Blit11 3D UI RGBA pixel shader"));
break; break;
case BLITSHADER_3D_RGBAI: case BLITSHADER_3D_RGBAI:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughRGBA3DI, "Blit11 3D I RGBA pixel shader"));
break; break;
case BLITSHADER_3D_BGRAF: case BLITSHADER_3D_BGRAF:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D BGRA pixel shader"));
break; break;
case BLITSHADER_3D_RGBF: case BLITSHADER_3D_RGBF:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughRGB3D, "Blit11 3D RGB pixel shader"));
break; break;
case BLITSHADER_3D_RGBUI: case BLITSHADER_3D_RGBUI:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughRGB3DUI, "Blit11 3D RGB UI pixel shader"));
break; break;
case BLITSHADER_3D_RGBI: case BLITSHADER_3D_RGBI:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughRGB3DI, "Blit11 3D RGB I pixel shader"));
break; break;
case BLITSHADER_3D_RGF: case BLITSHADER_3D_RGF:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughRG3D, "Blit11 3D RG pixel shader"));
break; break;
case BLITSHADER_3D_RGUI: case BLITSHADER_3D_RGUI:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughRG3DUI, "Blit11 3D RG UI pixel shader"));
break; break;
case BLITSHADER_3D_RGI: case BLITSHADER_3D_RGI:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughRG3DI, "Blit11 3D RG I pixel shader"));
break; break;
case BLITSHADER_3D_RF: case BLITSHADER_3D_RF:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughR3D, "Blit11 3D R pixel shader"));
break; break;
case BLITSHADER_3D_RUI: case BLITSHADER_3D_RUI:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughR3DUI, "Blit11 3D R UI pixel shader"));
break; break;
case BLITSHADER_3D_RI: case BLITSHADER_3D_RI:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughR3DI, "Blit11 3D R I pixel shader"));
break; break;
case BLITSHADER_3D_ALPHA: case BLITSHADER_3D_ALPHA:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader")); addBlitShaderToMap(
blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughRGBA3D, "Blit11 3D alpha pixel shader"));
break; break;
case BLITSHADER_3D_LUMA: case BLITSHADER_3D_LUMA:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughLum3D, "Blit11 3D luminance pixel shader")); addBlitShaderToMap(blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughLum3D,
"Blit11 3D luminance pixel shader"));
break; break;
case BLITSHADER_3D_LUMAALPHA: case BLITSHADER_3D_LUMAALPHA:
addBlitShaderToMap(blitShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_PassthroughLumAlpha3D, "Blit11 3D luminance alpha pixel shader")); addBlitShaderToMap(blitShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_PassthroughLumAlpha3D,
"Blit11 3D luminance alpha pixel shader"));
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -1339,7 +1560,9 @@ gl::Error Blit11::getBlitShader(GLenum destFormat, bool isSigned, ShaderDimensio ...@@ -1339,7 +1560,9 @@ gl::Error Blit11::getBlitShader(GLenum destFormat, bool isSigned, ShaderDimensio
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
gl::Error Blit11::getSwizzleShader(GLenum type, D3D11_SRV_DIMENSION viewDimension, const Shader **shader) gl::Error Blit11::getSwizzleShader(GLenum type,
D3D11_SRV_DIMENSION viewDimension,
const Shader **shader)
{ {
SwizzleShaderType swizzleShaderType = GetSwizzleShaderType(type, viewDimension); SwizzleShaderType swizzleShaderType = GetSwizzleShaderType(type, viewDimension);
...@@ -1363,40 +1586,64 @@ gl::Error Blit11::getSwizzleShader(GLenum type, D3D11_SRV_DIMENSION viewDimensio ...@@ -1363,40 +1586,64 @@ gl::Error Blit11::getSwizzleShader(GLenum type, D3D11_SRV_DIMENSION viewDimensio
switch (swizzleShaderType) switch (swizzleShaderType)
{ {
case SWIZZLESHADER_2D_FLOAT: case SWIZZLESHADER_2D_FLOAT:
addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_SwizzleF2D, "Blit11 2D F swizzle pixel shader")); addSwizzleShaderToMap(
swizzleShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_SwizzleF2D, "Blit11 2D F swizzle pixel shader"));
break; break;
case SWIZZLESHADER_2D_UINT: case SWIZZLESHADER_2D_UINT:
addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_SwizzleUI2D, "Blit11 2D UI swizzle pixel shader")); addSwizzleShaderToMap(
swizzleShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_SwizzleUI2D, "Blit11 2D UI swizzle pixel shader"));
break; break;
case SWIZZLESHADER_2D_INT: case SWIZZLESHADER_2D_INT:
addSwizzleShaderToMap(swizzleShaderType, SHADER_2D, d3d11::CompilePS(device, g_PS_SwizzleI2D, "Blit11 2D I swizzle pixel shader")); addSwizzleShaderToMap(
swizzleShaderType, SHADER_2D,
d3d11::CompilePS(device, g_PS_SwizzleI2D, "Blit11 2D I swizzle pixel shader"));
break; break;
case SWIZZLESHADER_CUBE_FLOAT: case SWIZZLESHADER_CUBE_FLOAT:
addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Cube F swizzle pixel shader")); addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_SwizzleF2DArray,
"Blit11 2D Cube F swizzle pixel shader"));
break; break;
case SWIZZLESHADER_CUBE_UINT: case SWIZZLESHADER_CUBE_UINT:
addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Cube UI swizzle pixel shader")); addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_SwizzleUI2DArray,
"Blit11 2D Cube UI swizzle pixel shader"));
break; break;
case SWIZZLESHADER_CUBE_INT: case SWIZZLESHADER_CUBE_INT:
addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Cube I swizzle pixel shader")); addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_SwizzleI2DArray,
"Blit11 2D Cube I swizzle pixel shader"));
break; break;
case SWIZZLESHADER_3D_FLOAT: case SWIZZLESHADER_3D_FLOAT:
addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleF3D, "Blit11 3D F swizzle pixel shader")); addSwizzleShaderToMap(
swizzleShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_SwizzleF3D, "Blit11 3D F swizzle pixel shader"));
break; break;
case SWIZZLESHADER_3D_UINT: case SWIZZLESHADER_3D_UINT:
addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleUI3D, "Blit11 3D UI swizzle pixel shader")); addSwizzleShaderToMap(
swizzleShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_SwizzleUI3D, "Blit11 3D UI swizzle pixel shader"));
break; break;
case SWIZZLESHADER_3D_INT: case SWIZZLESHADER_3D_INT:
addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleI3D, "Blit11 3D I swizzle pixel shader")); addSwizzleShaderToMap(
swizzleShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_SwizzleI3D, "Blit11 3D I swizzle pixel shader"));
break; break;
case SWIZZLESHADER_ARRAY_FLOAT: case SWIZZLESHADER_ARRAY_FLOAT:
addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleF2DArray, "Blit11 2D Array F swizzle pixel shader")); addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_SwizzleF2DArray,
"Blit11 2D Array F swizzle pixel shader"));
break; break;
case SWIZZLESHADER_ARRAY_UINT: case SWIZZLESHADER_ARRAY_UINT:
addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleUI2DArray, "Blit11 2D Array UI swizzle pixel shader")); addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_SwizzleUI2DArray,
"Blit11 2D Array UI swizzle pixel shader"));
break; break;
case SWIZZLESHADER_ARRAY_INT: case SWIZZLESHADER_ARRAY_INT:
addSwizzleShaderToMap(swizzleShaderType, SHADER_3D, d3d11::CompilePS(device, g_PS_SwizzleI2DArray, "Blit11 2D Array I swizzle pixel shader")); addSwizzleShaderToMap(swizzleShaderType, SHADER_3D,
d3d11::CompilePS(device, g_PS_SwizzleI2DArray,
"Blit11 2D Array I swizzle pixel shader"));
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -1406,7 +1653,16 @@ gl::Error Blit11::getSwizzleShader(GLenum type, D3D11_SRV_DIMENSION viewDimensio ...@@ -1406,7 +1653,16 @@ gl::Error Blit11::getSwizzleShader(GLenum type, D3D11_SRV_DIMENSION viewDimensio
swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType); swizzleShaderIt = mSwizzleShaderMap.find(swizzleShaderType);
ASSERT(swizzleShaderIt != mSwizzleShaderMap.end()); ASSERT(swizzleShaderIt != mSwizzleShaderMap.end());
*shader = &swizzleShaderIt->second; *shader = &swizzleShaderIt->second;
return gl::Error(GL_NO_ERROR); return gl::NoError();
} }
gl::ErrorOrResult<TextureHelper11> Blit11::resolveDepthStencil(RenderTarget11 *dsRenderTarget,
bool resolveDepth,
bool resolveStencil)
{
ASSERT(resolveDepth || resolveStencil);
UNIMPLEMENTED();
return gl::Error(GL_INVALID_OPERATION,
"Multisample depth stencil resolve not implemented yet.");
} }
} // namespace rx
...@@ -42,18 +42,38 @@ class Blit11 : angle::NonCopyable ...@@ -42,18 +42,38 @@ class Blit11 : angle::NonCopyable
GLenum filter, GLenum filter,
bool maskOffAlpha); bool maskOffAlpha);
gl::Error copyStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, gl::Error copyStencil(const TextureHelper11 &source,
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, unsigned int sourceSubresource,
const gl::Box &sourceArea,
const gl::Extents &sourceSize,
const TextureHelper11 &dest,
unsigned int destSubresource,
const gl::Box &destArea,
const gl::Extents &destSize,
const gl::Rectangle *scissor); const gl::Rectangle *scissor);
gl::Error copyDepth(ID3D11ShaderResourceView *source, const gl::Box &sourceArea, const gl::Extents &sourceSize, gl::Error copyDepth(ID3D11ShaderResourceView *source,
ID3D11DepthStencilView *dest, const gl::Box &destArea, const gl::Extents &destSize, const gl::Box &sourceArea,
const gl::Extents &sourceSize,
ID3D11DepthStencilView *dest,
const gl::Box &destArea,
const gl::Extents &destSize,
const gl::Rectangle *scissor); const gl::Rectangle *scissor);
gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, gl::Error copyDepthStencil(const TextureHelper11 &source,
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, unsigned int sourceSubresource,
const gl::Box &sourceArea,
const gl::Extents &sourceSize,
const TextureHelper11 &dest,
unsigned int destSubresource,
const gl::Box &destArea,
const gl::Extents &destSize,
const gl::Rectangle *scissor); const gl::Rectangle *scissor);
gl::ErrorOrResult<TextureHelper11> resolveDepthStencil(RenderTarget11 *dsRenderTarget,
bool resolveDepth,
bool resolveStencil);
private: private:
enum BlitShaderType enum BlitShaderType
{ {
...@@ -109,9 +129,13 @@ class Blit11 : angle::NonCopyable ...@@ -109,9 +129,13 @@ class Blit11 : angle::NonCopyable
SWIZZLESHADER_ARRAY_INT, SWIZZLESHADER_ARRAY_INT,
}; };
typedef void (*WriteVertexFunction)(const gl::Box &sourceArea, const gl::Extents &sourceSize, typedef void (*WriteVertexFunction)(const gl::Box &sourceArea,
const gl::Box &destArea, const gl::Extents &destSize, const gl::Extents &sourceSize,
void *outVertices, unsigned int *outStride, unsigned int *outVertexCount, const gl::Box &destArea,
const gl::Extents &destSize,
void *outVertices,
unsigned int *outStride,
unsigned int *outVertexCount,
D3D11_PRIMITIVE_TOPOLOGY *outTopology); D3D11_PRIMITIVE_TOPOLOGY *outTopology);
enum ShaderDimension enum ShaderDimension
...@@ -139,19 +163,67 @@ class Blit11 : angle::NonCopyable ...@@ -139,19 +163,67 @@ class Blit11 : angle::NonCopyable
ShaderSupport getShaderSupport(const Shader &shader); ShaderSupport getShaderSupport(const Shader &shader);
static BlitShaderType GetBlitShaderType(GLenum destinationFormat, bool isSigned, ShaderDimension dimension); static BlitShaderType GetBlitShaderType(GLenum destinationFormat,
bool isSigned,
ShaderDimension dimension);
static SwizzleShaderType GetSwizzleShaderType(GLenum type, D3D11_SRV_DIMENSION dimensionality); static SwizzleShaderType GetSwizzleShaderType(GLenum type, D3D11_SRV_DIMENSION dimensionality);
gl::Error copyDepthStencil(ID3D11Resource *source, unsigned int sourceSubresource, const gl::Box &sourceArea, const gl::Extents &sourceSize, typedef void BlitConvertFunction(const gl::Box &sourceArea,
ID3D11Resource *dest, unsigned int destSubresource, const gl::Box &destArea, const gl::Extents &destSize, const gl::Box &destArea,
const gl::Rectangle *scissor, bool stencilOnly); const gl::Rectangle &clipRect,
const gl::Extents &sourceSize,
void addBlitShaderToMap(BlitShaderType blitShaderType, ShaderDimension dimension, ID3D11PixelShader *ps); unsigned int sourceRowPitch,
unsigned int destRowPitch,
gl::Error getBlitShader(GLenum destFormat, bool isSigned, ShaderDimension dimension, const Shader **shaderOut); ptrdiff_t readOffset,
gl::Error getSwizzleShader(GLenum type, D3D11_SRV_DIMENSION viewDimension, const Shader **shaderOut); ptrdiff_t writeOffset,
size_t copySize,
size_t srcPixelStride,
size_t destPixelStride,
const uint8_t *sourceData,
uint8_t *destData);
gl::Error copyDepthStencilImpl(const TextureHelper11 &source,
unsigned int sourceSubresource,
const gl::Box &sourceArea,
const gl::Extents &sourceSize,
const TextureHelper11 &dest,
unsigned int destSubresource,
const gl::Box &destArea,
const gl::Extents &destSize,
const gl::Rectangle *scissor,
bool stencilOnly);
void addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType, ShaderDimension dimension, ID3D11PixelShader *ps); gl::Error copyAndConvert(const TextureHelper11 &source,
unsigned int sourceSubresource,
const gl::Box &sourceArea,
const gl::Extents &sourceSize,
const TextureHelper11 &dest,
unsigned int destSubresource,
const gl::Box &destArea,
const gl::Extents &destSize,
const gl::Rectangle *scissor,
size_t readOffset,
size_t writeOffset,
size_t copySize,
size_t srcPixelStride,
size_t destPixelStride,
BlitConvertFunction *convertFunction);
void addBlitShaderToMap(BlitShaderType blitShaderType,
ShaderDimension dimension,
ID3D11PixelShader *ps);
gl::Error getBlitShader(GLenum destFormat,
bool isSigned,
ShaderDimension dimension,
const Shader **shaderOut);
gl::Error getSwizzleShader(GLenum type,
D3D11_SRV_DIMENSION viewDimension,
const Shader **shaderOut);
void addSwizzleShaderToMap(SwizzleShaderType swizzleShaderType,
ShaderDimension dimension,
ID3D11PixelShader *ps);
void clearShaderMap(); void clearShaderMap();
...@@ -181,6 +253,6 @@ class Blit11 : angle::NonCopyable ...@@ -181,6 +253,6 @@ class Blit11 : angle::NonCopyable
ID3D11Buffer *mSwizzleCB; ID3D11Buffer *mSwizzleCB;
}; };
} } // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_ #endif // LIBANGLE_RENDERER_D3D_D3D11_BLIT11_H_
...@@ -1332,9 +1332,9 @@ gl::Error Buffer11::PackStorage::packPixels(const gl::FramebufferAttachment &rea ...@@ -1332,9 +1332,9 @@ gl::Error Buffer11::PackStorage::packPixels(const gl::FramebufferAttachment &rea
if (!mStagingTexture.getResource() || mStagingTexture.getFormat() != srcTexture.getFormat() || if (!mStagingTexture.getResource() || mStagingTexture.getFormat() != srcTexture.getFormat() ||
mStagingTexture.getExtents() != srcTextureSize) mStagingTexture.getExtents() != srcTextureSize)
{ {
ANGLE_TRY_RESULT(CreateStagingTexture(srcTexture.getTextureType(), srcTexture.getFormat(), ANGLE_TRY_RESULT(
srcTexture.getANGLEFormat(), srcTextureSize, CreateStagingTexture(srcTexture.getTextureType(), srcTexture.getANGLEFormat(),
mRenderer->getDevice()), srcTextureSize, StagingAccess::READ, mRenderer->getDevice()),
mStagingTexture); mStagingTexture);
} }
......
...@@ -3587,11 +3587,7 @@ gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAtt ...@@ -3587,11 +3587,7 @@ gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAtt
const bool invertTexture = UsePresentPathFast(this, &srcAttachment); const bool invertTexture = UsePresentPathFast(this, &srcAttachment);
RenderTargetD3D *renderTarget = nullptr; RenderTargetD3D *renderTarget = nullptr;
gl::Error error = srcAttachment.getRenderTarget(&renderTarget); ANGLE_TRY(srcAttachment.getRenderTarget(&renderTarget));
if (error.isError())
{
return error;
}
RenderTarget11 *rt11 = GetAs<RenderTarget11>(renderTarget); RenderTarget11 *rt11 = GetAs<RenderTarget11>(renderTarget);
ASSERT(rt11->getTexture()); ASSERT(rt11->getTexture());
...@@ -3625,19 +3621,16 @@ gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAtt ...@@ -3625,19 +3621,16 @@ gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAtt
if (safeArea.width == 0 || safeArea.height == 0) if (safeArea.width == 0 || safeArea.height == 0)
{ {
// no work to do // no work to do
return gl::Error(GL_NO_ERROR); return gl::NoError();
} }
gl::Extents safeSize(safeArea.width, safeArea.height, 1); gl::Extents safeSize(safeArea.width, safeArea.height, 1);
auto errorOrResult = TextureHelper11 stagingHelper;
CreateStagingTexture(textureHelper.getTextureType(), textureHelper.getFormat(), ANGLE_TRY_RESULT(
textureHelper.getANGLEFormat(), safeSize, mDevice); CreateStagingTexture(textureHelper.getTextureType(), textureHelper.getANGLEFormat(),
if (errorOrResult.isError()) safeSize, StagingAccess::READ, mDevice),
{ stagingHelper);
return errorOrResult.getError();
}
TextureHelper11 stagingHelper(errorOrResult.getResult());
TextureHelper11 resolvedTextureHelper; TextureHelper11 resolvedTextureHelper;
// "srcTexture" usually points to the source texture. // "srcTexture" usually points to the source texture.
...@@ -3695,8 +3688,12 @@ gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAtt ...@@ -3695,8 +3688,12 @@ gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAtt
mDeviceContext->CopySubresourceRegion(stagingHelper.getResource(), 0, 0, 0, 0, mDeviceContext->CopySubresourceRegion(stagingHelper.getResource(), 0, 0, 0, 0,
srcTexture->getResource(), sourceSubResource, &srcBox); srcTexture->getResource(), sourceSubResource, &srcBox);
if (invertTexture) if (!invertTexture)
{ {
PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0);
return packPixels(stagingHelper, packParams, pixelsOut);
}
gl::PixelPackState invertTexturePack; gl::PixelPackState invertTexturePack;
// Create a new PixelPackState with reversed row order. Note that we can't just assign // Create a new PixelPackState with reversed row order. Note that we can't just assign
...@@ -3708,17 +3705,10 @@ gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAtt ...@@ -3708,17 +3705,10 @@ gl::Error Renderer11::readFromAttachment(const gl::FramebufferAttachment &srcAtt
invertTexturePack.reverseRowOrder = !pack.reverseRowOrder; invertTexturePack.reverseRowOrder = !pack.reverseRowOrder;
PackPixelsParams packParams(safeArea, format, type, outputPitch, invertTexturePack, 0); PackPixelsParams packParams(safeArea, format, type, outputPitch, invertTexturePack, 0);
error = packPixels(stagingHelper, packParams, pixelsOut); gl::Error error = packPixels(stagingHelper, packParams, pixelsOut);
invertTexturePack.pixelBuffer.set(nullptr); invertTexturePack.pixelBuffer.set(nullptr);
ANGLE_TRY(error);
return error; return gl::NoError();
}
else
{
PackPixelsParams packParams(safeArea, format, type, outputPitch, pack, 0);
return packPixels(stagingHelper, packParams, pixelsOut);
}
} }
gl::Error Renderer11::packPixels(const TextureHelper11 &textureHelper, gl::Error Renderer11::packPixels(const TextureHelper11 &textureHelper,
...@@ -3768,49 +3758,53 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, ...@@ -3768,49 +3758,53 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn,
ASSERT(colorBlit != (depthBlit || stencilBlit)); ASSERT(colorBlit != (depthBlit || stencilBlit));
RenderTarget11 *drawRenderTarget11 = GetAs<RenderTarget11>(drawRenderTarget); RenderTarget11 *drawRenderTarget11 = GetAs<RenderTarget11>(drawRenderTarget);
if (!drawRenderTarget) if (!drawRenderTarget11)
{ {
return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal draw render target from the draw framebuffer."); return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal draw render target from the draw framebuffer.");
} }
ID3D11Resource *drawTexture = drawRenderTarget11->getTexture(); TextureHelper11 drawTexture = TextureHelper11::MakeAndReference(
drawRenderTarget11->getTexture(), drawRenderTarget11->getANGLEFormat());
unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex(); unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex();
ID3D11RenderTargetView *drawRTV = drawRenderTarget11->getRenderTargetView(); ID3D11RenderTargetView *drawRTV = drawRenderTarget11->getRenderTargetView();
ID3D11DepthStencilView *drawDSV = drawRenderTarget11->getDepthStencilView(); ID3D11DepthStencilView *drawDSV = drawRenderTarget11->getDepthStencilView();
RenderTarget11 *readRenderTarget11 = GetAs<RenderTarget11>(readRenderTarget); RenderTarget11 *readRenderTarget11 = GetAs<RenderTarget11>(readRenderTarget);
if (!readRenderTarget) if (!readRenderTarget11)
{ {
return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target from the read framebuffer."); return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target from the read framebuffer.");
} }
ID3D11Resource *readTexture = NULL; TextureHelper11 readTexture;
ID3D11ShaderResourceView *readSRV = NULL;
unsigned int readSubresource = 0; unsigned int readSubresource = 0;
if (readRenderTarget->getSamples() > 0) ID3D11ShaderResourceView *readSRV = nullptr;
{
ID3D11Resource *unresolvedResource = readRenderTarget11->getTexture();
ID3D11Texture2D *unresolvedTexture = d3d11::DynamicCastComObject<ID3D11Texture2D>(unresolvedResource);
if (unresolvedTexture) if (readRenderTarget->getSamples() > 1)
{ {
readTexture = resolveMultisampledTexture(unresolvedTexture, readRenderTarget11->getSubresourceIndex()); auto readRT11 = GetAs<RenderTarget11>(readRenderTarget);
readSubresource = 0; ANGLE_TRY_RESULT(resolveMultisampledTexture(readRT11, depthBlit, stencilBlit), readTexture);
SafeRelease(unresolvedTexture); const auto &formatSet = d3d11::GetANGLEFormatSet(readTexture.getANGLEFormat());
HRESULT hresult = mDevice->CreateShaderResourceView(readTexture, NULL, &readSRV); D3D11_SHADER_RESOURCE_VIEW_DESC srViewDesc;
srViewDesc.Format = formatSet.srvFormat;
srViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srViewDesc.Texture2D.MipLevels = 1;
srViewDesc.Texture2D.MostDetailedMip = 0;
HRESULT hresult =
mDevice->CreateShaderResourceView(readTexture.getResource(), &srViewDesc, &readSRV);
if (FAILED(hresult)) if (FAILED(hresult))
{ {
SafeRelease(readTexture); return gl::Error(GL_OUT_OF_MEMORY,
return gl::Error(GL_OUT_OF_MEMORY, "Failed to create shader resource view to resolve multisampled framebuffer."); "Renderer11::blitRenderbufferRect: Failed to create temporary SRV.");
}
} }
} }
else else
{ {
readTexture = readRenderTarget11->getTexture(); ASSERT(readRenderTarget11);
readTexture->AddRef(); readTexture = TextureHelper11::MakeAndReference(readRenderTarget11->getTexture(),
readRenderTarget11->getANGLEFormat());
readSubresource = readRenderTarget11->getSubresourceIndex(); readSubresource = readRenderTarget11->getSubresourceIndex();
readSRV = readRenderTarget11->getBlitShaderResourceView(); readSRV = readRenderTarget11->getBlitShaderResourceView();
if (readSRV == nullptr) if (readSRV == nullptr)
...@@ -3818,18 +3812,17 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, ...@@ -3818,18 +3812,17 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn,
ASSERT(depthBlit || stencilBlit); ASSERT(depthBlit || stencilBlit);
readSRV = readRenderTarget11->getShaderResourceView(); readSRV = readRenderTarget11->getShaderResourceView();
} }
ASSERT(readSRV);
readSRV->AddRef(); readSRV->AddRef();
} }
if (!readTexture || !readSRV) if (!readSRV)
{ {
SafeRelease(readTexture);
SafeRelease(readSRV);
return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target view from the read render target."); return gl::Error(GL_OUT_OF_MEMORY, "Failed to retrieve the internal read render target view from the read render target.");
} }
gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1); const gl::Extents readSize(readRenderTarget->getWidth(), readRenderTarget->getHeight(), 1);
gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1); const gl::Extents drawSize(drawRenderTarget->getWidth(), drawRenderTarget->getHeight(), 1);
// From the spec: // From the spec:
// "The actual region taken from the read framebuffer is limited to the intersection of the // "The actual region taken from the read framebuffer is limited to the intersection of the
...@@ -3891,7 +3884,7 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, ...@@ -3891,7 +3884,7 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn,
drawRect.height += drawOffset; drawRect.height += drawOffset;
} }
bool scissorNeeded = scissor && gl::ClipRectangle(drawRect, *scissor, NULL); bool scissorNeeded = scissor && gl::ClipRectangle(drawRect, *scissor, nullptr);
const auto &destFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getInternalFormat()); const auto &destFormatInfo = gl::GetInternalFormatInfo(drawRenderTarget->getInternalFormat());
const auto &srcFormatInfo = gl::GetInternalFormatInfo(readRenderTarget->getInternalFormat()); const auto &srcFormatInfo = gl::GetInternalFormatInfo(readRenderTarget->getInternalFormat());
...@@ -3933,8 +3926,6 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, ...@@ -3933,8 +3926,6 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn,
bool partialDSBlit = (dxgiFormatInfo.depthBits > 0 && depthBlit) != (dxgiFormatInfo.stencilBits > 0 && stencilBlit); bool partialDSBlit = (dxgiFormatInfo.depthBits > 0 && depthBlit) != (dxgiFormatInfo.stencilBits > 0 && stencilBlit);
gl::Error result(GL_NO_ERROR);
if (readRenderTarget11->getANGLEFormat() == drawRenderTarget11->getANGLEFormat() && if (readRenderTarget11->getANGLEFormat() == drawRenderTarget11->getANGLEFormat() &&
!stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit && !stretchRequired && !outOfBounds && !flipRequired && !partialDSBlit &&
!colorMaskingNeeded && (!(depthBlit || stencilBlit) || wholeBufferCopy)) !colorMaskingNeeded && (!(depthBlit || stencilBlit) || wholeBufferCopy))
...@@ -3977,11 +3968,11 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, ...@@ -3977,11 +3968,11 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn,
// D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox
// We also require complete framebuffer copies for depth-stencil blit. // We also require complete framebuffer copies for depth-stencil blit.
D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox; D3D11_BOX *pSrcBox = wholeBufferCopy ? nullptr : &readBox;
mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, dstX, dstY, 0, mDeviceContext->CopySubresourceRegion(drawTexture.getResource(), drawSubresource, dstX,
readTexture, readSubresource, pSrcBox); dstY, 0, readTexture.getResource(), readSubresource,
result = gl::Error(GL_NO_ERROR); pSrcBox);
} }
else else
{ {
...@@ -3990,34 +3981,33 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn, ...@@ -3990,34 +3981,33 @@ gl::Error Renderer11::blitRenderbufferRect(const gl::Rectangle &readRectIn,
if (depthBlit && stencilBlit) if (depthBlit && stencilBlit)
{ {
result = mBlit->copyDepthStencil(readTexture, readSubresource, readArea, readSize, ANGLE_TRY(mBlit->copyDepthStencil(readTexture, readSubresource, readArea, readSize,
drawTexture, drawSubresource, drawArea, drawSize, drawTexture, drawSubresource, drawArea, drawSize,
scissor); scissor));
} }
else if (depthBlit) else if (depthBlit)
{ {
result = mBlit->copyDepth(readSRV, readArea, readSize, drawDSV, drawArea, drawSize, ANGLE_TRY(mBlit->copyDepth(readSRV, readArea, readSize, drawDSV, drawArea, drawSize,
scissor); scissor));
} }
else if (stencilBlit) else if (stencilBlit)
{ {
result = mBlit->copyStencil(readTexture, readSubresource, readArea, readSize, ANGLE_TRY(mBlit->copyStencil(readTexture, readSubresource, readArea, readSize,
drawTexture, drawSubresource, drawArea, drawSize, drawTexture, drawSubresource, drawArea, drawSize,
scissor); scissor));
} }
else else
{ {
// We don't currently support masking off any other channel than alpha // We don't currently support masking off any other channel than alpha
bool maskOffAlpha = colorMaskingNeeded && colorMask.alpha; bool maskOffAlpha = colorMaskingNeeded && colorMask.alpha;
result = mBlit->copyTexture(readSRV, readArea, readSize, drawRTV, drawArea, drawSize, ANGLE_TRY(mBlit->copyTexture(readSRV, readArea, readSize, drawRTV, drawArea, drawSize,
scissor, destFormatInfo.format, filter, maskOffAlpha); scissor, destFormatInfo.format, filter, maskOffAlpha));
} }
} }
SafeRelease(readTexture);
SafeRelease(readSRV); SafeRelease(readSRV);
return result; return gl::NoError();
} }
bool Renderer11::isES3Capable() const bool Renderer11::isES3Capable() const
...@@ -4065,42 +4055,42 @@ void Renderer11::onBufferDelete(const Buffer11 *deleted) ...@@ -4065,42 +4055,42 @@ void Renderer11::onBufferDelete(const Buffer11 *deleted)
mAliveBuffers.erase(deleted); mAliveBuffers.erase(deleted);
} }
ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource) gl::ErrorOrResult<TextureHelper11>
Renderer11::resolveMultisampledTexture(RenderTarget11 *renderTarget, bool depth, bool stencil)
{ {
D3D11_TEXTURE2D_DESC textureDesc; if (depth || stencil)
source->GetDesc(&textureDesc);
if (textureDesc.SampleDesc.Count > 1)
{ {
return mBlit->resolveDepthStencil(renderTarget, depth, stencil);
}
const auto &formatSet = d3d11::GetANGLEFormatSet(renderTarget->getANGLEFormat());
ASSERT(renderTarget->getSamples() > 1);
D3D11_TEXTURE2D_DESC resolveDesc; D3D11_TEXTURE2D_DESC resolveDesc;
resolveDesc.Width = textureDesc.Width; resolveDesc.Width = renderTarget->getWidth();
resolveDesc.Height = textureDesc.Height; resolveDesc.Height = renderTarget->getHeight();
resolveDesc.MipLevels = 1; resolveDesc.MipLevels = 1;
resolveDesc.ArraySize = 1; resolveDesc.ArraySize = 1;
resolveDesc.Format = textureDesc.Format; resolveDesc.Format = formatSet.texFormat;
resolveDesc.SampleDesc.Count = 1; resolveDesc.SampleDesc.Count = 1;
resolveDesc.SampleDesc.Quality = 0; resolveDesc.SampleDesc.Quality = 0;
resolveDesc.Usage = textureDesc.Usage; resolveDesc.Usage = D3D11_USAGE_DEFAULT;
resolveDesc.BindFlags = textureDesc.BindFlags; resolveDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
resolveDesc.CPUAccessFlags = 0; resolveDesc.CPUAccessFlags = 0;
resolveDesc.MiscFlags = 0; resolveDesc.MiscFlags = 0;
ID3D11Texture2D *resolveTexture = NULL; ID3D11Texture2D *resolveTexture = nullptr;
HRESULT result = mDevice->CreateTexture2D(&resolveDesc, NULL, &resolveTexture); HRESULT result = mDevice->CreateTexture2D(&resolveDesc, nullptr, &resolveTexture);
if (FAILED(result)) if (FAILED(result))
{ {
ERR("Failed to create a multisample resolve texture, HRESULT: 0x%X.", result); return gl::Error(GL_OUT_OF_MEMORY,
return NULL; "Failed to create a multisample resolve texture, HRESULT: 0x%X.", result);
} }
mDeviceContext->ResolveSubresource(resolveTexture, 0, source, subresource, textureDesc.Format); mDeviceContext->ResolveSubresource(resolveTexture, 0, renderTarget->getTexture(),
return resolveTexture; renderTarget->getSubresourceIndex(), formatSet.texFormat);
} return TextureHelper11::MakeAndPossess2D(resolveTexture, renderTarget->getANGLEFormat());
else
{
source->AddRef();
return source;
}
} }
bool Renderer11::getLUID(LUID *adapterLuid) const bool Renderer11::getLUID(LUID *adapterLuid) const
......
...@@ -382,7 +382,9 @@ class Renderer11 : public RendererD3D ...@@ -382,7 +382,9 @@ class Renderer11 : public RendererD3D
gl::Error generateSwizzles(const gl::ContextState &data, gl::SamplerType type); gl::Error generateSwizzles(const gl::ContextState &data, gl::SamplerType type);
gl::Error generateSwizzles(const gl::ContextState &data); gl::Error generateSwizzles(const gl::ContextState &data);
ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource); gl::ErrorOrResult<TextureHelper11> resolveMultisampledTexture(RenderTarget11 *renderTarget,
bool depth,
bool stencil);
void populateRenderer11DeviceCaps(); void populateRenderer11DeviceCaps();
......
...@@ -408,22 +408,16 @@ gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, ...@@ -408,22 +408,16 @@ gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture,
copyArea.depth == texSize.depth; copyArea.depth == texSize.depth;
ID3D11Resource *dstTexture = nullptr; ID3D11Resource *dstTexture = nullptr;
gl::Error error(GL_NO_ERROR);
// If the zero-LOD workaround is active and we want to update a level greater than zero, then we // If the zero-LOD workaround is active and we want to update a level greater than zero, then we
// should update the mipmapped texture, even if mapmaps are currently disabled. // should update the mipmapped texture, even if mapmaps are currently disabled.
if (index.mipIndex > 0 && mRenderer->getWorkarounds().zeroMaxLodWorkaround) if (index.mipIndex > 0 && mRenderer->getWorkarounds().zeroMaxLodWorkaround)
{ {
error = getMippedResource(&dstTexture); ANGLE_TRY(getMippedResource(&dstTexture));
} }
else else
{ {
error = getResource(&dstTexture); ANGLE_TRY(getResource(&dstTexture));
}
if (error.isError())
{
return error;
} }
unsigned int dstSubresource = getSubresourceIndex(index); unsigned int dstSubresource = getSubresourceIndex(index);
...@@ -436,29 +430,27 @@ gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture, ...@@ -436,29 +430,27 @@ gl::Error TextureStorage11::updateSubresourceLevel(ID3D11Resource *srcTexture,
{ {
// CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
Blit11 *blitter = mRenderer->getBlitter(); Blit11 *blitter = mRenderer->getBlitter();
TextureHelper11 source = TextureHelper11::MakeAndReference(srcTexture, getANGLEFormat());
return blitter->copyDepthStencil(srcTexture, sourceSubresource, copyArea, texSize, TextureHelper11 dest = TextureHelper11::MakeAndReference(dstTexture, getANGLEFormat());
dstTexture, dstSubresource, copyArea, texSize, nullptr); return blitter->copyDepthStencil(source, sourceSubresource, copyArea, texSize, dest,
dstSubresource, copyArea, texSize, nullptr);
} }
else
{
D3D11_BOX srcBox; D3D11_BOX srcBox;
srcBox.left = copyArea.x; srcBox.left = copyArea.x;
srcBox.top = copyArea.y; srcBox.top = copyArea.y;
srcBox.right = srcBox.right =
copyArea.x + roundUp(static_cast<UINT>(copyArea.width), dxgiFormatSizeInfo.blockWidth); copyArea.x + roundUp(static_cast<UINT>(copyArea.width), dxgiFormatSizeInfo.blockWidth);
srcBox.bottom = copyArea.y + srcBox.bottom =
roundUp(static_cast<UINT>(copyArea.height), dxgiFormatSizeInfo.blockHeight); copyArea.y + roundUp(static_cast<UINT>(copyArea.height), dxgiFormatSizeInfo.blockHeight);
srcBox.front = copyArea.z; srcBox.front = copyArea.z;
srcBox.back = copyArea.z + copyArea.depth; srcBox.back = copyArea.z + copyArea.depth;
ID3D11DeviceContext *context = mRenderer->getDeviceContext(); ID3D11DeviceContext *context = mRenderer->getDeviceContext();
context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, context->CopySubresourceRegion(dstTexture, dstSubresource, copyArea.x, copyArea.y, copyArea.z,
copyArea.z, srcTexture, sourceSubresource, srcTexture, sourceSubresource, fullCopy ? nullptr : &srcBox);
fullCopy ? nullptr : &srcBox); return gl::NoError();
return gl::Error(GL_NO_ERROR);
}
} }
gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource *dstTexture, gl::Error TextureStorage11::copySubresourceLevel(ID3D11Resource *dstTexture,
......
...@@ -1658,11 +1658,13 @@ void TextureHelper11::reset() ...@@ -1658,11 +1658,13 @@ void TextureHelper11::reset()
} }
gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType, gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType,
DXGI_FORMAT dxgiFormat,
d3d11::ANGLEFormat angleFormat, d3d11::ANGLEFormat angleFormat,
const gl::Extents &size, const gl::Extents &size,
StagingAccess readAndWriteAccess,
ID3D11Device *device) ID3D11Device *device)
{ {
const auto &formatSet = d3d11::GetANGLEFormatSet(angleFormat);
if (textureType == GL_TEXTURE_2D) if (textureType == GL_TEXTURE_2D)
{ {
D3D11_TEXTURE2D_DESC stagingDesc; D3D11_TEXTURE2D_DESC stagingDesc;
...@@ -1670,7 +1672,7 @@ gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType, ...@@ -1670,7 +1672,7 @@ gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType,
stagingDesc.Height = size.height; stagingDesc.Height = size.height;
stagingDesc.MipLevels = 1; stagingDesc.MipLevels = 1;
stagingDesc.ArraySize = 1; stagingDesc.ArraySize = 1;
stagingDesc.Format = dxgiFormat; stagingDesc.Format = formatSet.texFormat;
stagingDesc.SampleDesc.Count = 1; stagingDesc.SampleDesc.Count = 1;
stagingDesc.SampleDesc.Quality = 0; stagingDesc.SampleDesc.Quality = 0;
stagingDesc.Usage = D3D11_USAGE_STAGING; stagingDesc.Usage = D3D11_USAGE_STAGING;
...@@ -1678,6 +1680,11 @@ gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType, ...@@ -1678,6 +1680,11 @@ gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType,
stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
stagingDesc.MiscFlags = 0; stagingDesc.MiscFlags = 0;
if (readAndWriteAccess == StagingAccess::READ_WRITE)
{
stagingDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE;
}
ID3D11Texture2D *stagingTex = nullptr; ID3D11Texture2D *stagingTex = nullptr;
HRESULT result = device->CreateTexture2D(&stagingDesc, nullptr, &stagingTex); HRESULT result = device->CreateTexture2D(&stagingDesc, nullptr, &stagingTex);
if (FAILED(result)) if (FAILED(result))
...@@ -1695,7 +1702,7 @@ gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType, ...@@ -1695,7 +1702,7 @@ gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType,
stagingDesc.Height = size.height; stagingDesc.Height = size.height;
stagingDesc.Depth = 1; stagingDesc.Depth = 1;
stagingDesc.MipLevels = 1; stagingDesc.MipLevels = 1;
stagingDesc.Format = dxgiFormat; stagingDesc.Format = formatSet.texFormat;
stagingDesc.Usage = D3D11_USAGE_STAGING; stagingDesc.Usage = D3D11_USAGE_STAGING;
stagingDesc.BindFlags = 0; stagingDesc.BindFlags = 0;
stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
......
...@@ -396,10 +396,16 @@ class TextureHelper11 : angle::NonCopyable ...@@ -396,10 +396,16 @@ class TextureHelper11 : angle::NonCopyable
ID3D11Texture3D *mTexture3D; ID3D11Texture3D *mTexture3D;
}; };
enum class StagingAccess
{
READ,
READ_WRITE,
};
gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType, gl::ErrorOrResult<TextureHelper11> CreateStagingTexture(GLenum textureType,
DXGI_FORMAT dxgiFormat,
d3d11::ANGLEFormat angleFormat, d3d11::ANGLEFormat angleFormat,
const gl::Extents &size, const gl::Extents &size,
StagingAccess readAndWriteAccess,
ID3D11Device *device); ID3D11Device *device);
bool UsePresentPathFast(const Renderer11 *renderer, const gl::FramebufferAttachment *colorbuffer); bool UsePresentPathFast(const Renderer11 *renderer, const gl::FramebufferAttachment *colorbuffer);
......
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