Vulkan: Basic support of copySubImage
- Implement basic path that does a cpu readback for everything and
establish conformance for every case except the ones that need
conversion.
- Enables most copy sub image dEQP tests.
Bug: angleproject:2501
Change-Id: Ib67c184894625dde850f320c40fe51fe70ba974f
Reviewed-on: https://chromium-review.googlesource.com/1054387
Commit-Queue: Luc Ferron <lucferron@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index 3144ef5..8a2be4c 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -277,46 +277,12 @@
void *pixels)
{
const gl::State &glState = context->getGLState();
- ContextVk *contextVk = vk::GetImpl(context);
- RendererVk *renderer = contextVk->getRenderer();
- VkDevice device = renderer->getDevice();
-
- RenderTargetVk *renderTarget = mRenderTargetCache.getColorRead(mState);
+ RenderTargetVk *renderTarget = getColorReadRenderTarget();
ASSERT(renderTarget);
- vk::ImageHelper stagingImage;
- ANGLE_TRY(stagingImage.init2DStaging(
- device, renderer->getMemoryProperties(), renderTarget->image->getFormat(),
- gl::Extents(area.width, area.height, 1), vk::StagingUsage::Read));
-
- vk::CommandBuffer *commandBuffer = nullptr;
- ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
-
- stagingImage.changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
- VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
- VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, commandBuffer);
-
- vk::ImageHelper::Copy(renderTarget->image, &stagingImage, gl::Offset(area.x, area.y, 0),
- gl::Offset(), gl::Extents(area.width, area.height, 1),
- VK_IMAGE_ASPECT_COLOR_BIT, commandBuffer);
-
- // Triggers a full finish.
- // TODO(jmadill): Don't block on asynchronous readback.
- ANGLE_TRY(renderer->finish(context));
-
- // TODO(jmadill): parameters
- uint8_t *mapPointer = nullptr;
- ANGLE_TRY(stagingImage.getDeviceMemory().map(device, 0, stagingImage.getAllocatedMemorySize(),
- 0, &mapPointer));
-
const angle::Format &angleFormat = renderTarget->image->getFormat().textureFormat();
GLuint outputPitch = angleFormat.pixelBytes * area.width;
- // Get the staging image pitch and use it to pack the pixels later.
- VkSubresourceLayout subresourceLayout;
- stagingImage.getImage().getSubresourceLayout(device, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0,
- &subresourceLayout);
-
PackPixelsParams params;
params.area = area;
params.format = format;
@@ -325,13 +291,16 @@
params.packBuffer = glState.getTargetBuffer(gl::BufferBinding::PixelPack);
params.pack = glState.getPackState();
- PackPixels(params, angleFormat, static_cast<int>(subresourceLayout.rowPitch), mapPointer,
- reinterpret_cast<uint8_t *>(pixels));
+ vk::CommandBuffer *commandBuffer = nullptr;
+ ANGLE_TRY(beginWriteResource(vk::GetImpl(context)->getRenderer(), &commandBuffer));
+ return ReadPixelsFromRenderTarget(context, area, params, renderTarget, commandBuffer, pixels);
+}
- stagingImage.getDeviceMemory().unmap(device);
- renderer->releaseObject(renderer->getCurrentQueueSerial(), &stagingImage);
-
- return vk::NoError();
+RenderTargetVk *FramebufferVk::getColorReadRenderTarget()
+{
+ RenderTargetVk *renderTarget = mRenderTargetCache.getColorRead(mState);
+ ASSERT(renderTarget && renderTarget->image->valid());
+ return renderTarget;
}
gl::Error FramebufferVk::blit(const gl::Context *context,
@@ -807,4 +776,53 @@
mActiveColorComponentMasks[2].set(colorIndex, b);
mActiveColorComponentMasks[3].set(colorIndex, a);
}
+
+gl::Error ReadPixelsFromRenderTarget(const gl::Context *context,
+ const gl::Rectangle &area,
+ const PackPixelsParams &packPixelsParams,
+ RenderTargetVk *renderTarget,
+ vk::CommandBuffer *commandBuffer,
+ void *pixels)
+{
+ ContextVk *contextVk = vk::GetImpl(context);
+ RendererVk *renderer = contextVk->getRenderer();
+ VkDevice device = renderer->getDevice();
+
+ vk::ImageHelper stagingImage;
+ ANGLE_TRY(stagingImage.init2DStaging(
+ device, renderer->getMemoryProperties(), renderTarget->image->getFormat(),
+ gl::Extents(area.width, area.height, 1), vk::StagingUsage::Read));
+
+ stagingImage.changeLayoutWithStages(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_GENERAL,
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, commandBuffer);
+
+ vk::ImageHelper::Copy(renderTarget->image, &stagingImage, gl::Offset(area.x, area.y, 0),
+ gl::Offset(), gl::Extents(area.width, area.height, 1),
+ VK_IMAGE_ASPECT_COLOR_BIT, commandBuffer);
+
+ // Triggers a full finish.
+ // TODO(jmadill): Don't block on asynchronous readback.
+ ANGLE_TRY(renderer->finish(context));
+
+ // TODO(jmadill): parameters
+ uint8_t *mapPointer = nullptr;
+ ANGLE_TRY(stagingImage.getDeviceMemory().map(device, 0, stagingImage.getAllocatedMemorySize(),
+ 0, &mapPointer));
+
+ const angle::Format &angleFormat = renderTarget->image->getFormat().textureFormat();
+
+ // Get the staging image pitch and use it to pack the pixels later.
+ VkSubresourceLayout subresourceLayout;
+ stagingImage.getImage().getSubresourceLayout(device, VK_IMAGE_ASPECT_COLOR_BIT, 0, 0,
+ &subresourceLayout);
+
+ PackPixels(packPixelsParams, angleFormat, static_cast<int>(subresourceLayout.rowPitch),
+ mapPointer, reinterpret_cast<uint8_t *>(pixels));
+
+ stagingImage.getDeviceMemory().unmap(device);
+ renderer->releaseObject(renderer->getCurrentQueueSerial(), &stagingImage);
+
+ return vk::NoError();
+}
} // namespace rx