blob: 9227b0cc10db291579400a3be38a971eb581463f [file] [log] [blame]
Geoff Lang95663912015-04-02 15:54:45 -04001#include "ANGLETest.h"
2
3// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lang8a6f19d2015-04-02 15:57:55 -04004ANGLE_TYPED_TEST_CASE(FramebufferRenderMipmapTest, ES2_D3D9, ES2_D3D11, ES3_D3D11, ES2_OPENGL, ES3_OPENGL);
Geoff Lang95663912015-04-02 15:54:45 -04005
6template<typename T>
7class FramebufferRenderMipmapTest : public ANGLETest
8{
9protected:
10 FramebufferRenderMipmapTest() : ANGLETest(T::GetGlesMajorVersion(), T::GetPlatform())
11 {
12 setWindowWidth(256);
13 setWindowHeight(256);
14 setConfigRedBits(8);
15 setConfigGreenBits(8);
16 setConfigBlueBits(8);
17 setConfigAlphaBits(8);
18 }
19
20 virtual void SetUp()
21 {
22 ANGLETest::SetUp();
23
24 const std::string vsSource = SHADER_SOURCE
25 (
26 attribute highp vec4 position;
27 void main(void)
28 {
29 gl_Position = position;
30 }
31 );
32
33 const std::string fsSource = SHADER_SOURCE
34 (
35 uniform highp vec4 color;
36 void main(void)
37 {
38 gl_FragColor = color;
39 }
40 );
41
42 mProgram = CompileProgram(vsSource, fsSource);
43 if (mProgram == 0)
44 {
45 FAIL() << "shader compilation failed.";
46 }
47
48 mColorLocation = glGetUniformLocation(mProgram, "color");
49
50 glUseProgram(mProgram);
51
52 glClearColor(0, 0, 0, 0);
53 glClearDepthf(0.0);
54 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
55
56 glEnable(GL_BLEND);
57 glDisable(GL_DEPTH_TEST);
58
59 ASSERT_GL_NO_ERROR();
60 }
61
62 virtual void TearDown()
63 {
64 glDeleteProgram(mProgram);
65
66 ANGLETest::TearDown();
67 }
68
69 GLuint mProgram;
70 GLint mColorLocation;
71};
72
73// Validate that if we are in ES3 or GL_OES_fbo_render_mipmap exists, there are no validation errors
74// when using a non-zero level in glFramebufferTexture2D.
75TYPED_TEST(FramebufferRenderMipmapTest, Validation)
76{
77 bool renderToMipmapSupported = extensionEnabled("GL_OES_fbo_render_mipmap") || getClientVersion() > 2;
78
79 GLuint tex = 0;
80 glGenTextures(1, &tex);
81 glBindTexture(GL_TEXTURE_2D, tex);
82
83 const size_t levels = 5;
84 for (size_t i = 0; i < levels; i++)
85 {
86 size_t size = 1 << ((levels - 1) - i);
87 glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
88 }
89
90 EXPECT_GL_NO_ERROR();
91
92 GLuint fbo = 0;
93 glGenFramebuffers(1, &fbo);
94 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
95 EXPECT_GL_NO_ERROR();
96
97 for (size_t i = 0; i < levels; i++)
98 {
99 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
100
101 if (i > 0 && !renderToMipmapSupported)
102 {
103 EXPECT_GL_ERROR(GL_INVALID_VALUE);
104 }
105 else
106 {
107 EXPECT_GL_NO_ERROR();
108 EXPECT_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER), GLenum(GL_FRAMEBUFFER_COMPLETE));
109 }
110 }
111
112 glDeleteFramebuffers(1, &fbo);
113 glDeleteTextures(1, &tex);
114}
115
116// Render to various levels of a texture and check that they have the correct color data via ReadPixels
117TYPED_TEST(FramebufferRenderMipmapTest, RenderToMipmap)
118{
Geoff Lang1a0847c2015-04-08 13:49:31 -0400119 // TODO(geofflang): Figure out why this is broken on Intel OpenGL
120 if (isIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
121 {
122 std::cout << "Test skipped on Intel OpenGL." << std::endl;
123 return;
124 }
125
Geoff Lang95663912015-04-02 15:54:45 -0400126 bool renderToMipmapSupported = extensionEnabled("GL_OES_fbo_render_mipmap") || getClientVersion() > 2;
127 if (!renderToMipmapSupported)
128 {
129 std::cout << "Test skipped because GL_OES_fbo_render_mipmap or ES3 is not available." << std::endl;
130 return;
131 }
132
133 const GLfloat levelColors[] =
134 {
135 1.0f, 0.0f, 0.0f, 1.0f,
136 0.0f, 1.0f, 0.0f, 1.0f,
137 0.0f, 0.0f, 1.0f, 1.0f,
138 1.0f, 1.0f, 0.0f, 1.0f,
139 1.0f, 0.0f, 1.0f, 1.0f,
140 0.0f, 1.0f, 1.0f, 1.0f,
141 };
142 const size_t testLevels = ArraySize(levelColors) / 4;
143
144 GLuint tex = 0;
145 glGenTextures(1, &tex);
146 glBindTexture(GL_TEXTURE_2D, tex);
147
148 for (size_t i = 0; i < testLevels; i++)
149 {
150 size_t size = 1 << ((testLevels - 1) - i);
151 glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
152 }
153
154 EXPECT_GL_NO_ERROR();
155
156 GLuint fbo = 0;
157 glGenFramebuffers(1, &fbo);
158 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
159 EXPECT_GL_NO_ERROR();
160
161 // Render to the levels of the texture with different colors
162 for (size_t i = 0; i < testLevels; i++)
163 {
164 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
165 EXPECT_GL_NO_ERROR();
166
167 glUseProgram(mProgram);
168 glUniform4fv(mColorLocation, 1, levelColors + (i * 4));
169
170 drawQuad(mProgram, "position", 0.5f);
171 EXPECT_GL_NO_ERROR();
172 }
173
174 // Test that the levels of the texture are correct
175 for (size_t i = 0; i < testLevels; i++)
176 {
177 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, i);
178 EXPECT_GL_NO_ERROR();
179
180 const GLfloat *color = levelColors + (i * 4);
181 EXPECT_PIXEL_EQ(0, 0, color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255);
182 }
183
184 glDeleteFramebuffers(1, &fbo);
185 glDeleteTextures(1, &tex);
186
187 EXPECT_GL_NO_ERROR();
188}