Commit 7e69f76a by Martin Radev Committed by Commit Bot

Disallow active transform feedback with a multi-view draw framebuffer

According to the ANGLE_multiview spec Draw* commands should generate an INVALID_OPERATION error if there is an active transform feedback object and the number of views in the active draw framebuffer is greater than 1. The patch addresses this by extending the base draw call validation. BUG=angleproject:2062 TEST=angle_end2end_tests Change-Id: I67221cb2cfee6febae8d97697b234aeffff313de Reviewed-on: https://chromium-review.googlesource.com/589268 Commit-Queue: Martin Radev <mradev@nvidia.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 7cf6166a
......@@ -2821,13 +2821,25 @@ bool ValidateDrawBase(ValidationContext *context, GLenum mode, GLsizei count)
if (context->getExtensions().multiview)
{
const int programNumViews = program->getNumViews();
if (programNumViews != -1 && framebuffer->getNumViews() != programNumViews)
const int programNumViews = program->getNumViews();
const int framebufferNumViews = framebuffer->getNumViews();
if (programNumViews != -1 && framebufferNumViews != programNumViews)
{
context->handleError(InvalidOperation() << "The number of views in the active program "
"and draw framebuffer does not match.");
return false;
}
const TransformFeedback *transformFeedbackObject = state.getCurrentTransformFeedback();
if (transformFeedbackObject != nullptr && transformFeedbackObject->isActive() &&
framebufferNumViews > 1)
{
context->handleError(InvalidOperation()
<< "There is an active transform feedback object "
"when the number of views in the active draw "
"framebuffer is greater than 1.");
return false;
}
}
// Uniform buffer validation
......
......@@ -234,4 +234,59 @@ TEST_P(MultiviewDrawValidationTest, NumViewsMismatch)
}
}
// The test verifies that glDraw*:
// 1) generates an INVALID_OPERATION error if the number of views in the active draw framebuffer is
// greater than 1 and there is an active transform feedback object.
// 2) does not generate any error if the number of views in the draw framebuffer is 1.
TEST_P(MultiviewDrawValidationTest, ActiveTransformFeedback)
{
if (!requestMultiviewExtension())
{
return;
}
const GLint viewportOffsets[4] = {0, 0, 2, 0};
const std::string &vsSource =
"#version 300 es\n"
"void main()\n"
"{}\n";
const std::string &fsSource =
"#version 300 es\n"
"precision mediump float;\n"
"void main()\n"
"{}\n";
ANGLE_GL_PROGRAM(program, vsSource, fsSource);
glUseProgram(program);
GLBuffer tbo;
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, tbo);
glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(float) * 4u, nullptr, GL_STATIC_DRAW);
GLTransformFeedback transformFeedback;
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedback);
glBeginTransformFeedback(GL_TRIANGLES);
ASSERT_GL_NO_ERROR();
// Check that drawArrays generates an error when there is an active transform feedback object
// and the number of views in the draw framebuffer is greater than 1.
{
glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTex2d,
0, 2, &viewportOffsets[0]);
glDrawArrays(GL_TRIANGLES, 0, 3);
EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}
// Check that drawArrays does not generate an error when the number of views in the draw
// framebuffer is 1.
{
glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTex2d,
0, 1, &viewportOffsets[0]);
glDrawArrays(GL_TRIANGLES, 0, 3);
EXPECT_GL_NO_ERROR();
}
glEndTransformFeedback();
}
ANGLE_INSTANTIATE_TEST(MultiviewDrawValidationTest, ES31_OPENGL());
\ No newline at end of file
......@@ -44,12 +44,13 @@ class GLWrapper
GLuint mHandle = 0;
};
using GLVertexArray = GLWrapper<glGenVertexArrays, glDeleteVertexArrays>;
using GLBuffer = GLWrapper<glGenBuffers, glDeleteBuffers>;
using GLTexture = GLWrapper<glGenTextures, glDeleteTextures>;
using GLFramebuffer = GLWrapper<glGenFramebuffers, glDeleteFramebuffers>;
using GLRenderbuffer = GLWrapper<glGenRenderbuffers, glDeleteRenderbuffers>;
using GLSampler = GLWrapper<glGenSamplers, glDeleteSamplers>;
using GLVertexArray = GLWrapper<glGenVertexArrays, glDeleteVertexArrays>;
using GLBuffer = GLWrapper<glGenBuffers, glDeleteBuffers>;
using GLTexture = GLWrapper<glGenTextures, glDeleteTextures>;
using GLFramebuffer = GLWrapper<glGenFramebuffers, glDeleteFramebuffers>;
using GLRenderbuffer = GLWrapper<glGenRenderbuffers, glDeleteRenderbuffers>;
using GLSampler = GLWrapper<glGenSamplers, glDeleteSamplers>;
using GLTransformFeedback = GLWrapper<glGenTransformFeedbacks, glDeleteTransformFeedbacks>;
// Don't use GLProgram directly, use ANGLE_GL_PROGRAM.
namespace priv
......
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