blob: 293d114ab4c026ccf084826f2e3ce17cd2aef555 [file] [log] [blame]
Geoff Lang53b8aec2015-08-24 10:33:25 -04001//
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
9namespace angle
10{
11
12class CopyTexImageTest : public ANGLETest
13{
14 protected:
15 CopyTexImageTest()
16 {
17 setWindowWidth(16);
18 setWindowHeight(16);
19 setConfigRedBits(8);
20 setConfigGreenBits(8);
21 setConfigBlueBits(8);
22 setConfigAlphaBits(8);
23 }
24
25 GLuint createFramebuffer(GLenum format, GLenum type, GLfloat color[4]) const
26 {
27 GLuint fbo;
28 glGenFramebuffers(1, &fbo);
29 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
30
31 GLuint texture = createTexture(format, type);
32 glBindTexture(GL_TEXTURE_2D, texture);
33 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
34
35 glClearColor(color[0], color[1], color[2], color[3]);
36 glClear(GL_COLOR_BUFFER_BIT);
37
38 return fbo;
39 }
40
41 GLuint createTexture(GLenum format, GLenum type) const
42 {
43 GLuint tex;
44 glGenTextures(1, &tex);
45 glBindTexture(GL_TEXTURE_2D, tex);
46 glTexImage2D(GL_TEXTURE_2D, 0, format, 16, 16, 0, format, type, nullptr);
47
48 // Disable mipmapping
49 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
50 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
51
52 return tex;
53 }
54
55 GLuint createTextureFromCopyTexImage(GLuint fbo, GLenum format) const
56 {
57 GLuint tex;
58 glGenTextures(1, &tex);
59 glBindTexture(GL_TEXTURE_2D, tex);
60
61 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
62 glCopyTexImage2D(GL_TEXTURE_2D, 0, format, 0, 0, 16, 16, 0);
63
64 // Disable mipmapping
65 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
66 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
67
68 return tex;
69 }
70
71 void copyTextureWithCopyTexSubImage(GLuint fbo,
72 GLuint texture,
73 GLint xoffset,
74 GLint yoffset,
75 GLint x,
76 GLint y,
77 GLsizei w,
78 GLsizei h) const
79 {
80 glBindTexture(GL_TEXTURE_2D, texture);
81 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
82 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, x, y, w, h);
83 }
84
85 virtual void SetUp()
86 {
87 ANGLETest::SetUp();
88
89 const std::string vsSource =
90 "precision highp float;\n"
91 "attribute vec4 position;\n"
92 "varying vec2 texcoord;\n"
93 "\n"
94 "void main()\n"
95 "{\n"
96 " gl_Position = position;\n"
97 " texcoord = (position.xy * 0.5) + 0.5;\n"
98 " texcoord.y = 1.0 - texcoord.y;\n"
99 "}\n";
100
101 const std::string textureFSSource =
102 "precision highp float;\n"
103 "uniform sampler2D tex;\n"
104 "varying vec2 texcoord;\n"
105 "\n"
106 "void main()\n"
107 "{\n"
108 " gl_FragColor = texture2D(tex, texcoord);\n"
109 "}\n";
110
111 mTextureProgram = CompileProgram(vsSource, textureFSSource);
112 if (mTextureProgram == 0)
113 {
114 FAIL() << "shader compilation failed.";
115 }
116
117 mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
118
119 ASSERT_GL_NO_ERROR();
120 }
121
122 virtual void TearDown()
123 {
124 glDeleteProgram(mTextureProgram);
125
126 ANGLETest::TearDown();
127 }
128
129 void verifyResults(GLuint texture, GLubyte data[4], GLint x, GLint y) const
130 {
131 glViewport(0, 0, 16, 16);
132
133 glBindFramebuffer(GL_FRAMEBUFFER, 0);
134
135 // Draw a quad with the target texture
136 glUseProgram(mTextureProgram);
137 glBindTexture(GL_TEXTURE_2D, texture);
138 glUniform1i(mTextureUniformLocation, 0);
139
140 drawQuad(mTextureProgram, "position", 0.5f);
141
142 // Expect that the rendered quad has the same color as the source texture
143 EXPECT_PIXEL_NEAR(x, y, data[0], data[1], data[2], data[3], 1.0);
144 }
145
146 GLuint mTextureProgram;
147 GLint mTextureUniformLocation;
148};
149
150TEST_P(CopyTexImageTest, RGBAToL)
151{
152 GLfloat color[] = {
153 0.25f, 1.0f, 0.75f, 0.5f,
154 };
155
156 GLuint fbo = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color);
157 GLuint tex = createTextureFromCopyTexImage(fbo, GL_LUMINANCE);
158
159 GLubyte expected[] = {
160 64, 64, 64, 255,
161 };
162 verifyResults(tex, expected, 0, 0);
163}
164
165TEST_P(CopyTexImageTest, RGBToL)
166{
Geoff Langaa40fee2015-09-01 09:35:45 -0400167 // TODO (geofflang): Figure out why CopyTex[Sub]Image doesn't work with
168 // RGB->L on older Intel chips
Jamie Madill7208f692016-02-29 10:47:35 -0500169 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Langaa40fee2015-09-01 09:35:45 -0400170 {
171 std::cout << "Test skipped on Intel OpenGL." << std::endl;
172 return;
173 }
174
Geoff Lang53b8aec2015-08-24 10:33:25 -0400175 GLfloat color[] = {
176 0.25f, 1.0f, 0.75f, 0.5f,
177 };
178
179 GLuint fbo = createFramebuffer(GL_RGB, GL_UNSIGNED_BYTE, color);
180 GLuint tex = createTextureFromCopyTexImage(fbo, GL_LUMINANCE);
181
182 GLubyte expected[] = {
183 64, 64, 64, 255,
184 };
185 verifyResults(tex, expected, 0, 0);
186}
187
188TEST_P(CopyTexImageTest, RGBAToLA)
189{
190 GLfloat color[] = {
191 0.25f, 1.0f, 0.75f, 0.5f,
192 };
193
194 GLuint fbo = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color);
195 GLuint tex = createTextureFromCopyTexImage(fbo, GL_LUMINANCE_ALPHA);
196
197 GLubyte expected[] = {
198 64, 64, 64, 127,
199 };
200 verifyResults(tex, expected, 0, 0);
201}
202
203TEST_P(CopyTexImageTest, RGBAToA)
204{
205 GLfloat color[] = {
206 0.25f, 1.0f, 0.75f, 0.5f,
207 };
208
209 GLuint fbo = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color);
210 GLuint tex = createTextureFromCopyTexImage(fbo, GL_ALPHA);
211
212 GLubyte expected[] = {
213 0, 0, 0, 127,
214 };
215 verifyResults(tex, expected, 0, 0);
216}
217
218TEST_P(CopyTexImageTest, SubImageRGBAToL)
219{
220 GLfloat color0[] = {
221 0.25f, 1.0f, 0.75f, 0.5f,
222 };
223 GLuint fbo0 = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color0);
224 GLuint tex = createTextureFromCopyTexImage(fbo0, GL_LUMINANCE);
225
226 GLfloat color1[] = {
227 0.5f, 0.25f, 1.0f, 0.75f,
228 };
229 GLuint fbo1 = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color1);
230 copyTextureWithCopyTexSubImage(fbo1, tex, 2, 4, 5, 6, 8, 8);
231
232 GLubyte expected0[] = {
233 64, 64, 64, 255,
234 };
235 verifyResults(tex, expected0, 0, 0);
236
237 GLubyte expected1[] = {
238 127, 127, 127, 255,
239 };
240 verifyResults(tex, expected1, 7, 7);
241}
242
243TEST_P(CopyTexImageTest, SubImageRGBAToLA)
244{
245 GLfloat color0[] = {
246 0.25f, 1.0f, 0.75f, 0.5f,
247 };
248 GLuint fbo0 = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color0);
249 GLuint tex = createTextureFromCopyTexImage(fbo0, GL_LUMINANCE_ALPHA);
250
251 GLfloat color1[] = {
252 0.5f, 0.25f, 1.0f, 0.75f,
253 };
254 GLuint fbo1 = createFramebuffer(GL_RGBA, GL_UNSIGNED_BYTE, color1);
255 copyTextureWithCopyTexSubImage(fbo1, tex, 2, 4, 5, 6, 8, 8);
256
257 GLubyte expected0[] = {
258 64, 64, 64, 127,
259 };
260 verifyResults(tex, expected0, 0, 0);
261
262 GLubyte expected1[] = {
263 127, 127, 127, 192,
264 };
265 verifyResults(tex, expected1, 7, 7);
266}
267
268TEST_P(CopyTexImageTest, SubImageRGBToL)
269{
Geoff Langaa40fee2015-09-01 09:35:45 -0400270 // TODO (geofflang): Figure out why CopyTex[Sub]Image doesn't work with
271 // RGB->L on older Intel chips
Jamie Madill7208f692016-02-29 10:47:35 -0500272 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Langaa40fee2015-09-01 09:35:45 -0400273 {
274 std::cout << "Test skipped on Intel OpenGL." << std::endl;
275 return;
276 }
277
Geoff Lang53b8aec2015-08-24 10:33:25 -0400278 GLfloat color0[] = {
279 0.25f, 1.0f, 0.75f, 0.5f,
280 };
281 GLuint fbo0 = createFramebuffer(GL_RGB, GL_UNSIGNED_BYTE, color0);
282 GLuint tex = createTextureFromCopyTexImage(fbo0, GL_LUMINANCE);
283
284 GLfloat color1[] = {
285 0.5f, 0.25f, 1.0f, 0.75f,
286 };
287 GLuint fbo1 = createFramebuffer(GL_RGB, GL_UNSIGNED_BYTE, color1);
288 copyTextureWithCopyTexSubImage(fbo1, tex, 2, 4, 5, 6, 8, 8);
289
290 GLubyte expected0[] = {
291 64, 64, 64, 255,
292 };
293 verifyResults(tex, expected0, 0, 0);
294
295 GLubyte expected1[] = {
296 127, 127, 127, 255,
297 };
298 verifyResults(tex, expected1, 7, 7);
299}
300
301// Use this to select which configurations (e.g. which renderer, which GLES major version) these
302// tests should be run against.
Geoff Lange0cc2a42016-01-20 10:58:17 -0500303ANGLE_INSTANTIATE_TEST(CopyTexImageTest,
304 ES2_D3D9(),
Austin Kinross2a63b3f2016-02-08 12:29:08 -0800305 ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE),
306 ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE),
Geoff Lange0cc2a42016-01-20 10:58:17 -0500307 ES2_OPENGL(),
308 ES2_OPENGL(3, 3),
309 ES2_OPENGLES());
Geoff Lang53b8aec2015-08-24 10:33:25 -0400310}