1#include "ANGLETest.h"
2
3class ClearTest : public ANGLETest
4{
5protected:
6    ClearTest()
7    {
8        setWindowWidth(128);
9        setWindowHeight(128);
10        setConfigRedBits(8);
11        setConfigGreenBits(8);
12        setConfigBlueBits(8);
13        setConfigAlphaBits(8);
14        setConfigDepthBits(24);
15        setClientVersion(3);
16    }
17
18    virtual void SetUp()
19    {
20        ANGLETest::SetUp();
21
22        const std::string vertexShaderSource = SHADER_SOURCE
23        (
24            precision highp float;
25            attribute vec4 position;
26
27            void main()
28            {
29                gl_Position = position;
30            }
31        );
32
33        const std::string fragmentShaderSource = SHADER_SOURCE
34        (
35            precision highp float;
36
37            void main()
38            {
39                gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
40            }
41        );
42
43        mProgram = CompileProgram(vertexShaderSource, fragmentShaderSource);
44        if (mProgram == 0)
45        {
46            FAIL() << "shader compilation failed.";
47        }
48
49        glGenFramebuffers(1, &mFBO);
50
51        ASSERT_GL_NO_ERROR();
52    }
53
54    virtual void TearDown()
55    {
56        glDeleteProgram(mProgram);
57        glDeleteFramebuffers(1, &mFBO);
58
59        ANGLETest::TearDown();
60    }
61
62    GLuint mProgram;
63    GLuint mFBO;
64};
65
66TEST_F(ClearTest, ClearIssue)
67{
68    glEnable(GL_DEPTH_TEST);
69    glDepthFunc(GL_LEQUAL);
70
71    glClearColor(0.0, 1.0, 0.0, 1.0);
72    glClearDepthf(0.0);
73    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
74
75    EXPECT_GL_NO_ERROR();
76
77    glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
78
79    GLuint rbo;
80    glGenRenderbuffers(1, &rbo);
81    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
82    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB565, 16, 16);
83
84    EXPECT_GL_NO_ERROR();
85
86    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
87
88    EXPECT_GL_NO_ERROR();
89
90    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
91    glClearDepthf(1.0f);
92    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
93
94    EXPECT_GL_NO_ERROR();
95
96    glBindFramebuffer(GL_FRAMEBUFFER, 0);
97    glBindBuffer(GL_ARRAY_BUFFER, 0);
98
99    drawQuad(mProgram, "position", 0.5f);
100
101    EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
102}
103
104// Requires ES3
105// This tests a bug where in a masked clear when calling "ClearBuffer", we would
106// mistakenly clear every channel (including the masked-out ones)
107TEST_F(ClearTest, MaskedClearBufferBug)
108{
109    unsigned char pixelData[] = { 255, 255, 255, 255 };
110
111    glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
112
113    GLuint textures[2];
114    glGenTextures(2, &textures[0]);
115
116    glBindTexture(GL_TEXTURE_2D, textures[0]);
117    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
118    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
119
120    glBindTexture(GL_TEXTURE_2D, textures[1]);
121    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
122    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textures[1], 0);
123
124    ASSERT_GL_NO_ERROR();
125    EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);
126
127    float clearValue[] = { 0, 0.5f, 0.5f, 1.0f };
128    GLenum drawBuffers[] = { GL_NONE, GL_COLOR_ATTACHMENT1 };
129    glDrawBuffers(2, drawBuffers);
130    glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
131    glClearBufferfv(GL_COLOR, 1, clearValue);
132
133    ASSERT_GL_NO_ERROR();
134    EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);
135
136    // TODO: glReadBuffer support
137    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0);
138    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
139    EXPECT_PIXEL_EQ(0, 0, 0, 127, 255, 255);
140
141    glDeleteTextures(2, textures);
142}
143
144TEST_F(ClearTest, BadFBOSerialBug)
145{
146    // First make a simple framebuffer, and clear it to green
147    glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
148
149    GLuint textures[2];
150    glGenTextures(2, &textures[0]);
151
152    glBindTexture(GL_TEXTURE_2D, textures[0]);
153    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
154    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
155
156    GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0 };
157    glDrawBuffers(1, drawBuffers);
158
159    float clearValues1[] = { 0.0f, 1.0f, 0.0f, 1.0f };
160    glClearBufferfv(GL_COLOR, 0, clearValues1);
161
162    ASSERT_GL_NO_ERROR();
163    EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
164
165    // Next make a second framebuffer, and draw it to red
166    // (Triggers bad applied render target serial)
167    GLuint fbo2;
168    glGenFramebuffers(1, &fbo2);
169    ASSERT_GL_NO_ERROR();
170
171    glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
172
173    glBindTexture(GL_TEXTURE_2D, textures[1]);
174    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
175    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
176
177    glDrawBuffers(1, drawBuffers);
178
179    drawQuad(mProgram, "position", 0.5f);
180
181    ASSERT_GL_NO_ERROR();
182    EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
183
184    // Check that the first framebuffer is still green.
185    glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
186    EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
187
188    glDeleteTextures(2, textures);
189    glDeleteFramebuffers(1, &fbo2);
190}
191