Commit b067db75 by Ian Elliott Committed by Commit Bot

Vulkan: Fix copySubImageImplWithDraw() for pre-rotation

This involves cases of copying from a rotated default framebuffer. Various adjustments are needed for where the source is and its relationship to gl_FragCoord in the custom ImageCopy fragment shaders. Various tests are affected, including the following: Test: angle_deqp_gles2_tests --gtest_filter=dEQP.GLES2/functional_texture_specification_basic_copy*teximage2d_* Test: angle_deqp_gles3_tests --gtest_filter=dEQP.GLES3/functional_texture_specification_basic_copy*teximage2d_* Bug: b/158245571 Bug: b/157933235 Change-Id: Id9ec56d849cd2268954dd82623a7632a10fb8e8f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2248204Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarCourtney Goeltzenleuchter <courtneygo@google.com> Commit-Queue: Ian Elliott <ianelliott@google.com>
parent 6b49449d
......@@ -164,59 +164,59 @@
"src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000017.inc":
"6c22f38721dc29cae029174e6c4e4706",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000000.inc":
"f6360c798a9f79dfd2282e2668d91458",
"c1ad09ddda829019c168d6280921d374",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000001.inc":
"056aa59763aa95c55317d35bdc839e48",
"1f6192d3cb6c65e52798d231ecfc85f4",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000002.inc":
"1fc4201905b25c37882f19a49c892d83",
"5b14990a583493943543077c103a5ac9",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000004.inc":
"2108c7c63751f50e0cb455c282586eb2",
"a4ed2bdbe3161ac5de2f38054cd868e8",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000005.inc":
"01feb628559b1bec11269a09a5e5c455",
"3b3380b48b1a4f9b038062965caa9f62",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000006.inc":
"e207ff27f96775591801e3004b8f1c24",
"cbceb29bc6b11c2b780b3ac4596a41a5",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000008.inc":
"a7253e70adb10a686d38107fdc3cb29a",
"c8e704740513d51cdde047d30de26512",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000009.inc":
"f68a60034225fa97ce8f6ceda72bc0ac",
"fa84ad753c26f81330a9517edb6190c4",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.0000000A.inc":
"0cb35cb4b0820d9c8bbc24c4d1ca75e5",
"9fa8e4722b7613d02e85835a705ea3ef",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000010.inc":
"9e4ea90cb7a5e647518a29fa17eb2d29",
"fe83e1963df20330f142f807e694eeff",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000011.inc":
"487bdab5fb10a1592c41c60a6534df91",
"f864e836f25911a58e46e5864229713a",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000012.inc":
"45959c2c12e5e4f01ea734400e0e7f26",
"83d017b15e0dc809947da1aefc2517c4",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000014.inc":
"1832949b4dcaf245c29d248b5d5d2c02",
"9dd21b8d9bb59a842bd65a01650b7e87",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000015.inc":
"163de0317adf74f0efe06a8456a1fb26",
"9ea3f0aaa8dde52913a51f9f6e446773",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000016.inc":
"aa03ae5e425112cbbd7ac03dce52f0ef",
"a9558d6652f0b6d1989ac05e98e91452",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000018.inc":
"ef73f48913cacb633c802559de7000a3",
"f349a3b5b60ad61dfc9f66046fc754aa",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000019.inc":
"70f86a68fa068010a0430650629c0a74",
"3183a23f0ee3de28a3d5637b50ab0ccd",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.0000001A.inc":
"63d9f677f2a83e1c44a8caa2416520a4",
"3aeeeb2b14d097e7f356ee217b28ab18",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000020.inc":
"d1e6bc3b0363da1e4b44457e93585cf7",
"4a55c25b409f83a728cb1b2fe7ba859f",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000021.inc":
"130caf208f3481d12d47469d484a4c86",
"b346cd1f0653389707ee034f7c24f973",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000022.inc":
"d63d05dac24659e83a4837224b988f17",
"976313b24d7db916180ddaad767c1076",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000024.inc":
"1cda0371af83ddf7a28e8bed90173bcb",
"10c2b317a7c83e873e4ed78aadea3ddf",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000025.inc":
"ee0a7b33a8cc0f3688eedebcdc8f744d",
"b38f67f88d9c1d61514b75ce91a12987",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000026.inc":
"d026b4d993d37be1edacfe944b132bfd",
"4551025c7b312b33653a50c834ee6df9",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000028.inc":
"2ee2946b0cb300b010712dffd08711af",
"ddfa660cc681f253603acd2a060c183d",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.00000029.inc":
"0c54580c0f912cc04920fa7bfa5da9a6",
"82aef552fdd54d79920c7d883e84df15",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageCopy.frag.0000002A.inc":
"9b81edc5b043d29030140b454f6f1f50",
"be903b8892589e573d724761bc287955",
"src/libANGLE/renderer/vulkan/shaders/gen/OverlayCull.comp.00000000.inc":
"9217a56a28260a57f69d2e9ae014f6e3",
"src/libANGLE/renderer/vulkan/shaders/gen/OverlayCull.comp.00000001.inc":
......@@ -268,7 +268,7 @@
"src/libANGLE/renderer/vulkan/shaders/src/ImageClear.frag.json":
"f3e0afbc2368002e8a1148edcbe709fa",
"src/libANGLE/renderer/vulkan/shaders/src/ImageCopy.frag":
"900796c40d8494da9d78a6c3fa53aea4",
"a6efe37493456cfe83325b37c2c1b917",
"src/libANGLE/renderer/vulkan/shaders/src/ImageCopy.frag.json":
"f6b69ba316a5565400c2875e5da14b73",
"src/libANGLE/renderer/vulkan/shaders/src/OverlayCull.comp":
......
......@@ -560,10 +560,10 @@ angle::Result TextureVk::copySubImageImpl(const gl::Context *context,
const vk::ImageView *copyImageView = nullptr;
ANGLE_TRY(colorReadRT->getAndRetainCopyImageView(contextVk, &copyImageView));
return copySubImageImplWithDraw(contextVk, offsetImageIndex, modifiedDestOffset, destFormat,
colorReadRT->getLevelIndex(), clippedSourceBox,
isViewportFlipY, false, false, false,
&colorReadRT->getImage(), copyImageView);
return copySubImageImplWithDraw(
contextVk, offsetImageIndex, modifiedDestOffset, destFormat,
colorReadRT->getLevelIndex(), clippedSourceBox, isViewportFlipY, false, false, false,
&colorReadRT->getImage(), copyImageView, contextVk->getRotationReadFramebuffer());
}
// Do a CPU readback that does the conversion, and then stage the change to the pixel buffer.
......@@ -615,7 +615,7 @@ angle::Result TextureVk::copySubTextureImpl(ContextVk *contextVk,
return copySubImageImplWithDraw(
contextVk, offsetImageIndex, destOffset, destVkFormat, sourceLevelGL, sourceBox, false,
unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha, &source->getImage(),
&source->getCopyImageViewAndRecordUse(contextVk));
&source->getCopyImageViewAndRecordUse(contextVk), SurfaceRotation::Identity);
}
if (sourceLevelGL != 0)
......@@ -831,24 +831,66 @@ angle::Result TextureVk::copySubImageImplWithDraw(ContextVk *contextVk,
bool unpackPremultiplyAlpha,
bool unpackUnmultiplyAlpha,
vk::ImageHelper *srcImage,
const vk::ImageView *srcView)
const vk::ImageView *srcView,
SurfaceRotation srcFramebufferRotation)
{
RendererVk *renderer = contextVk->getRenderer();
UtilsVk &utilsVk = contextVk->getUtils();
// Potentially make adjustments for pre-rotatation.
gl::Box rotatedSourceBox = sourceBox;
gl::Extents srcExtents = srcImage->getLevelExtents2D(0);
switch (srcFramebufferRotation)
{
case SurfaceRotation::Identity:
// No adjustments needed
break;
case SurfaceRotation::Rotated90Degrees:
// Turn off y-flip for 90 degrees, as we don't want it affecting the
// shaderParams.srcOffset calculation done in UtilsVk::copyImage().
ASSERT(isSrcFlipY);
isSrcFlipY = false;
std::swap(rotatedSourceBox.x, rotatedSourceBox.y);
std::swap(rotatedSourceBox.width, rotatedSourceBox.height);
std::swap(srcExtents.width, srcExtents.height);
break;
case SurfaceRotation::Rotated180Degrees:
ASSERT(isSrcFlipY);
rotatedSourceBox.x = srcExtents.width - sourceBox.x - sourceBox.width;
rotatedSourceBox.y = srcExtents.height - sourceBox.y - sourceBox.height;
break;
case SurfaceRotation::Rotated270Degrees:
// Turn off y-flip for 270 degrees, as we don't want it affecting the
// shaderParams.srcOffset calculation done in UtilsVk::copyImage(). It is needed
// within the shader (when it will affect how the shader looks-up the source pixel),
// and so shaderParams.flipY is turned on at the right time within
// UtilsVk::copyImage().
ASSERT(isSrcFlipY);
isSrcFlipY = false;
rotatedSourceBox.x = srcExtents.height - sourceBox.y - sourceBox.height;
rotatedSourceBox.y = srcExtents.width - sourceBox.x - sourceBox.width;
std::swap(rotatedSourceBox.width, rotatedSourceBox.height);
std::swap(srcExtents.width, srcExtents.height);
break;
default:
UNREACHABLE();
break;
}
UtilsVk::CopyImageParameters params;
params.srcOffset[0] = sourceBox.x;
params.srcOffset[1] = sourceBox.y;
params.srcExtents[0] = sourceBox.width;
params.srcExtents[1] = sourceBox.height;
params.srcOffset[0] = rotatedSourceBox.x;
params.srcOffset[1] = rotatedSourceBox.y;
params.srcExtents[0] = rotatedSourceBox.width;
params.srcExtents[1] = rotatedSourceBox.height;
params.destOffset[0] = destOffset.x;
params.destOffset[1] = destOffset.y;
params.srcMip = static_cast<uint32_t>(sourceLevelGL) - srcImage->getBaseLevel();
params.srcHeight = srcImage->getExtents().height;
params.srcHeight = srcExtents.height;
params.srcPremultiplyAlpha = unpackPremultiplyAlpha && !unpackUnmultiplyAlpha;
params.srcUnmultiplyAlpha = unpackUnmultiplyAlpha && !unpackPremultiplyAlpha;
params.srcFlipY = isSrcFlipY;
params.destFlipY = unpackFlipY;
params.srcRotation = srcFramebufferRotation;
uint32_t level = index.getLevelIndex();
uint32_t baseLayer = index.hasLayer() ? index.getLayerIndex() : destOffset.z;
......
......@@ -330,7 +330,8 @@ class TextureVk : public TextureImpl, public angle::ObserverInterface
bool unpackPremultiplyAlpha,
bool unpackUnmultiplyAlpha,
vk::ImageHelper *srcImage,
const vk::ImageView *srcView);
const vk::ImageView *srcView,
SurfaceRotation srcFramebufferRotation);
angle::Result initImage(ContextVk *contextVk,
const vk::Format &format,
......
......@@ -1129,12 +1129,6 @@ angle::Result UtilsVk::startRenderPass(ContextVk *contextVk,
framebufferInfo.width = renderArea.x + renderArea.width;
framebufferInfo.height = renderArea.y + renderArea.height;
framebufferInfo.layers = 1;
if (contextVk->isRotatedAspectRatioForDrawFBO())
{
// The surface is rotated 90/270 degrees. This changes the aspect ratio of
// the surface. Swap the width and height of the framebuffer.
std::swap(framebufferInfo.width, framebufferInfo.height);
}
vk::Framebuffer framebuffer;
ANGLE_VK_TRY(contextVk, framebuffer.init(contextVk->getDevice(), framebufferInfo));
......@@ -1679,6 +1673,7 @@ angle::Result UtilsVk::copyImage(ContextVk *contextVk,
const angle::Format &dstIntendedFormat = dstFormat.intendedFormat();
ImageCopyShaderParams shaderParams;
shaderParams.flipX = 0;
shaderParams.flipY = params.srcFlipY || params.destFlipY;
shaderParams.premultiplyAlpha = params.srcPremultiplyAlpha;
shaderParams.unmultiplyAlpha = params.srcUnmultiplyAlpha;
......@@ -1691,6 +1686,7 @@ angle::Result UtilsVk::copyImage(ContextVk *contextVk,
shaderParams.srcOffset[1] = params.srcOffset[1];
shaderParams.destOffset[0] = params.destOffset[0];
shaderParams.destOffset[1] = params.destOffset[1];
shaderParams.rotateXY = 0;
shaderParams.srcIsSRGB =
gl::GetSizedInternalFormatInfo(srcFormat.internalFormat).colorEncoding == GL_SRGB;
......@@ -1720,6 +1716,33 @@ angle::Result UtilsVk::copyImage(ContextVk *contextVk,
shaderParams.srcOffset[1] = params.srcOffset[1] + params.srcExtents[1] - 1;
}
switch (params.srcRotation)
{
case SurfaceRotation::Identity:
break;
case SurfaceRotation::Rotated90Degrees:
shaderParams.rotateXY = 1;
break;
case SurfaceRotation::Rotated180Degrees:
shaderParams.flipX = true;
ASSERT(shaderParams.flipY);
shaderParams.flipY = false;
shaderParams.srcOffset[0] += params.srcExtents[0];
shaderParams.srcOffset[1] -= params.srcExtents[1];
break;
case SurfaceRotation::Rotated270Degrees:
shaderParams.flipX = true;
ASSERT(!shaderParams.flipY);
shaderParams.flipY = true;
shaderParams.srcOffset[0] += params.srcExtents[0];
shaderParams.srcOffset[1] += params.srcExtents[1];
shaderParams.rotateXY = 1;
break;
default:
UNREACHABLE();
break;
}
uint32_t flags = GetImageCopyFlags(srcFormat, dstFormat);
if (src->getType() == VK_IMAGE_TYPE_3D)
{
......@@ -1756,6 +1779,13 @@ angle::Result UtilsVk::copyImage(ContextVk *contextVk,
renderArea.y = params.destOffset[1];
renderArea.width = params.srcExtents[0];
renderArea.height = params.srcExtents[1];
if ((params.srcRotation == SurfaceRotation::Rotated90Degrees) ||
(params.srcRotation == SurfaceRotation::Rotated270Degrees))
{
// The surface is rotated 90/270 degrees. This changes the aspect ratio of the surface.
std::swap(renderArea.x, renderArea.y);
std::swap(renderArea.width, renderArea.height);
}
VkViewport viewport;
gl_vk::GetViewport(renderArea, 0.0f, 1.0f, false, dest->getExtents().height, &viewport);
......
......@@ -143,6 +143,7 @@ class UtilsVk : angle::NonCopyable
bool srcUnmultiplyAlpha;
bool srcFlipY;
bool destFlipY;
SurfaceRotation srcRotation;
};
struct OverlayCullParameters
......@@ -319,6 +320,7 @@ class UtilsVk : angle::NonCopyable
int32_t destOffset[2] = {};
int32_t srcMip = 0;
int32_t srcLayer = 0;
uint32_t flipX = 0;
uint32_t flipY = 0;
uint32_t premultiplyAlpha = 0;
uint32_t unmultiplyAlpha = 0;
......@@ -327,6 +329,7 @@ class UtilsVk : angle::NonCopyable
uint32_t srcIsSRGB = 0;
uint32_t destIsSRGB = 0;
uint32_t destDefaultChannelsMask = 0;
uint32_t rotateXY = 0;
};
union BlitResolveOffset
......
......@@ -53,7 +53,8 @@ layout(push_constant) uniform PushConstants {
ivec2 destOffset;
int srcMip;
int srcLayer;
// Whether y needs to be flipped
// Whether x and/or y need to be flipped
bool flipX;
bool flipY;
// Premultiplied alpha conversions
bool premultiplyAlpha;
......@@ -70,6 +71,7 @@ layout(push_constant) uniform PushConstants {
// Bit 0 is ignored, because R is always present. For B and G, the result is set to 0 and for
// A, the result is set to 1.
int destDefaultChannelsMask;
bool rotateXY;
} params;
#if SrcIsFloat
......@@ -114,12 +116,20 @@ void main()
ivec2 srcSubImageCoords = destSubImageCoords;
// If flipping Y, srcOffset would contain the opposite y coordinate, so we can
// simply reverse the direction in which y grows.
// If flipping X and/or Y, srcOffset would contain the opposite x and/or y coordinate, so we
// can simply reverse the direction in which x and/or y grows.
if (params.flipX)
{
srcSubImageCoords.x = -srcSubImageCoords.x;
}
if (params.flipY)
{
srcSubImageCoords.y = -srcSubImageCoords.y;
}
if (params.rotateXY)
{
srcSubImageCoords.xy = srcSubImageCoords.yx;
}
#if SrcIs2D
SrcType srcValue = texelFetch(src, params.srcOffset + srcSubImageCoords, params.srcMip);
......
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