WebGLCompat: Fix depthstencil query results.
getFramebufferAttachmentParameter returns incorrect
result for framebuffers in an inconsistent state.
BUG=angleproject:2259
Change-Id: I76fa99f1b8847c30469d344bd93dedd9cf6657bf
Reviewed-on: https://chromium-review.googlesource.com/798318
Reviewed-by: Bryan Bernhart <bryan.bernhart@intel.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index caebc20..18a2c3b 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -1686,7 +1686,7 @@
GLint *params)
{
const Framebuffer *framebuffer = mGLState.getTargetFramebuffer(target);
- QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
+ QueryFramebufferAttachmentParameteriv(this, framebuffer, attachment, pname, params);
}
void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
@@ -2220,7 +2220,7 @@
return EGL_NONE;
}
- const FramebufferAttachment *backAttachment = framebuffer->getAttachment(GL_BACK);
+ const FramebufferAttachment *backAttachment = framebuffer->getAttachment(this, GL_BACK);
ASSERT(backAttachment != nullptr);
return backAttachment->getSurface()->getRenderBuffer();
}
diff --git a/src/libANGLE/Framebuffer.cpp b/src/libANGLE/Framebuffer.cpp
index 187733f..67db701 100644
--- a/src/libANGLE/Framebuffer.cpp
+++ b/src/libANGLE/Framebuffer.cpp
@@ -297,7 +297,8 @@
return mLabel;
}
-const FramebufferAttachment *FramebufferState::getAttachment(GLenum attachment) const
+const FramebufferAttachment *FramebufferState::getAttachment(const Context *context,
+ GLenum attachment) const
{
if (attachment >= GL_COLOR_ATTACHMENT0 && attachment <= GL_COLOR_ATTACHMENT15)
{
@@ -317,7 +318,17 @@
return getStencilAttachment();
case GL_DEPTH_STENCIL:
case GL_DEPTH_STENCIL_ATTACHMENT:
- return getDepthStencilAttachment();
+ // In WebG1, DEPTH_STENCIL_ATTACHMENT is an alternative attachment point and even when
+ // inconsistant (i.e. multiple conflicting attachment points), it is still permitted to
+ // query the attachment parameters.
+ if (context->isWebGL1())
+ {
+ return getWebGLDepthStencilAttachment();
+ }
+ else
+ {
+ return getDepthStencilAttachment();
+ }
default:
UNREACHABLE();
return nullptr;
@@ -402,6 +413,11 @@
return mDepthAttachment.isAttached() ? &mDepthAttachment : nullptr;
}
+const FramebufferAttachment *FramebufferState::getWebGLDepthStencilAttachment() const
+{
+ return mWebGLDepthStencilAttachment.isAttached() ? &mWebGLDepthStencilAttachment : nullptr;
+}
+
const FramebufferAttachment *FramebufferState::getStencilAttachment() const
{
return mStencilAttachment.isAttached() ? &mStencilAttachment : nullptr;
@@ -466,7 +482,15 @@
// must be COLOR_ATTACHMENTi or NONE"
ASSERT(mDrawBufferStates[drawBufferIdx] == GL_COLOR_ATTACHMENT0 + drawBufferIdx ||
(drawBufferIdx == 0 && mDrawBufferStates[drawBufferIdx] == GL_BACK));
- return getAttachment(mDrawBufferStates[drawBufferIdx]);
+
+ if (mDrawBufferStates[drawBufferIdx] == GL_BACK)
+ {
+ return getColorAttachment(0);
+ }
+ else
+ {
+ return getColorAttachment(mDrawBufferStates[drawBufferIdx] - GL_COLOR_ATTACHMENT0);
+ }
}
else
{
@@ -797,9 +821,10 @@
return mState.getFirstNonNullAttachment();
}
-const FramebufferAttachment *Framebuffer::getAttachment(GLenum attachment) const
+const FramebufferAttachment *Framebuffer::getAttachment(const Context *context,
+ GLenum attachment) const
{
- return mState.getAttachment(attachment);
+ return mState.getAttachment(context, attachment);
}
size_t Framebuffer::getDrawbufferStateCount() const
diff --git a/src/libANGLE/Framebuffer.h b/src/libANGLE/Framebuffer.h
index 25985d1..32d3507 100644
--- a/src/libANGLE/Framebuffer.h
+++ b/src/libANGLE/Framebuffer.h
@@ -60,7 +60,7 @@
const std::string &getLabel();
size_t getReadIndex() const;
- const FramebufferAttachment *getAttachment(GLenum attachment) const;
+ const FramebufferAttachment *getAttachment(const Context *context, GLenum attachment) const;
const FramebufferAttachment *getReadAttachment() const;
const FramebufferAttachment *getFirstNonNullAttachment() const;
const FramebufferAttachment *getFirstColorAttachment() const;
@@ -100,6 +100,8 @@
GLint getBaseViewIndex() const;
private:
+ const FramebufferAttachment *getWebGLDepthStencilAttachment() const;
+
friend class Framebuffer;
std::string mLabel;
@@ -185,7 +187,7 @@
const FramebufferAttachment *getFirstColorbuffer() const;
const FramebufferAttachment *getFirstNonNullAttachment() const;
- const FramebufferAttachment *getAttachment(GLenum attachment) const;
+ const FramebufferAttachment *getAttachment(const Context *context, GLenum attachment) const;
GLenum getMultiviewLayout() const;
GLsizei getNumViews() const;
GLint getBaseViewIndex() const;
diff --git a/src/libANGLE/queryutils.cpp b/src/libANGLE/queryutils.cpp
index 16a989c..020db1a 100644
--- a/src/libANGLE/queryutils.cpp
+++ b/src/libANGLE/queryutils.cpp
@@ -778,14 +778,16 @@
} // anonymous namespace
-void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
+void QueryFramebufferAttachmentParameteriv(const Context *context,
+ const Framebuffer *framebuffer,
GLenum attachment,
GLenum pname,
GLint *params)
{
ASSERT(framebuffer);
- const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment);
+ const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
+
if (attachmentObject == nullptr)
{
// ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
diff --git a/src/libANGLE/queryutils.h b/src/libANGLE/queryutils.h
index 990cbc1..142f006 100644
--- a/src/libANGLE/queryutils.h
+++ b/src/libANGLE/queryutils.h
@@ -32,7 +32,8 @@
class VertexBinding;
struct VertexAttribCurrentValueData;
-void QueryFramebufferAttachmentParameteriv(const Framebuffer *framebuffer,
+void QueryFramebufferAttachmentParameteriv(const Context *context,
+ const Framebuffer *framebuffer,
GLenum attachment,
GLenum pname,
GLint *params);
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index a0617c2..fe97d78 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -1189,7 +1189,7 @@
return true;
}
-bool ValidateBlitFramebufferParameters(ValidationContext *context,
+bool ValidateBlitFramebufferParameters(Context *context,
GLint srcX0,
GLint srcY0,
GLint srcX1,
@@ -1383,9 +1383,9 @@
if (mask & masks[i])
{
const gl::FramebufferAttachment *readBuffer =
- readFramebuffer->getAttachment(attachments[i]);
+ readFramebuffer->getAttachment(context, attachments[i]);
const gl::FramebufferAttachment *drawBuffer =
- drawFramebuffer->getAttachment(attachments[i]);
+ drawFramebuffer->getAttachment(context, attachments[i]);
if (readBuffer && drawBuffer)
{
@@ -3739,7 +3739,7 @@
return true;
}
-bool ValidateGetFramebufferAttachmentParameterivBase(ValidationContext *context,
+bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
GLenum target,
GLenum attachment,
GLenum pname,
@@ -3889,7 +3889,7 @@
}
}
- const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(attachment);
+ const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
if (attachmentObject)
{
ASSERT(attachmentObject->type() == GL_RENDERBUFFER ||
@@ -4001,7 +4001,7 @@
return true;
}
-bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *context,
+bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
GLenum target,
GLenum attachment,
GLenum pname,
diff --git a/src/libANGLE/validationES.h b/src/libANGLE/validationES.h
index e29432b..d63b6a4 100644
--- a/src/libANGLE/validationES.h
+++ b/src/libANGLE/validationES.h
@@ -104,7 +104,7 @@
GLenum renderbuffertarget,
GLuint renderbuffer);
-bool ValidateBlitFramebufferParameters(ValidationContext *context,
+bool ValidateBlitFramebufferParameters(Context *context,
GLint srcX0,
GLint srcY0,
GLint srcX1,
@@ -382,12 +382,12 @@
bool ValidateRobustEntryPoint(ValidationContext *context, GLsizei bufSize);
bool ValidateRobustBufferSize(ValidationContext *context, GLsizei bufSize, GLsizei numParams);
-bool ValidateGetFramebufferAttachmentParameterivBase(ValidationContext *context,
+bool ValidateGetFramebufferAttachmentParameterivBase(Context *context,
GLenum target,
GLenum attachment,
GLenum pname,
GLsizei *numParams);
-bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(ValidationContext *context,
+bool ValidateGetFramebufferAttachmentParameterivRobustANGLE(Context *context,
GLenum target,
GLenum attachment,
GLenum pname,
diff --git a/src/libANGLE/validationES2.cpp b/src/libANGLE/validationES2.cpp
index 5e505aa..0cc6d0b 100644
--- a/src/libANGLE/validationES2.cpp
+++ b/src/libANGLE/validationES2.cpp
@@ -2502,9 +2502,9 @@
if (mask & masks[i])
{
const FramebufferAttachment *readBuffer =
- readFramebuffer->getAttachment(attachments[i]);
+ readFramebuffer->getAttachment(context, attachments[i]);
const FramebufferAttachment *drawBuffer =
- drawFramebuffer->getAttachment(attachments[i]);
+ drawFramebuffer->getAttachment(context, attachments[i]);
if (readBuffer && drawBuffer)
{
@@ -5834,7 +5834,7 @@
return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
}
-bool ValidateGetFramebufferAttachmentParameteriv(ValidationContext *context,
+bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
GLenum target,
GLenum attachment,
GLenum pname,
diff --git a/src/libANGLE/validationES2.h b/src/libANGLE/validationES2.h
index 5dc0917..af995ae 100644
--- a/src/libANGLE/validationES2.h
+++ b/src/libANGLE/validationES2.h
@@ -597,7 +597,7 @@
bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count);
-bool ValidateGetFramebufferAttachmentParameteriv(ValidationContext *context,
+bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
GLenum target,
GLenum attachment,
GLenum pname,
diff --git a/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
index d4459ec..ed55e64 100644
--- a/src/libGLESv2/entry_points_gles_2_0_ext.cpp
+++ b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
@@ -2091,7 +2091,7 @@
}
const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
- QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
+ QueryFramebufferAttachmentParameteriv(context, framebuffer, attachment, pname, params);
SetRobustLengthParam(length, numParams);
}
}
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index 76ed9b7..a3cf133 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -2935,10 +2935,9 @@
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture, 0);
- GLint attachmentType;
+ GLint attachmentType = 0;
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
- GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
- /*param*/ &attachmentType);
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &attachmentType);
EXPECT_GL_NO_ERROR();
EXPECT_GLENUM_EQ(GL_TEXTURE, attachmentType);
@@ -2947,11 +2946,42 @@
glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
- GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
- /*param*/ &attachmentType);
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &attachmentType);
EXPECT_GL_ERROR(GL_INVALID_ENUM);
}
+// Verify framebuffer attachments return expected types when in an inconsistant state.
+TEST_P(WebGLCompatibilityTest, FramebufferAttachmentConsistancy)
+{
+ ANGLE_SKIP_TEST_IF(getClientMajorVersion() > 2);
+
+ GLFramebuffer fbo;
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+ GLRenderbuffer rb1;
+ glBindRenderbuffer(GL_RENDERBUFFER, rb1);
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb1);
+
+ GLint attachmentType = 0;
+ glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &attachmentType);
+
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(GL_RENDERBUFFER, attachmentType);
+
+ GLRenderbuffer rb2;
+ glBindRenderbuffer(GL_RENDERBUFFER, rb2);
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rb2);
+
+ glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &attachmentType);
+
+ EXPECT_GL_NO_ERROR();
+ EXPECT_GLENUM_EQ(GL_RENDERBUFFER, attachmentType);
+}
+
// This tests that rendering feedback loops works as expected with WebGL 2.
// Based on WebGL test conformance2/rendering/rendering-sampling-feedback-loop.html
TEST_P(WebGL2CompatibilityTest, RenderingFeedbackLoopWithDrawBuffers)