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 // http://anglebug.com/5241
107 ANGLE_SKIP_TEST_IF(IsMetal() && IsOSX() && IsNVIDIA());
108
109 const GLfloat levelColors[] = {
110 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
111 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
112 };
113 const GLint testLevels = static_cast<GLint>(ArraySize(levelColors) / 4);
114
115 GLuint tex = 0;
116 glGenTextures(1, &tex);
117 glBindTexture(GL_TEXTURE_2D, tex);
118
119 for (GLint i = 0; i < testLevels; i++)
120 {
121 GLsizei size = 1 << ((testLevels - 1) - i);
122 glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
123 }
124
125 EXPECT_GL_NO_ERROR();
126
127 GLuint fbo = 0;
128 glGenFramebuffers(1, &fbo);
129 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
130 EXPECT_GL_NO_ERROR();
131
132 // Render to the levels of the texture with different colors
133 for (GLint i = 0; i < testLevels; i++)
134 {
135 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
136 EXPECT_GL_NO_ERROR();
137
138 glUseProgram(mProgram);
139 glUniform4fv(mColorLocation, 1, levelColors + (i * 4));
140
141 drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
142 EXPECT_GL_NO_ERROR();
143 }
144
145 // Test that the levels of the texture are correct
146 for (GLint i = 0; i < testLevels; i++)
147 {
148 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
149 EXPECT_GL_NO_ERROR();
150
151 const GLfloat *color = levelColors + (i * 4);
152 EXPECT_PIXEL_EQ(0, 0, color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255);
153 }
154
155 glDeleteFramebuffers(1, &fbo);
156 glDeleteTextures(1, &tex);
157
158 EXPECT_GL_NO_ERROR();
159 }
160
161 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
162 // tests should be run against.
163 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(FramebufferRenderMipmapTest);
164