Commit be30c4fb by Luc Ferron Committed by Commit Bot

Vulkan: Framebuffer blit support for depth/stencil cases

Bug: angleproject:2643 Change-Id: Ib50e4051f5b3965c2a752cf2cd45d3470312cdcf Reviewed-on: https://chromium-review.googlesource.com/1115370 Commit-Queue: Luc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent a0adaf98
......@@ -342,6 +342,74 @@ RenderTargetVk *FramebufferVk::getDepthStencilRenderTarget() const
return mRenderTargetCache.getDepthStencil();
}
gl::Error FramebufferVk::blitUsingCopy(RendererVk *renderer,
vk::CommandBuffer *commandBuffer,
const gl::Rectangle &readArea,
const gl::Rectangle &destArea,
RenderTargetVk *readRenderTarget,
RenderTargetVk *drawRenderTarget,
const gl::Rectangle *scissor,
bool blitDepthBuffer,
bool blitStencilBuffer)
{
gl::Rectangle scissoredDrawRect = destArea;
gl::Rectangle scissoredReadRect = readArea;
if (scissor)
{
if (!ClipRectangle(destArea, *scissor, &scissoredDrawRect))
{
return gl::NoError();
}
if (!ClipRectangle(readArea, *scissor, &scissoredReadRect))
{
return gl::NoError();
}
}
const gl::Extents sourceFrameBufferExtents = readRenderTarget->getImageExtents();
const gl::Extents drawFrameBufferExtents = drawRenderTarget->getImageExtents();
// After cropping for the scissor, we also want to crop for the size of the buffers.
gl::Rectangle readFrameBufferBounds(0, 0, sourceFrameBufferExtents.width,
sourceFrameBufferExtents.height);
gl::Rectangle drawFrameBufferBounds(0, 0, drawFrameBufferExtents.width,
drawFrameBufferExtents.height);
if (!ClipRectangle(scissoredReadRect, readFrameBufferBounds, &scissoredReadRect))
{
return gl::NoError();
}
if (!ClipRectangle(scissoredDrawRect, drawFrameBufferBounds, &scissoredDrawRect))
{
return gl::NoError();
}
ASSERT(readFrameBufferBounds == drawFrameBufferBounds);
ASSERT(scissoredReadRect == readFrameBufferBounds);
ASSERT(scissoredDrawRect == drawFrameBufferBounds);
VkFlags aspectFlags =
vk::GetDepthStencilAspectFlags(readRenderTarget->getImageFormat().textureFormat());
vk::ImageHelper *readImage = readRenderTarget->getImageForRead(
this, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, aspectFlags, commandBuffer);
vk::ImageHelper *writeImage = drawRenderTarget->getImageForWrite(this);
// Requirement of the copyImageToBuffer, the dst image must be in
// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL layout.
writeImage->changeLayoutWithStages(aspectFlags, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, commandBuffer);
VkImageAspectFlags depthBit = blitDepthBuffer ? VK_IMAGE_ASPECT_DEPTH_BIT : 0;
VkImageAspectFlags stencilBit = blitStencilBuffer ? VK_IMAGE_ASPECT_STENCIL_BIT : 0;
VkImageAspectFlags aspectMask = depthBit | stencilBit;
vk::ImageHelper::Copy(readImage, writeImage, gl::Offset(), gl::Offset(),
gl::Extents(scissoredDrawRect.width, scissoredDrawRect.height, 1),
aspectMask, commandBuffer);
return gl::NoError();
}
RenderTargetVk *FramebufferVk::getColorReadRenderTarget() const
{
RenderTargetVk *renderTarget = mRenderTargetCache.getColorRead(mState);
......@@ -368,7 +436,6 @@ gl::Error FramebufferVk::blit(const gl::Context *context,
vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
FramebufferVk *sourceFramebufferVk = vk::GetImpl(sourceFramebuffer);
if (blitColorBuffer)
{
RenderTargetVk *readRenderTarget = sourceFramebufferVk->getColorReadRenderTarget();
......@@ -400,10 +467,9 @@ gl::Error FramebufferVk::blit(const gl::Context *context,
}
else
{
// TODO(lucferron): Support framebuffer blit with a slower path.
// http://anglebug.com/2643
UNIMPLEMENTED();
return gl::InternalError();
ASSERT(filter == GL_NEAREST);
ANGLE_TRY(blitUsingCopy(renderer, commandBuffer, sourceArea, destArea, readRenderTarget,
drawRenderTarget, scissor, blitDepthBuffer, blitStencilBuffer));
}
}
......
......@@ -107,6 +107,16 @@ class FramebufferVk : public FramebufferImpl, public vk::CommandGraphResource
FramebufferVk(const gl::FramebufferState &state);
FramebufferVk(const gl::FramebufferState &state, WindowSurfaceVk *backbuffer);
gl::Error blitUsingCopy(RendererVk *renderer,
vk::CommandBuffer *commandBuffer,
const gl::Rectangle &rectangle,
const gl::Rectangle &destArea,
RenderTargetVk *renderTargetVk,
RenderTargetVk *drawRenderTargetVk,
const gl::Rectangle *scissor,
bool blitDepthBuffer,
bool blitStencilBuffer);
gl::ErrorOrResult<vk::Framebuffer *> getFramebuffer(RendererVk *rendererVk);
gl::Error clearWithClearAttachments(ContextVk *contextVk,
......
......@@ -711,6 +711,11 @@ Error ImageHelper::init2DStaging(VkDevice device,
return NoError();
}
VkImageAspectFlags ImageHelper::getAspectFlags() const
{
return GetFormatAspectFlags(mFormat->textureFormat());
}
void ImageHelper::dumpResources(Serial serial, std::vector<GarbageObject> *garbageQueue)
{
mImage.dumpResources(serial, garbageQueue);
......@@ -865,7 +870,7 @@ void ImageHelper::Copy(ImageHelper *srcImage,
srcImage->getCurrentLayout() != VK_IMAGE_LAYOUT_GENERAL)
{
srcImage->changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
srcImage->getAspectFlags(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
}
......@@ -873,7 +878,7 @@ void ImageHelper::Copy(ImageHelper *srcImage,
dstImage->getCurrentLayout() != VK_IMAGE_LAYOUT_GENERAL)
{
dstImage->changeLayoutWithStages(
VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
dstImage->getAspectFlags(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
}
......
......@@ -193,6 +193,7 @@ class ImageHelper final : angle::NonCopyable
const gl::Extents &extent,
StagingUsage usage);
VkImageAspectFlags getAspectFlags() const;
void release(Serial serial, RendererVk *renderer);
void destroy(VkDevice device);
void dumpResources(Serial serial, std::vector<GarbageObject> *garbageQueue);
......
......@@ -570,11 +570,6 @@ TEST_P(BlitFramebufferANGLETest, ReverseOversizedBlit)
// blit from user-created FBO to system framebuffer, with depth buffer.
TEST_P(BlitFramebufferANGLETest, BlitWithDepth)
{
// TODO(lucferron): The format used is not supported for vkCmdBlitImage so we'll need to
// implement a slow path.
// http://anglebug.com/2643
ANGLE_SKIP_TEST_IF(IsVulkan());
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_ANGLE_framebuffer_blit"));
glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
......@@ -614,11 +609,6 @@ TEST_P(BlitFramebufferANGLETest, BlitWithDepth)
// blit from system FBO to user-created framebuffer, with depth buffer.
TEST_P(BlitFramebufferANGLETest, ReverseBlitWithDepth)
{
// TODO(lucferron): The format used is not supported for vkCmdBlitImage so we'll need to
// implement a slow path.
// http://anglebug.com/2643
ANGLE_SKIP_TEST_IF(IsVulkan());
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_ANGLE_framebuffer_blit"));
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
......@@ -791,17 +781,15 @@ TEST_P(BlitFramebufferANGLETest, BlitWithMissingAttachments)
TEST_P(BlitFramebufferANGLETest, BlitStencil)
{
// TODO(lucferron): The format used is not supported for vkCmdBlitImage so we'll need to
// implement a slow path.
// http://anglebug.com/2643
ANGLE_SKIP_TEST_IF(IsVulkan());
ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_ANGLE_framebuffer_blit"));
// TODO(jmadill): Figure out if we can fix this on D3D9.
// https://code.google.com/p/angleproject/issues/detail?id=2205
ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
// TODO(lucferron): Diagnose and fix http://anglebug.com/2693
ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsVulkan());
glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
glClear(GL_COLOR_BUFFER_BIT);
......
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