Vulkan: Fix all copyTexImage/copySubTexImage cases with Y flip
- Validated by running:
-functional_texture_specification_basic_copytexsubimage2d_*
-functional_texture_specification_basic_copyteximage2d_*
With the flip flag enabled.
Bug: angleproject:2673
Change-Id: I5a3041af79f9316256b0650ab7e3fd0e086e46e3
Reviewed-on: https://chromium-review.googlesource.com/1129820
Commit-Queue: Luc Ferron <lucferron@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/TextureVk.cpp b/src/libANGLE/renderer/vulkan/TextureVk.cpp
index 1d8a5d0..dadd0a9 100644
--- a/src/libANGLE/renderer/vulkan/TextureVk.cpp
+++ b/src/libANGLE/renderer/vulkan/TextureVk.cpp
@@ -168,6 +168,8 @@
const gl::InternalFormat &formatInfo,
FramebufferVk *framebufferVk)
{
+ ContextVk *contextVk = vk::GetImpl(context);
+
// If the extents and offset is outside the source image, we need to clip.
gl::Rectangle clippedRectangle;
const gl::Extents readExtents = framebufferVk->getReadImageExtents();
@@ -178,6 +180,12 @@
return gl::NoError();
}
+ bool isViewportFlipEnabled = contextVk->isViewportFlipEnabledForDrawFBO();
+ if (isViewportFlipEnabled)
+ {
+ clippedRectangle.y = readExtents.height - clippedRectangle.y - clippedRectangle.height;
+ }
+
// 1- obtain a buffer handle to copy to
RendererVk *renderer = GetImplAs<ContextVk>(context)->getRenderer();
@@ -199,34 +207,46 @@
mStagingBuffer.allocate(renderer, allocationSize, &stagingPointer, &bufferHandle,
&stagingOffset, &newBufferAllocated);
+ gl::PixelPackState pixelPackState = gl::PixelPackState();
+ // TODO(lucferron): The pixel pack state alignment should probably be 1 instead of 4.
+ // http://anglebug.com/2718
+
+ if (isViewportFlipEnabled)
+ {
+ pixelPackState.reverseRowOrder = !pixelPackState.reverseRowOrder;
+ }
+
PackPixelsParams params;
- params.area = sourceArea;
+ params.area = clippedRectangle;
params.format = formatInfo.format;
params.type = formatInfo.type;
params.outputPitch = static_cast<GLuint>(outputRowPitch);
params.packBuffer = nullptr;
- params.pack = gl::PixelPackState();
+ params.pack = pixelPackState;
// 2- copy the source image region to the pixel buffer using a cpu readback
if (loadFunction.requiresConversion)
{
// When a conversion is required, we need to use the loadFunction to read from a temporary
// buffer instead so its an even slower path.
- size_t bufferSize = storageFormat.pixelBytes * sourceArea.width * sourceArea.height;
+ size_t bufferSize =
+ storageFormat.pixelBytes * clippedRectangle.width * clippedRectangle.height;
angle::MemoryBuffer *memoryBuffer = nullptr;
ANGLE_TRY(context->getScratchBuffer(bufferSize, &memoryBuffer));
// Read into the scratch buffer
- ANGLE_TRY(framebufferVk->readPixelsImpl(context, sourceArea, params, memoryBuffer->data()));
+ ANGLE_TRY(
+ framebufferVk->readPixelsImpl(context, clippedRectangle, params, memoryBuffer->data()));
// Load from scratch buffer to our pixel buffer
- loadFunction.loadFunction(sourceArea.width, sourceArea.height, 1, memoryBuffer->data(),
- outputRowPitch, 0, stagingPointer, outputRowPitch, 0);
+ loadFunction.loadFunction(clippedRectangle.width, clippedRectangle.height, 1,
+ memoryBuffer->data(), outputRowPitch, 0, stagingPointer,
+ outputRowPitch, 0);
}
else
{
// We read directly from the framebuffer into our pixel buffer.
- ANGLE_TRY(framebufferVk->readPixelsImpl(context, sourceArea, params, stagingPointer));
+ ANGLE_TRY(framebufferVk->readPixelsImpl(context, clippedRectangle, params, stagingPointer));
}
// 3- enqueue the destination image subresource update