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 ...@@ -342,6 +342,74 @@ RenderTargetVk *FramebufferVk::getDepthStencilRenderTarget() const
return mRenderTargetCache.getDepthStencil(); 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 *FramebufferVk::getColorReadRenderTarget() const
{ {
RenderTargetVk *renderTarget = mRenderTargetCache.getColorRead(mState); RenderTargetVk *renderTarget = mRenderTargetCache.getColorRead(mState);
...@@ -368,7 +436,6 @@ gl::Error FramebufferVk::blit(const gl::Context *context, ...@@ -368,7 +436,6 @@ gl::Error FramebufferVk::blit(const gl::Context *context,
vk::CommandBuffer *commandBuffer = nullptr; vk::CommandBuffer *commandBuffer = nullptr;
ANGLE_TRY(beginWriteResource(renderer, &commandBuffer)); ANGLE_TRY(beginWriteResource(renderer, &commandBuffer));
FramebufferVk *sourceFramebufferVk = vk::GetImpl(sourceFramebuffer); FramebufferVk *sourceFramebufferVk = vk::GetImpl(sourceFramebuffer);
if (blitColorBuffer) if (blitColorBuffer)
{ {
RenderTargetVk *readRenderTarget = sourceFramebufferVk->getColorReadRenderTarget(); RenderTargetVk *readRenderTarget = sourceFramebufferVk->getColorReadRenderTarget();
...@@ -400,10 +467,9 @@ gl::Error FramebufferVk::blit(const gl::Context *context, ...@@ -400,10 +467,9 @@ gl::Error FramebufferVk::blit(const gl::Context *context,
} }
else else
{ {
// TODO(lucferron): Support framebuffer blit with a slower path. ASSERT(filter == GL_NEAREST);
// http://anglebug.com/2643 ANGLE_TRY(blitUsingCopy(renderer, commandBuffer, sourceArea, destArea, readRenderTarget,
UNIMPLEMENTED(); drawRenderTarget, scissor, blitDepthBuffer, blitStencilBuffer));
return gl::InternalError();
} }
} }
......
...@@ -107,6 +107,16 @@ class FramebufferVk : public FramebufferImpl, public vk::CommandGraphResource ...@@ -107,6 +107,16 @@ class FramebufferVk : public FramebufferImpl, public vk::CommandGraphResource
FramebufferVk(const gl::FramebufferState &state); FramebufferVk(const gl::FramebufferState &state);
FramebufferVk(const gl::FramebufferState &state, WindowSurfaceVk *backbuffer); 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::ErrorOrResult<vk::Framebuffer *> getFramebuffer(RendererVk *rendererVk);
gl::Error clearWithClearAttachments(ContextVk *contextVk, gl::Error clearWithClearAttachments(ContextVk *contextVk,
......
...@@ -711,6 +711,11 @@ Error ImageHelper::init2DStaging(VkDevice device, ...@@ -711,6 +711,11 @@ Error ImageHelper::init2DStaging(VkDevice device,
return NoError(); return NoError();
} }
VkImageAspectFlags ImageHelper::getAspectFlags() const
{
return GetFormatAspectFlags(mFormat->textureFormat());
}
void ImageHelper::dumpResources(Serial serial, std::vector<GarbageObject> *garbageQueue) void ImageHelper::dumpResources(Serial serial, std::vector<GarbageObject> *garbageQueue)
{ {
mImage.dumpResources(serial, garbageQueue); mImage.dumpResources(serial, garbageQueue);
...@@ -865,7 +870,7 @@ void ImageHelper::Copy(ImageHelper *srcImage, ...@@ -865,7 +870,7 @@ void ImageHelper::Copy(ImageHelper *srcImage,
srcImage->getCurrentLayout() != VK_IMAGE_LAYOUT_GENERAL) srcImage->getCurrentLayout() != VK_IMAGE_LAYOUT_GENERAL)
{ {
srcImage->changeLayoutWithStages( 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); VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
} }
...@@ -873,7 +878,7 @@ void ImageHelper::Copy(ImageHelper *srcImage, ...@@ -873,7 +878,7 @@ void ImageHelper::Copy(ImageHelper *srcImage,
dstImage->getCurrentLayout() != VK_IMAGE_LAYOUT_GENERAL) dstImage->getCurrentLayout() != VK_IMAGE_LAYOUT_GENERAL)
{ {
dstImage->changeLayoutWithStages( 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); VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, commandBuffer);
} }
......
...@@ -193,6 +193,7 @@ class ImageHelper final : angle::NonCopyable ...@@ -193,6 +193,7 @@ class ImageHelper final : angle::NonCopyable
const gl::Extents &extent, const gl::Extents &extent,
StagingUsage usage); StagingUsage usage);
VkImageAspectFlags getAspectFlags() const;
void release(Serial serial, RendererVk *renderer); void release(Serial serial, RendererVk *renderer);
void destroy(VkDevice device); void destroy(VkDevice device);
void dumpResources(Serial serial, std::vector<GarbageObject> *garbageQueue); void dumpResources(Serial serial, std::vector<GarbageObject> *garbageQueue);
......
...@@ -570,11 +570,6 @@ TEST_P(BlitFramebufferANGLETest, ReverseOversizedBlit) ...@@ -570,11 +570,6 @@ TEST_P(BlitFramebufferANGLETest, ReverseOversizedBlit)
// blit from user-created FBO to system framebuffer, with depth buffer. // blit from user-created FBO to system framebuffer, with depth buffer.
TEST_P(BlitFramebufferANGLETest, BlitWithDepth) 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")); ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_ANGLE_framebuffer_blit"));
glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO); glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
...@@ -614,11 +609,6 @@ TEST_P(BlitFramebufferANGLETest, BlitWithDepth) ...@@ -614,11 +609,6 @@ TEST_P(BlitFramebufferANGLETest, BlitWithDepth)
// blit from system FBO to user-created framebuffer, with depth buffer. // blit from system FBO to user-created framebuffer, with depth buffer.
TEST_P(BlitFramebufferANGLETest, ReverseBlitWithDepth) 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")); ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_ANGLE_framebuffer_blit"));
glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO); glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
...@@ -791,17 +781,15 @@ TEST_P(BlitFramebufferANGLETest, BlitWithMissingAttachments) ...@@ -791,17 +781,15 @@ TEST_P(BlitFramebufferANGLETest, BlitWithMissingAttachments)
TEST_P(BlitFramebufferANGLETest, BlitStencil) 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")); ANGLE_SKIP_TEST_IF(!extensionEnabled("GL_ANGLE_framebuffer_blit"));
// TODO(jmadill): Figure out if we can fix this on D3D9. // TODO(jmadill): Figure out if we can fix this on D3D9.
// https://code.google.com/p/angleproject/issues/detail?id=2205 // https://code.google.com/p/angleproject/issues/detail?id=2205
ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9()); 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); glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
glClear(GL_COLOR_BUFFER_BIT); 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