1#include "ANGLETest.h"
2
3class TransformFeedbackTest : public ANGLETest
4{
5  protected:
6      TransformFeedbackTest()
7    {
8        setWindowWidth(128);
9        setWindowHeight(128);
10        setConfigRedBits(8);
11        setConfigGreenBits(8);
12        setConfigBlueBits(8);
13        setConfigAlphaBits(8);
14        setClientVersion(3);
15    }
16
17    virtual void SetUp()
18    {
19        ANGLETest::SetUp();
20
21        const std::string vertexShaderSource = SHADER_SOURCE
22        (
23            precision highp float;
24            attribute vec4 position;
25
26            void main()
27            {
28                gl_Position = position;
29            }
30        );
31
32        const std::string fragmentShaderSource = SHADER_SOURCE
33        (
34            precision highp float;
35
36            void main()
37            {
38                gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
39            }
40        );
41
42        mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
43        if (mProgram == 0)
44        {
45            FAIL() << "shader compilation failed.";
46        }
47
48        glGenBuffers(1, &mTransformFeedbackBuffer);
49        mTransformFeedbackBufferSize = 1 << 24; // ~16MB
50        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBuffer);
51        glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBufferSize, NULL, GL_STATIC_DRAW);
52
53        ASSERT_GL_NO_ERROR();
54    }
55
56    virtual void TearDown()
57    {
58        glDeleteProgram(mProgram);
59        glDeleteBuffers(1, &mTransformFeedbackBuffer);
60        ANGLETest::TearDown();
61    }
62
63    GLuint mProgram;
64
65    size_t mTransformFeedbackBufferSize;
66    GLuint mTransformFeedbackBuffer;
67};
68
69TEST_F(TransformFeedbackTest, ZeroSizedViewport)
70{
71    // Set the program's transform feedback varyings (just gl_Position)
72    const GLchar* transformFeedbackVaryings[] =
73    {
74        "gl_Position"
75    };
76    glTransformFeedbackVaryings(mProgram, ArraySize(transformFeedbackVaryings), transformFeedbackVaryings, GL_INTERLEAVED_ATTRIBS);
77    glLinkProgram(mProgram);
78
79    // Re-link the program
80    GLint linkStatus;
81    glGetProgramiv(mProgram, GL_LINK_STATUS, &linkStatus);
82    ASSERT_NE(linkStatus, 0);
83
84    glUseProgram(mProgram);
85
86    // Bind the buffer for transform feedback output and start transform feedback
87    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBuffer);
88    glBeginTransformFeedback(GL_TRIANGLES);
89
90    // Create a query to check how many primitives were written
91    GLuint primitivesWrittenQuery = 0;
92    glGenQueries(1, &primitivesWrittenQuery);
93    glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, primitivesWrittenQuery);
94
95    // Set a viewport that would result in no pixels being written to the framebuffer and draw
96    // a quad
97    glViewport(0, 0, 0, 0);
98
99    drawQuad(mProgram, "position", 0.5f);
100
101    // End the query and transform feedkback
102    glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
103    glEndTransformFeedback();
104
105    // Check how many primitives were written and verify that some were written even if
106    // no pixels were rendered
107    GLuint primitivesWritten = 0;
108    glGetQueryObjectuiv(primitivesWrittenQuery, GL_QUERY_RESULT_EXT, &primitivesWritten);
109    EXPECT_GL_NO_ERROR();
110
111    EXPECT_EQ(primitivesWritten, 2);
112}
113