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 bool renderToMipmapSupported =
57 IsGLExtensionEnabled("GL_OES_fbo_render_mipmap") || getClientMajorVersion() > 2;
58
59 GLuint tex = 0;
60 glGenTextures(1, &tex);
61 glBindTexture(GL_TEXTURE_2D, tex);
62
63 const GLint levels = 5;
64 for (GLint i = 0; i < levels; i++)
65 {
66 GLsizei size = 1 << ((levels - 1) - i);
67 glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
68 }
69
70 EXPECT_GL_NO_ERROR();
71
72 GLuint fbo = 0;
73 glGenFramebuffers(1, &fbo);
74 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
75 EXPECT_GL_NO_ERROR();
76
77 for (GLint i = 0; i < levels; i++)
78 {
79 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
80
81 if (i > 0 && !renderToMipmapSupported)
82 {
83 EXPECT_GL_ERROR(GL_INVALID_VALUE);
84 }
85 else
86 {
87 EXPECT_GL_NO_ERROR();
88 EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GLenum(GL_FRAMEBUFFER_COMPLETE));
89 }
90 }
91
92 glDeleteFramebuffers(1, &fbo);
93 glDeleteTextures(1, &tex);
94 }
95
96 // Render to various levels of a texture and check that they have the correct color data via
97 // ReadPixels
TEST_P(FramebufferRenderMipmapTest,RenderToMipmap)98 TEST_P(FramebufferRenderMipmapTest, RenderToMipmap)
99 {
100 bool renderToMipmapSupported =
101 IsGLExtensionEnabled("GL_OES_fbo_render_mipmap") || getClientMajorVersion() > 2;
102 ANGLE_SKIP_TEST_IF(!renderToMipmapSupported);
103
104 const GLfloat levelColors[] = {
105 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
106 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
107 };
108 const GLint testLevels = static_cast<GLint>(ArraySize(levelColors) / 4);
109
110 GLuint tex = 0;
111 glGenTextures(1, &tex);
112 glBindTexture(GL_TEXTURE_2D, tex);
113
114 for (GLint i = 0; i < testLevels; i++)
115 {
116 GLsizei size = 1 << ((testLevels - 1) - i);
117 glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
118 }
119
120 EXPECT_GL_NO_ERROR();
121
122 GLuint fbo = 0;
123 glGenFramebuffers(1, &fbo);
124 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
125 EXPECT_GL_NO_ERROR();
126
127 // Render to the levels of the texture with different colors
128 for (GLint i = 0; i < testLevels; i++)
129 {
130 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
131 EXPECT_GL_NO_ERROR();
132
133 glUseProgram(mProgram);
134 glUniform4fv(mColorLocation, 1, levelColors + (i * 4));
135
136 drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
137 EXPECT_GL_NO_ERROR();
138 }
139
140 // Test that the levels of the texture are correct
141 for (GLint i = 0; i < testLevels; i++)
142 {
143 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
144 EXPECT_GL_NO_ERROR();
145
146 const GLfloat *color = levelColors + (i * 4);
147 EXPECT_PIXEL_EQ(0, 0, color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255);
148 }
149
150 glDeleteFramebuffers(1, &fbo);
151 glDeleteTextures(1, &tex);
152
153 EXPECT_GL_NO_ERROR();
154 }
155
156 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
157 // tests should be run against.
158 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(FramebufferRenderMipmapTest);
159