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 ...@@ -517,6 +517,34 @@ const FramebufferAttachment *FramebufferState::getDepthStencilAttachment() const
return nullptr; 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 bool FramebufferState::attachmentsHaveSameDimensions() const
{ {
Optional<Extents> attachmentSize; Optional<Extents> attachmentSize;
...@@ -673,11 +701,12 @@ Box FramebufferState::getDimensions() const ...@@ -673,11 +701,12 @@ Box FramebufferState::getDimensions() const
Extents FramebufferState::getExtents() 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(); const FramebufferAttachment *first = getFirstNonNullAttachment();
if (first) if (first)
{ {
return first->getSize(); return getAttachmentExtentsIntersection();
} }
return Extents(getDefaultWidth(), getDefaultHeight(), 0); return Extents(getDefaultWidth(), getDefaultHeight(), 0);
} }
......
...@@ -81,6 +81,7 @@ class FramebufferState final : angle::NonCopyable ...@@ -81,6 +81,7 @@ class FramebufferState final : angle::NonCopyable
} }
const DrawBufferMask getColorAttachmentsMask() const { return mColorAttachmentsMask; } const DrawBufferMask getColorAttachmentsMask() const { return mColorAttachmentsMask; }
const Extents getAttachmentExtentsIntersection() const;
bool attachmentsHaveSameDimensions() const; bool attachmentsHaveSameDimensions() const;
bool hasSeparateDepthAndStencilAttachments() const; bool hasSeparateDepthAndStencilAttachments() const;
bool colorAttachmentsAreUniqueImages() const; bool colorAttachmentsAreUniqueImages() const;
......
...@@ -2020,7 +2020,8 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, ...@@ -2020,7 +2020,8 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk,
// Gather VkImageViews over all FBO attachments, also size of attached region. // Gather VkImageViews over all FBO attachments, also size of attached region.
std::vector<VkImageView> attachments; std::vector<VkImageView> attachments;
gl::Extents attachmentsSize; gl::Extents attachmentsSize = mState.getExtents();
ASSERT(attachmentsSize.width != 0 && attachmentsSize.height != 0);
// Color attachments. // Color attachments.
const auto &colorRenderTargets = mRenderTargetCache.getColors(); const auto &colorRenderTargets = mRenderTargetCache.getColors();
...@@ -2034,9 +2035,6 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, ...@@ -2034,9 +2035,6 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk,
contextVk, mCurrentFramebufferDesc.getWriteControlMode(), &imageView)); contextVk, mCurrentFramebufferDesc.getWriteControlMode(), &imageView));
attachments.push_back(imageView->getHandle()); attachments.push_back(imageView->getHandle());
ASSERT(attachmentsSize.empty() || attachmentsSize == colorRenderTarget->getExtents());
attachmentsSize = colorRenderTarget->getExtents();
} }
// Depth/stencil attachment. // Depth/stencil attachment.
...@@ -2047,10 +2045,6 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, ...@@ -2047,10 +2045,6 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk,
ANGLE_TRY(depthStencilRenderTarget->getImageView(contextVk, &imageView)); ANGLE_TRY(depthStencilRenderTarget->getImageView(contextVk, &imageView));
attachments.push_back(imageView->getHandle()); attachments.push_back(imageView->getHandle());
ASSERT(attachmentsSize.empty() ||
attachmentsSize == depthStencilRenderTarget->getExtents());
attachmentsSize = depthStencilRenderTarget->getExtents();
} }
// Color resolve attachments. // Color resolve attachments.
...@@ -2076,8 +2070,6 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, ...@@ -2076,8 +2070,6 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk,
ANGLE_TRY(colorRenderTarget->getResolveImageView(contextVk, &resolveImageView)); ANGLE_TRY(colorRenderTarget->getResolveImageView(contextVk, &resolveImageView));
attachments.push_back(resolveImageView->getHandle()); attachments.push_back(resolveImageView->getHandle());
ASSERT(!attachmentsSize.empty());
} }
} }
} }
...@@ -2089,17 +2081,8 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk, ...@@ -2089,17 +2081,8 @@ angle::Result FramebufferVk::getFramebuffer(ContextVk *contextVk,
ANGLE_TRY(depthStencilRenderTarget->getResolveImageView(contextVk, &imageView)); ANGLE_TRY(depthStencilRenderTarget->getResolveImageView(contextVk, &imageView));
attachments.push_back(imageView->getHandle()); 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 = {}; VkFramebufferCreateInfo framebufferInfo = {};
framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
...@@ -2708,10 +2691,6 @@ angle::Result FramebufferVk::readPixelsImpl(ContextVk *contextVk, ...@@ -2708,10 +2691,6 @@ angle::Result FramebufferVk::readPixelsImpl(ContextVk *contextVk,
gl::Extents FramebufferVk::getReadImageExtents() const gl::Extents FramebufferVk::getReadImageExtents() const
{ {
RenderTargetVk *readRenderTarget = mRenderTargetCache.getColorRead(mState); RenderTargetVk *readRenderTarget = mRenderTargetCache.getColorRead(mState);
ASSERT(readRenderTarget->getExtents().width == mState.getDimensions().width);
ASSERT(readRenderTarget->getExtents().height == mState.getDimensions().height);
return readRenderTarget->getExtents(); return readRenderTarget->getExtents();
} }
......
...@@ -3054,8 +3054,6 @@ TEST_P(FramebufferTest_ES3, ChangeAttachmentThenInvalidateAndDraw) ...@@ -3054,8 +3054,6 @@ TEST_P(FramebufferTest_ES3, ChangeAttachmentThenInvalidateAndDraw)
// outside common intersection area are undefined. // outside common intersection area are undefined.
TEST_P(FramebufferTest_ES3, AttachmentsWithUnequalDimensions) TEST_P(FramebufferTest_ES3, AttachmentsWithUnequalDimensions)
{ {
// TODO: https://issuetracker.google.com/181800403
ANGLE_SKIP_TEST_IF(IsVulkan());
// TODO: https://anglebug.com/5866 // TODO: https://anglebug.com/5866
ANGLE_SKIP_TEST_IF(IsD3D() || IsMetal()); 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