1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "test_utils/ANGLETest.h"
8
9 using namespace angle;
10
11 class FramebufferRenderMipmapTest : public ANGLETest
12 {
13 protected:
FramebufferRenderMipmapTest()14 FramebufferRenderMipmapTest()
15 {
16 setWindowWidth(256);
17 setWindowHeight(256);
18 setConfigRedBits(8);
19 setConfigGreenBits(8);
20 setConfigBlueBits(8);
21 setConfigAlphaBits(8);
22 }
23
testSetUp()24 void testSetUp() override
25 {
26 mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
27 if (mProgram == 0)
28 {
29 FAIL() << "shader compilation failed.";
30 }
31
32 mColorLocation = glGetUniformLocation(mProgram, essl1_shaders::ColorUniform());
33
34 glUseProgram(mProgram);
35
36 glClearColor(0, 0, 0, 0);
37 glClearDepthf(0.0);
38 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
39
40 glEnable(GL_BLEND);
41 glDisable(GL_DEPTH_TEST);
42
43 ASSERT_GL_NO_ERROR();
44 }
45
testTearDown()46 void testTearDown() override { glDeleteProgram(mProgram); }
47
48 GLuint mProgram;
49 GLint mColorLocation;
50 };
51
52 // Validate that if we are in ES3 or GL_OES_fbo_render_mipmap exists, there are no validation errors
53 // when using a non-zero level in glFramebufferTexture2D.
TEST_P(FramebufferRenderMipmapTest,Validation)54 TEST_P(FramebufferRenderMipmapTest, Validation)
55 {
56 // http://anglebug.com/4092
57 ANGLE_SKIP_TEST_IF(isSwiftshader());
58 bool renderToMipmapSupported =
59 IsGLExtensionEnabled("GL_OES_fbo_render_mipmap") || getClientMajorVersion() > 2;
60
61 GLuint tex = 0;
62 glGenTextures(1, &tex);
63 glBindTexture(GL_TEXTURE_2D, tex);
64
65 const GLint levels = 5;
66 for (GLint i = 0; i < levels; i++)
67 {
68 GLsizei size = 1 << ((levels - 1) - i);
69 glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
70 }
71
72 EXPECT_GL_NO_ERROR();
73
74 GLuint fbo = 0;
75 glGenFramebuffers(1, &fbo);
76 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
77 EXPECT_GL_NO_ERROR();
78
79 for (GLint i = 0; i < levels; i++)
80 {
81 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
82
83 if (i > 0 && !renderToMipmapSupported)
84 {
85 EXPECT_GL_ERROR(GL_INVALID_VALUE);
86 }
87 else
88 {
89 EXPECT_GL_NO_ERROR();
90 EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GLenum(GL_FRAMEBUFFER_COMPLETE));
91 }
92 }
93
94 glDeleteFramebuffers(1, &fbo);
95 glDeleteTextures(1, &tex);
96 }
97
98 // Render to various levels of a texture and check that they have the correct color data via
99 // ReadPixels
TEST_P(FramebufferRenderMipmapTest,RenderToMipmap)100 TEST_P(FramebufferRenderMipmapTest, RenderToMipmap)
101 {
102 bool renderToMipmapSupported =
103 IsGLExtensionEnabled("GL_OES_fbo_render_mipmap") || getClientMajorVersion() > 2;
104 ANGLE_SKIP_TEST_IF(!renderToMipmapSupported);
105
106 const GLfloat levelColors[] = {
107 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
108 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
109 };
110 const GLint testLevels = static_cast<GLint>(ArraySize(levelColors) / 4);
111
112 GLuint tex = 0;
113 glGenTextures(1, &tex);
114 glBindTexture(GL_TEXTURE_2D, tex);
115
116 for (GLint i = 0; i < testLevels; i++)
117 {
118 GLsizei size = 1 << ((testLevels - 1) - i);
119 glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
120 }
121
122 EXPECT_GL_NO_ERROR();
123
124 GLuint fbo = 0;
125 glGenFramebuffers(1, &fbo);
126 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
127 EXPECT_GL_NO_ERROR();
128
129 // Render to the levels of the texture with different colors
130 for (GLint i = 0; i < testLevels; i++)
131 {
132 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
133 EXPECT_GL_NO_ERROR();
134
135 glUseProgram(mProgram);
136 glUniform4fv(mColorLocation, 1, levelColors + (i * 4));
137
138 drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
139 EXPECT_GL_NO_ERROR();
140 }
141
142 // Test that the levels of the texture are correct
143 for (GLint i = 0; i < testLevels; i++)
144 {
145 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
146 EXPECT_GL_NO_ERROR();
147
148 const GLfloat *color = levelColors + (i * 4);
149 EXPECT_PIXEL_EQ(0, 0, color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255);
150 }
151
152 glDeleteFramebuffers(1, &fbo);
153 glDeleteTextures(1, &tex);
154
155 EXPECT_GL_NO_ERROR();
156 }
157
158 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
159 // tests should be run against.
160 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(FramebufferRenderMipmapTest);
161