Commit 1617e69e by Luc Ferron Committed by Commit Bot

Vulkan: Implement depth/stencil blit with flip of the viewport

- This makes all end2end tests pass successfully on Win/Nvidia with viewport flipping enabled. Bug: angleproject:2673 Change-Id: I031c0a0f5fb0aede58b59479e57c2c127bcb964c Reviewed-on: https://chromium-review.googlesource.com/1133703Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Luc Ferron <lucferron@chromium.org>
parent 1283ef62
......@@ -366,6 +366,7 @@ void PackPixels(const PackPixelsParams &params,
}
ColorWriteFunction colorWriteFunction = GetColorWriteFunction(formatType);
ASSERT(colorWriteFunction != nullptr);
// Maximum size of any Color<T> type used.
uint8_t temp[16];
......
......@@ -97,25 +97,35 @@ class FramebufferVk : public FramebufferImpl, public vk::CommandGraphResource
vk::Error readPixelsImpl(const gl::Context *context,
const gl::Rectangle &area,
const PackPixelsParams &packPixelsParams,
const VkImageAspectFlags &copyAspectFlags,
RenderTargetVk *renderTarget,
void *pixels);
const gl::Extents &getReadImageExtents() const;
gl::DrawBufferMask getEmulatedAlphaAttachmentMask();
RenderTargetVk *getColorReadRenderTarget() const;
private:
FramebufferVk(const gl::FramebufferState &state);
FramebufferVk(const gl::FramebufferState &state, WindowSurfaceVk *backbuffer);
gl::Error blitUsingCopy(RendererVk *renderer,
vk::CommandBuffer *commandBuffer,
const gl::Rectangle &rectangle,
gl::Error blitUsingCopy(vk::CommandBuffer *commandBuffer,
const gl::Rectangle &readArea,
const gl::Rectangle &destArea,
RenderTargetVk *renderTargetVk,
RenderTargetVk *drawRenderTargetVk,
RenderTargetVk *readRenderTarget,
RenderTargetVk *drawRenderTarget,
const gl::Rectangle *scissor,
bool blitDepthBuffer,
bool blitStencilBuffer);
gl::Error blitWithReadback(const gl::Context *context,
const gl::Rectangle &sourceArea,
const gl::Rectangle &destArea,
bool blitDepthBuffer,
bool blitStencilBuffer,
vk::CommandBuffer *commandBuffer,
RenderTargetVk *readRenderTarget,
RenderTargetVk *drawRenderTarget);
vk::Error getFramebuffer(RendererVk *rendererVk, vk::Framebuffer **framebufferOut);
......@@ -140,8 +150,6 @@ class FramebufferVk : public FramebufferImpl, public vk::CommandGraphResource
bool flipSource,
bool flipDest);
RenderTargetVk *getColorReadRenderTarget() const;
WindowSurfaceVk *mBackbuffer;
Optional<vk::RenderPassDesc> mRenderPassDesc;
......@@ -154,6 +162,7 @@ class FramebufferVk : public FramebufferImpl, public vk::CommandGraphResource
VkColorComponentFlags mActiveColorComponents;
gl::DrawBufferMask mActiveColorComponentMasksForClear[4];
vk::DynamicBuffer mReadPixelsBuffer;
vk::DynamicBuffer mBlitPixelBuffer;
// When we draw to the framebuffer, and the real format has an alpha channel but the format of
// the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will
......
......@@ -106,7 +106,6 @@ void RenderTargetVk::updateSwapchainImage(vk::ImageHelper *image, vk::ImageView
vk::ImageHelper *RenderTargetVk::getImageForRead(vk::CommandGraphResource *readingResource,
VkImageLayout layout,
VkImageAspectFlags aspectFlags,
vk::CommandBuffer *commandBuffer)
{
ASSERT(mImage && mImage->valid());
......@@ -114,7 +113,8 @@ vk::ImageHelper *RenderTargetVk::getImageForRead(vk::CommandGraphResource *readi
// TODO(jmadill): Better simultaneous resource access. http://anglebug.com/2679
mResource->addWriteDependency(readingResource);
mImage->changeLayoutWithStages(aspectFlags, layout, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
mImage->changeLayoutWithStages(mImage->getAspectFlags(), layout,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, commandBuffer);
return mImage;
......
......@@ -51,7 +51,6 @@ class RenderTargetVk final : public FramebufferAttachmentRenderTarget
// getImageForRead will also transition the resource to the given layout.
vk::ImageHelper *getImageForRead(vk::CommandGraphResource *readingResource,
VkImageLayout layout,
VkImageAspectFlags aspectFlags,
vk::CommandBuffer *commandBuffer);
vk::ImageHelper *getImageForWrite(vk::CommandGraphResource *writingResource) const;
vk::ImageView *getImageView() const;
......
......@@ -701,8 +701,8 @@ vk::Error RendererVk::finish(const gl::Context *context)
{
if (!mCommandGraph.empty())
{
vk::CommandBuffer commandBatch;
ANGLE_TRY(flushCommandGraph(context, &commandBatch));
vk::Scoped<vk::CommandBuffer> commandBatch(mDevice);
ANGLE_TRY(flushCommandGraph(context, &commandBatch.get()));
VkSubmitInfo submitInfo;
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
......@@ -711,11 +711,11 @@ vk::Error RendererVk::finish(const gl::Context *context)
submitInfo.pWaitSemaphores = nullptr;
submitInfo.pWaitDstStageMask = nullptr;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = commandBatch.ptr();
submitInfo.pCommandBuffers = commandBatch.get().ptr();
submitInfo.signalSemaphoreCount = 0;
submitInfo.pSignalSemaphores = nullptr;
ANGLE_TRY(submitFrame(submitInfo, std::move(commandBatch)));
ANGLE_TRY(submitFrame(submitInfo, std::move(commandBatch.get())));
}
ASSERT(mQueue != VK_NULL_HANDLE);
......
......@@ -232,8 +232,9 @@ vk::Error PixelBuffer::stageSubresourceUpdateFromFramebuffer(const gl::Context *
ANGLE_TRY_VK_ALLOCATION(context->getScratchBuffer(bufferSize, &memoryBuffer));
// Read into the scratch buffer
ANGLE_TRY(
framebufferVk->readPixelsImpl(context, clippedRectangle, params, memoryBuffer->data()));
ANGLE_TRY(framebufferVk->readPixelsImpl(
context, clippedRectangle, params, VK_IMAGE_ASPECT_COLOR_BIT,
framebufferVk->getColorReadRenderTarget(), memoryBuffer->data()));
// Load from scratch buffer to our pixel buffer
loadFunction.loadFunction(clippedRectangle.width, clippedRectangle.height, 1,
......@@ -243,7 +244,9 @@ vk::Error PixelBuffer::stageSubresourceUpdateFromFramebuffer(const gl::Context *
else
{
// We read directly from the framebuffer into our pixel buffer.
ANGLE_TRY(framebufferVk->readPixelsImpl(context, clippedRectangle, params, stagingPointer));
ANGLE_TRY(framebufferVk->readPixelsImpl(
context, clippedRectangle, params, VK_IMAGE_ASPECT_COLOR_BIT,
framebufferVk->getColorReadRenderTarget(), stagingPointer));
}
// 3- enqueue the destination image subresource update
......
......@@ -270,6 +270,12 @@ VkImageAspectFlags GetFormatAspectFlags(const angle::Format &format)
GetDepthStencilAspectFlags(format);
}
VkImageAspectFlags GetDepthStencilAspectFlagsForCopy(bool copyDepth, bool copyStencil)
{
return copyDepth ? VK_IMAGE_ASPECT_DEPTH_BIT
: 0 | copyStencil ? VK_IMAGE_ASPECT_STENCIL_BIT : 0;
}
Error::Error(VkResult result) : mResult(result), mFile(nullptr), mLine(0)
{
ASSERT(result == VK_SUCCESS);
......
......@@ -88,6 +88,7 @@ struct Format;
VkImageAspectFlags GetDepthStencilAspectFlags(const angle::Format &format);
VkImageAspectFlags GetFormatAspectFlags(const angle::Format &format);
VkImageAspectFlags GetDepthStencilAspectFlagsForCopy(bool copyDepth, bool copyStencil);
template <typename T>
struct ImplTypeHelper;
......
......@@ -605,14 +605,15 @@ TEST_P(BlitFramebufferANGLETest, BlitWithDepthUserToDefault)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
GL_NEAREST);
EXPECT_GL_NO_ERROR();
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
// if blit is happening correctly, this quad will draw only on the bottom half since it will be
// behind on the first half and in front on the second half.
// if blit is happening correctly, this quad will draw only on the bottom half since it will
// be behind on the first half and in front on the second half.
drawQuad(mBlueProgram, essl1_shaders::PositionAttrib(), 0.5f);
glDisable(GL_DEPTH_TEST);
......@@ -876,10 +877,6 @@ TEST_P(BlitFramebufferANGLETest, BlitStencil)
// make sure that attempting to blit a partial depth buffer issues an error
TEST_P(BlitFramebufferANGLETest, BlitPartialDepthStencil)
{
// TODO(lucferron): Fix this test and the implementation.
// http://anglebug.com/2673
ANGLE_SKIP_TEST_IF(IsVulkan());
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_ANGLE_framebuffer_blit"));
glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
......
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