Commit 4b7f12b2 by Geoff Lang Committed by Commit Bot

FramebufferD3D: Only make sure that enabled attachments are not the same.

It's acceptable to have the same object attached to muliple framebuffer attachments if they are not being drawn to. This was triggering failures in the conformance2/state/gl-object-get-calls.html test. BUG=483282 Change-Id: If088ccd9b1189f060dfa33ebbe4d82f1f47559b0 Reviewed-on: https://chromium-review.googlesource.com/354570Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent 41db2245
...@@ -67,6 +67,33 @@ const std::string &FramebufferState::getLabel() ...@@ -67,6 +67,33 @@ const std::string &FramebufferState::getLabel()
return mLabel; return mLabel;
} }
const FramebufferAttachment *FramebufferState::getAttachment(GLenum attachment) const
{
if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15)
{
return getColorAttachment(attachment - GL_COLOR_ATTACHMENT0);
}
switch (attachment)
{
case GL_COLOR:
case GL_BACK:
return getColorAttachment(0);
case GL_DEPTH:
case GL_DEPTH_ATTACHMENT:
return getDepthAttachment();
case GL_STENCIL:
case GL_STENCIL_ATTACHMENT:
return getStencilAttachment();
case GL_DEPTH_STENCIL:
case GL_DEPTH_STENCIL_ATTACHMENT:
return getDepthStencilAttachment();
default:
UNREACHABLE();
return nullptr;
}
}
const FramebufferAttachment *FramebufferState::getReadAttachment() const const FramebufferAttachment *FramebufferState::getReadAttachment() const
{ {
ASSERT(mReadBufferState == GL_BACK || (mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15)); ASSERT(mReadBufferState == GL_BACK || (mReadBufferState >= GL_COLOR_ATTACHMENT0 && mReadBufferState <= GL_COLOR_ATTACHMENT15));
...@@ -169,6 +196,28 @@ bool FramebufferState::attachmentsHaveSameDimensions() const ...@@ -169,6 +196,28 @@ bool FramebufferState::attachmentsHaveSameDimensions() const
return !hasMismatchedSize(mStencilAttachment); return !hasMismatchedSize(mStencilAttachment);
} }
const gl::FramebufferAttachment *FramebufferState::getDrawBuffer(size_t drawBufferIdx) const
{
ASSERT(drawBufferIdx < mDrawBufferStates.size());
if (mDrawBufferStates[drawBufferIdx] != GL_NONE)
{
// ES3 spec: "If the GL is bound to a draw framebuffer object, the ith buffer listed in bufs
// must be COLOR_ATTACHMENTi or NONE"
ASSERT(mDrawBufferStates[drawBufferIdx] == GL_COLOR_ATTACHMENT0 + drawBufferIdx ||
(drawBufferIdx == 0 && mDrawBufferStates[drawBufferIdx] == GL_BACK));
return getAttachment(mDrawBufferStates[drawBufferIdx]);
}
else
{
return nullptr;
}
}
size_t FramebufferState::getDrawBufferCount() const
{
return mDrawBufferStates.size();
}
Framebuffer::Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id) Framebuffer::Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id)
: mState(caps), : mState(caps),
mImpl(factory->createFramebuffer(mState)), mImpl(factory->createFramebuffer(mState)),
...@@ -295,31 +344,7 @@ const FramebufferAttachment *Framebuffer::getFirstColorbuffer() const ...@@ -295,31 +344,7 @@ const FramebufferAttachment *Framebuffer::getFirstColorbuffer() const
const FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const const FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
{ {
if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15) return mState.getAttachment(attachment);
{
return mState.getColorAttachment(attachment - GL_COLOR_ATTACHMENT0);
}
else
{
switch (attachment)
{
case GL_COLOR:
case GL_BACK:
return mState.getColorAttachment(0);
case GL_DEPTH:
case GL_DEPTH_ATTACHMENT:
return mState.getDepthAttachment();
case GL_STENCIL:
case GL_STENCIL_ATTACHMENT:
return mState.getStencilAttachment();
case GL_DEPTH_STENCIL:
case GL_DEPTH_STENCIL_ATTACHMENT:
return getDepthStencilBuffer();
default:
UNREACHABLE();
return nullptr;
}
}
} }
size_t Framebuffer::getDrawbufferStateCount() const size_t Framebuffer::getDrawbufferStateCount() const
...@@ -350,19 +375,7 @@ void Framebuffer::setDrawBuffers(size_t count, const GLenum *buffers) ...@@ -350,19 +375,7 @@ void Framebuffer::setDrawBuffers(size_t count, const GLenum *buffers)
const FramebufferAttachment *Framebuffer::getDrawBuffer(size_t drawBuffer) const const FramebufferAttachment *Framebuffer::getDrawBuffer(size_t drawBuffer) const
{ {
ASSERT(drawBuffer < mState.mDrawBufferStates.size()); return mState.getDrawBuffer(drawBuffer);
if (mState.mDrawBufferStates[drawBuffer] != GL_NONE)
{
// ES3 spec: "If the GL is bound to a draw framebuffer object, the ith buffer listed in bufs
// must be COLOR_ATTACHMENTi or NONE"
ASSERT(mState.mDrawBufferStates[drawBuffer] == GL_COLOR_ATTACHMENT0 + drawBuffer ||
(drawBuffer == 0 && mState.mDrawBufferStates[drawBuffer] == GL_BACK));
return getAttachment(mState.mDrawBufferStates[drawBuffer]);
}
else
{
return nullptr;
}
} }
bool Framebuffer::hasEnabledDrawBuffer() const bool Framebuffer::hasEnabledDrawBuffer() const
......
...@@ -58,6 +58,7 @@ class FramebufferState final : angle::NonCopyable ...@@ -58,6 +58,7 @@ class FramebufferState final : angle::NonCopyable
const std::string &getLabel(); const std::string &getLabel();
const FramebufferAttachment *getAttachment(GLenum attachment) const;
const FramebufferAttachment *getReadAttachment() const; const FramebufferAttachment *getReadAttachment() const;
const FramebufferAttachment *getFirstColorAttachment() const; const FramebufferAttachment *getFirstColorAttachment() const;
const FramebufferAttachment *getDepthOrStencilAttachment() const; const FramebufferAttachment *getDepthOrStencilAttachment() const;
...@@ -75,6 +76,9 @@ class FramebufferState final : angle::NonCopyable ...@@ -75,6 +76,9 @@ class FramebufferState final : angle::NonCopyable
bool attachmentsHaveSameDimensions() const; bool attachmentsHaveSameDimensions() const;
const FramebufferAttachment *getDrawBuffer(size_t drawBufferIdx) const;
size_t getDrawBufferCount() const;
private: private:
friend class Framebuffer; friend class Framebuffer;
......
...@@ -309,22 +309,31 @@ bool FramebufferD3D::checkStatus() const ...@@ -309,22 +309,31 @@ bool FramebufferD3D::checkStatus() const
return false; return false;
} }
// D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness by checking the
const auto &colorAttachments = mState.getColorAttachments(); // enabled draw buffers
for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++) for (size_t firstDrawBufferIdx = 0; firstDrawBufferIdx < mState.getDrawBufferCount();
firstDrawBufferIdx++)
{ {
const gl::FramebufferAttachment &attachment = colorAttachments[colorAttachment]; const gl::FramebufferAttachment *firstAttachment = mState.getDrawBuffer(firstDrawBufferIdx);
if (attachment.isAttached()) if (firstAttachment == nullptr)
{
continue;
}
for (size_t secondDrawBufferIdx = firstDrawBufferIdx + 1;
secondDrawBufferIdx < mState.getDrawBufferCount(); secondDrawBufferIdx++)
{ {
for (size_t prevColorAttachment = 0; prevColorAttachment < colorAttachment; prevColorAttachment++) const gl::FramebufferAttachment *secondAttachment =
mState.getDrawBuffer(secondDrawBufferIdx);
if (secondAttachment == nullptr)
{
continue;
}
if (firstAttachment->id() == secondAttachment->id() &&
firstAttachment->type() == secondAttachment->type())
{ {
const gl::FramebufferAttachment &prevAttachment = colorAttachments[prevColorAttachment]; return false;
if (prevAttachment.isAttached() &&
(attachment.id() == prevAttachment.id() &&
attachment.type() == prevAttachment.type()))
{
return false;
}
} }
} }
} }
......
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