Commit a37d9748 by Charlie Lao Committed by Commit Bot

Vulkan: Add support for FBO with unequal sized attachments

OpenGLES 3.0 allows FBO with unequal sized attachments. This CL removes assertion that all attachment must have equal size from vulkan backend, and uses common intersect area to create VkFramebuffer object. Bug: b/181800403 Change-Id: Icbb12a26784b184ebd91740855672013f64b889d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2824760 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent aa2d400a
......@@ -517,6 +517,34 @@ const FramebufferAttachment *FramebufferState::getDepthStencilAttachment() const
return nullptr;
}
const Extents FramebufferState::getAttachmentExtentsIntersection() const
{
int32_t width = std::numeric_limits<int32_t>::max();
int32_t height = std::numeric_limits<int32_t>::max();
for (const FramebufferAttachment &attachment : mColorAttachments)
{
if (attachment.isAttached())
{
width = std::min(width, attachment.getSize().width);
height = std::min(height, attachment.getSize().height);
}
}
if (mDepthAttachment.isAttached())
{
width = std::min(width, mDepthAttachment.getSize().width);
height = std::min(height, mDepthAttachment.getSize().height);
}
if (mStencilAttachment.isAttached())
{
width = std::min(width, mStencilAttachment.getSize().width);
height = std::min(height, mStencilAttachment.getSize().height);
}
return Extents(width, height, 0);
}
bool FramebufferState::attachmentsHaveSameDimensions() const
{
Optional<Extents> attachmentSize;
......@@ -673,11 +701,12 @@ Box FramebufferState::getDimensions() const
Extents FramebufferState::getExtents() const
{
ASSERT(attachmentsHaveSameDimensions());
// OpenGLES3.0 (https://www.khronos.org/registry/OpenGL/specs/es/3.0/es_spec_3.0.pdf
// section 4.4.4.2) allows attachments have unequal size.
const FramebufferAttachment *first = getFirstNonNullAttachment();
if (first)
{
return first->getSize();
return getAttachmentExtentsIntersection();
}
return Extents(getDefaultWidth(), getDefaultHeight(), 0);
}
......
......@@ -81,6 +81,7 @@ class FramebufferState final : angle::NonCopyable
}
const DrawBufferMask getColorAttachmentsMask() const { return mColorAttachmentsMask; }
const Extents getAttachmentExtentsIntersection() const;
bool attachmentsHaveSameDimensions() const;
bool hasSeparateDepthAndStencilAttachments() const;
bool colorAttachmentsAreUniqueImages() const;
......
......@@ -2020,7 +2020,8 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk,
// Gather VkImageViews over all FBO attachments, also size of attached region.
std::vector<VkImageView> attachments;
gl::Extents attachmentsSize;
gl::Extents attachmentsSize = mState.getExtents();
ASSERT(attachmentsSize.width != 0 && attachmentsSize.height != 0);
// Color attachments.
const auto &colorRenderTargets = mRenderTargetCache.getColors();
......@@ -2034,9 +2035,6 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk,
contextVk, mCurrentFramebufferDesc.getWriteControlMode(), &imageView));
attachments.push_back(imageView->getHandle());
ASSERT(attachmentsSize.empty() || attachmentsSize == colorRenderTarget->getExtents());
attachmentsSize = colorRenderTarget->getExtents();
}
// Depth/stencil attachment.
......@@ -2047,10 +2045,6 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk,
ANGLE_TRY(depthStencilRenderTarget->getImageView(contextVk, &imageView));
attachments.push_back(imageView->getHandle());
ASSERT(attachmentsSize.empty() ||
attachmentsSize == depthStencilRenderTarget->getExtents());
attachmentsSize = depthStencilRenderTarget->getExtents();
}
// Color resolve attachments.
......@@ -2076,8 +2070,6 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk,
ANGLE_TRY(colorRenderTarget->getResolveImageView(contextVk, &resolveImageView));
attachments.push_back(resolveImageView->getHandle());
ASSERT(!attachmentsSize.empty());
}
}
}
......@@ -2089,17 +2081,8 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk,
ANGLE_TRY(depthStencilRenderTarget->getResolveImageView(contextVk, &imageView));
attachments.push_back(imageView->getHandle());
ASSERT(!attachmentsSize.empty());
}
if (attachmentsSize.empty())
{
// No attachments, so use the default values.
attachmentsSize.height = mState.getDefaultHeight();
attachmentsSize.width = mState.getDefaultWidth();
attachmentsSize.depth = 0;
}
VkFramebufferCreateInfo framebufferInfo = {};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
......@@ -2708,10 +2691,6 @@ angle::Result FramebufferVk::readPixelsImpl(ContextVk *contextVk,
gl::Extents FramebufferVk::getReadImageExtents() const
{
RenderTargetVk *readRenderTarget = mRenderTargetCache.getColorRead(mState);
ASSERT(readRenderTarget->getExtents().width == mState.getDimensions().width);
ASSERT(readRenderTarget->getExtents().height == mState.getDimensions().height);
return readRenderTarget->getExtents();
}
......
......@@ -3054,8 +3054,6 @@ TEST_P(FramebufferTest_ES3, ChangeAttachmentThenInvalidateAndDraw)
// outside common intersection area are undefined.
TEST_P(FramebufferTest_ES3, AttachmentsWithUnequalDimensions)
{
// TODO: https://issuetracker.google.com/181800403
ANGLE_SKIP_TEST_IF(IsVulkan());
// TODO: https://anglebug.com/5866
ANGLE_SKIP_TEST_IF(IsD3D() || IsMetal());
......
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