blob: 9ed215252b7c41f54e7a8f0755dd80115eaf541e [file] [log] [blame]
Jamie Madillfa05f602015-05-07 13:47:11 -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//
Jamie Madill1fbc59f2016-02-24 15:25:51 -05006// Framebuffer tests:
7// Various tests related for Frambuffers.
8//
Jamie Madillfa05f602015-05-07 13:47:11 -04009
Corentin Wallezd3970de2015-05-14 11:07:48 -040010#include "test_utils/ANGLETest.h"
JiangYizhou461d9a32017-01-04 16:37:26 +080011#include "test_utils/gl_raii.h"
Geoff Langb6a673a2014-06-05 14:19:16 -040012
Jamie Madillfa05f602015-05-07 13:47:11 -040013using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070014
Geoff Lang857c09d2017-05-16 15:55:04 -040015namespace
16{
17
18void ExpectFramebufferCompleteOrUnsupported(GLenum binding)
19{
20 GLenum status = glCheckFramebufferStatus(binding);
21 EXPECT_TRUE(status == GL_FRAMEBUFFER_COMPLETE || status == GL_FRAMEBUFFER_UNSUPPORTED);
22}
23
24} // anonymous namespace
25
Geoff Langb6a673a2014-06-05 14:19:16 -040026class FramebufferFormatsTest : public ANGLETest
27{
Jamie Madillfa05f602015-05-07 13:47:11 -040028 protected:
Jamie Madill3215b202015-12-15 16:41:39 -050029 FramebufferFormatsTest() : mFramebuffer(0), mTexture(0), mRenderbuffer(0), mProgram(0)
Geoff Langb6a673a2014-06-05 14:19:16 -040030 {
31 setWindowWidth(128);
32 setWindowHeight(128);
33 setConfigRedBits(8);
34 setConfigGreenBits(8);
35 setConfigBlueBits(8);
36 setConfigAlphaBits(8);
37 }
38
39 void checkBitCount(GLuint fbo, GLenum channel, GLint minBits)
40 {
41 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
42
43 GLint bits = 0;
44 glGetIntegerv(channel, &bits);
45
46 if (minBits == 0)
47 {
48 EXPECT_EQ(minBits, bits);
49 }
50 else
51 {
52 EXPECT_GE(bits, minBits);
53 }
54 }
55
Jamie Madill1fbc59f2016-02-24 15:25:51 -050056 void testBitCounts(GLuint fbo,
57 GLint minRedBits,
58 GLint minGreenBits,
59 GLint minBlueBits,
60 GLint minAlphaBits,
61 GLint minDepthBits,
62 GLint minStencilBits)
Geoff Langb6a673a2014-06-05 14:19:16 -040063 {
64 checkBitCount(fbo, GL_RED_BITS, minRedBits);
65 checkBitCount(fbo, GL_GREEN_BITS, minGreenBits);
66 checkBitCount(fbo, GL_BLUE_BITS, minBlueBits);
67 checkBitCount(fbo, GL_ALPHA_BITS, minAlphaBits);
68 checkBitCount(fbo, GL_DEPTH_BITS, minDepthBits);
69 checkBitCount(fbo, GL_STENCIL_BITS, minStencilBits);
70 }
71
Jamie Madill1fbc59f2016-02-24 15:25:51 -050072 void testTextureFormat(GLenum internalFormat,
73 GLint minRedBits,
74 GLint minGreenBits,
75 GLint minBlueBits,
Geoff Langb6a673a2014-06-05 14:19:16 -040076 GLint minAlphaBits)
77 {
Jamie Madill3215b202015-12-15 16:41:39 -050078 glGenTextures(1, &mTexture);
79 glBindTexture(GL_TEXTURE_2D, mTexture);
Geoff Langc4e93662017-05-01 10:45:59 -040080
81 if (getClientMajorVersion() >= 3)
82 {
83 glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
84 }
85 else
86 {
87 glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
88 }
Geoff Langb6a673a2014-06-05 14:19:16 -040089
Jamie Madill3215b202015-12-15 16:41:39 -050090 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
Geoff Langb6a673a2014-06-05 14:19:16 -040091
Jamie Madill3215b202015-12-15 16:41:39 -050092 testBitCounts(mFramebuffer, minRedBits, minGreenBits, minBlueBits, minAlphaBits, 0, 0);
Geoff Langb6a673a2014-06-05 14:19:16 -040093 }
94
Jamie Madill1fbc59f2016-02-24 15:25:51 -050095 void testRenderbufferMultisampleFormat(int minESVersion,
96 GLenum attachmentType,
97 GLenum internalFormat)
Corentin Walleze0902642014-11-04 12:32:15 -080098 {
Geoff Langc4222072015-05-25 13:19:48 -040099 // TODO(geofflang): Figure out why this is broken on Intel OpenGL
Jamie Madill518b9fa2016-03-02 11:26:02 -0500100 if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Langc4222072015-05-25 13:19:48 -0400101 {
102 std::cout << "Test skipped on Intel OpenGL." << std::endl;
103 return;
104 }
105
Martin Radev1be913c2016-07-11 17:59:16 +0300106 int clientVersion = getClientMajorVersion();
Jamie Madillfa05f602015-05-07 13:47:11 -0400107 if (clientVersion < minESVersion)
Corentin Walleze0902642014-11-04 12:32:15 -0800108 {
109 return;
110 }
111
112 // Check that multisample is supported with at least two samples (minimum required is 1)
113 bool supports2Samples = false;
114
Jamie Madillfa05f602015-05-07 13:47:11 -0400115 if (clientVersion == 2)
Corentin Walleze0902642014-11-04 12:32:15 -0800116 {
117 if (extensionEnabled("ANGLE_framebuffer_multisample"))
118 {
119 int maxSamples;
120 glGetIntegerv(GL_MAX_SAMPLES_ANGLE, &maxSamples);
121 supports2Samples = maxSamples >= 2;
122 }
123 }
124 else
125 {
Jamie Madillfa05f602015-05-07 13:47:11 -0400126 assert(clientVersion >= 3);
Corentin Walleze0902642014-11-04 12:32:15 -0800127 int maxSamples;
128 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
129 supports2Samples = maxSamples >= 2;
130 }
131
132 if (!supports2Samples)
133 {
134 return;
135 }
136
Jamie Madill3215b202015-12-15 16:41:39 -0500137 glGenRenderbuffers(1, &mRenderbuffer);
138 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
Corentin Walleze0902642014-11-04 12:32:15 -0800139
140 EXPECT_GL_NO_ERROR();
141 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, internalFormat, 128, 128);
142 EXPECT_GL_NO_ERROR();
Jamie Madill3215b202015-12-15 16:41:39 -0500143 glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachmentType, GL_RENDERBUFFER, mRenderbuffer);
Corentin Walleze0902642014-11-04 12:32:15 -0800144 EXPECT_GL_NO_ERROR();
Corentin Walleze0902642014-11-04 12:32:15 -0800145 }
146
Olli Etuahobc21e182016-02-23 16:04:57 +0200147 void testZeroHeightRenderbuffer()
148 {
149 glGenRenderbuffers(1, &mRenderbuffer);
150 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
151 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 0);
152 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
153 mRenderbuffer);
154 EXPECT_GL_NO_ERROR();
155 }
156
Jamie Madill3215b202015-12-15 16:41:39 -0500157 void SetUp() override
Geoff Langb6a673a2014-06-05 14:19:16 -0400158 {
159 ANGLETest::SetUp();
Jamie Madill3215b202015-12-15 16:41:39 -0500160
161 glGenFramebuffers(1, &mFramebuffer);
162 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
Geoff Langb6a673a2014-06-05 14:19:16 -0400163 }
164
Jamie Madill3215b202015-12-15 16:41:39 -0500165 void TearDown() override
Geoff Langb6a673a2014-06-05 14:19:16 -0400166 {
167 ANGLETest::TearDown();
Jamie Madill3215b202015-12-15 16:41:39 -0500168
169 if (mTexture != 0)
170 {
171 glDeleteTextures(1, &mTexture);
172 mTexture = 0;
173 }
174
175 if (mRenderbuffer != 0)
176 {
177 glDeleteRenderbuffers(1, &mRenderbuffer);
178 mRenderbuffer = 0;
179 }
180
181 if (mFramebuffer != 0)
182 {
183 glDeleteFramebuffers(1, &mFramebuffer);
184 mFramebuffer = 0;
185 }
186
187 if (mProgram != 0)
188 {
189 glDeleteProgram(mProgram);
190 mProgram = 0;
191 }
Geoff Langb6a673a2014-06-05 14:19:16 -0400192 }
Jamie Madill3215b202015-12-15 16:41:39 -0500193
194 GLuint mFramebuffer;
195 GLuint mTexture;
196 GLuint mRenderbuffer;
197 GLuint mProgram;
Geoff Langb6a673a2014-06-05 14:19:16 -0400198};
199
Jamie Madillfa05f602015-05-07 13:47:11 -0400200TEST_P(FramebufferFormatsTest, RGBA4)
Geoff Langb6a673a2014-06-05 14:19:16 -0400201{
Geoff Langc4e93662017-05-01 10:45:59 -0400202 if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_storage"))
203 {
204 std::cout << "Test skipped due to missing ES3 or GL_EXT_texture_storage." << std::endl;
205 return;
206 }
207
Geoff Langb6a673a2014-06-05 14:19:16 -0400208 testTextureFormat(GL_RGBA4, 4, 4, 4, 4);
209}
210
Jamie Madillfa05f602015-05-07 13:47:11 -0400211TEST_P(FramebufferFormatsTest, RGB565)
Geoff Langb6a673a2014-06-05 14:19:16 -0400212{
Geoff Langc4e93662017-05-01 10:45:59 -0400213 if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_storage"))
214 {
215 std::cout << "Test skipped due to missing ES3 or GL_EXT_texture_storage." << std::endl;
216 return;
217 }
218
Geoff Langb6a673a2014-06-05 14:19:16 -0400219 testTextureFormat(GL_RGB565, 5, 6, 5, 0);
220}
221
Jamie Madillfa05f602015-05-07 13:47:11 -0400222TEST_P(FramebufferFormatsTest, RGB8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400223{
Geoff Langc4e93662017-05-01 10:45:59 -0400224 if (getClientMajorVersion() < 3 &&
225 (!extensionEnabled("GL_OES_rgb8_rgba8") || !extensionEnabled("GL_EXT_texture_storage")))
Geoff Langf34d1db2015-05-20 14:10:46 -0400226 {
Geoff Langc4e93662017-05-01 10:45:59 -0400227 std::cout
228 << "Test skipped due to missing ES3 or GL_OES_rgb8_rgba8 and GL_EXT_texture_storage."
229 << std::endl;
Geoff Langf34d1db2015-05-20 14:10:46 -0400230 return;
231 }
232
Geoff Langb6a673a2014-06-05 14:19:16 -0400233 testTextureFormat(GL_RGB8_OES, 8, 8, 8, 0);
234}
235
Jamie Madillfa05f602015-05-07 13:47:11 -0400236TEST_P(FramebufferFormatsTest, BGRA8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400237{
Geoff Langc4e93662017-05-01 10:45:59 -0400238 if (!extensionEnabled("GL_EXT_texture_format_BGRA8888") ||
239 (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_storage")))
Geoff Langf34d1db2015-05-20 14:10:46 -0400240 {
Geoff Langc4e93662017-05-01 10:45:59 -0400241 std::cout << "Test skipped due to missing GL_EXT_texture_format_BGRA8888 or "
242 "GL_EXT_texture_storage."
243 << std::endl;
Geoff Langf34d1db2015-05-20 14:10:46 -0400244 return;
245 }
246
Geoff Langb6a673a2014-06-05 14:19:16 -0400247 testTextureFormat(GL_BGRA8_EXT, 8, 8, 8, 8);
248}
249
Jamie Madillfa05f602015-05-07 13:47:11 -0400250TEST_P(FramebufferFormatsTest, RGBA8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400251{
Geoff Langc4e93662017-05-01 10:45:59 -0400252 if (getClientMajorVersion() < 3 &&
253 (!extensionEnabled("GL_OES_rgb8_rgba8") || !extensionEnabled("GL_EXT_texture_storage")))
Geoff Langf34d1db2015-05-20 14:10:46 -0400254 {
Geoff Langc4e93662017-05-01 10:45:59 -0400255 std::cout
256 << "Test skipped due to missing ES3 or GL_OES_rgb8_rgba8 and GL_EXT_texture_storage."
257 << std::endl;
Geoff Langf34d1db2015-05-20 14:10:46 -0400258 return;
259 }
260
Geoff Langb6a673a2014-06-05 14:19:16 -0400261 testTextureFormat(GL_RGBA8_OES, 8, 8, 8, 8);
262}
263
Jamie Madillfa05f602015-05-07 13:47:11 -0400264TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH16)
Corentin Walleze0902642014-11-04 12:32:15 -0800265{
266 testRenderbufferMultisampleFormat(2, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16);
267}
268
Jamie Madillfa05f602015-05-07 13:47:11 -0400269TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24)
Corentin Walleze0902642014-11-04 12:32:15 -0800270{
271 testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24);
272}
273
Jamie Madillfa05f602015-05-07 13:47:11 -0400274TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F)
Corentin Walleze0902642014-11-04 12:32:15 -0800275{
Martin Radev1be913c2016-07-11 17:59:16 +0300276 if (getClientMajorVersion() < 3)
Geoff Langf34d1db2015-05-20 14:10:46 -0400277 {
278 std::cout << "Test skipped due to missing ES3." << std::endl;
279 return;
280 }
281
Corentin Walleze0902642014-11-04 12:32:15 -0800282 testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32F);
283}
284
Jamie Madillfa05f602015-05-07 13:47:11 -0400285TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24_STENCIL8)
Corentin Walleze0902642014-11-04 12:32:15 -0800286{
287 testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8);
288}
289
Jamie Madillfa05f602015-05-07 13:47:11 -0400290TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F_STENCIL8)
Corentin Walleze0902642014-11-04 12:32:15 -0800291{
Martin Radev1be913c2016-07-11 17:59:16 +0300292 if (getClientMajorVersion() < 3)
Geoff Langf34d1db2015-05-20 14:10:46 -0400293 {
294 std::cout << "Test skipped due to missing ES3." << std::endl;
295 return;
296 }
297
Corentin Walleze0902642014-11-04 12:32:15 -0800298 testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH32F_STENCIL8);
299}
300
Jamie Madillfa05f602015-05-07 13:47:11 -0400301TEST_P(FramebufferFormatsTest, RenderbufferMultisample_STENCIL_INDEX8)
Corentin Walleze0902642014-11-04 12:32:15 -0800302{
Geoff Langf34d1db2015-05-20 14:10:46 -0400303 // TODO(geofflang): Figure out how to support GLSTENCIL_INDEX8 on desktop GL
Geoff Langdd323e92015-06-09 15:16:31 -0400304 if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Langf34d1db2015-05-20 14:10:46 -0400305 {
306 std::cout << "Test skipped on Desktop OpenGL." << std::endl;
307 return;
308 }
309
Corentin Walleze0902642014-11-04 12:32:15 -0800310 testRenderbufferMultisampleFormat(2, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8);
311}
Jamie Madillfa05f602015-05-07 13:47:11 -0400312
Jamie Madill3215b202015-12-15 16:41:39 -0500313// Test that binding an incomplete cube map is rejected by ANGLE.
314TEST_P(FramebufferFormatsTest, IncompleteCubeMap)
315{
316 // First make a complete CubeMap.
317 glGenTextures(1, &mTexture);
318 glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture);
319 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
320 nullptr);
321 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
322 nullptr);
323 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
324 nullptr);
325 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
326 nullptr);
327 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
328 nullptr);
329 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
330 nullptr);
331 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
332 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
333
334 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
335 mTexture, 0);
336
337 // Verify the framebuffer is complete.
338 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
339
340 // Make the CubeMap cube-incomplete.
341 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
342 nullptr);
343
344 // Verify the framebuffer is incomplete.
345 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
346 glCheckFramebufferStatus(GL_FRAMEBUFFER));
347
348 // Verify drawing with the incomplete framebuffer produces a GL error
349 const std::string &vs = "attribute vec4 position; void main() { gl_Position = position; }";
350 const std::string &ps = "void main() { gl_FragColor = vec4(1, 0, 0, 1); }";
351 mProgram = CompileProgram(vs, ps);
352 ASSERT_NE(0u, mProgram);
353 drawQuad(mProgram, "position", 0.5f);
354 ASSERT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
355}
356
Olli Etuahobc21e182016-02-23 16:04:57 +0200357// Test that a renderbuffer with zero height but nonzero width is handled without crashes/asserts.
358TEST_P(FramebufferFormatsTest, ZeroHeightRenderbuffer)
359{
Martin Radev1be913c2016-07-11 17:59:16 +0300360 if (getClientMajorVersion() < 3)
Olli Etuahobc21e182016-02-23 16:04:57 +0200361 {
362 std::cout << "Test skipped due to missing ES3" << std::endl;
363 return;
364 }
365
366 testZeroHeightRenderbuffer();
367}
368
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500369// Use this to select which configurations (e.g. which renderer, which GLES major version) these
370// tests should be run against.
Geoff Lange0cc2a42016-01-20 10:58:17 -0500371ANGLE_INSTANTIATE_TEST(FramebufferFormatsTest,
372 ES2_D3D9(),
373 ES2_D3D11(),
374 ES3_D3D11(),
375 ES2_OPENGL(),
376 ES3_OPENGL(),
377 ES2_OPENGLES(),
378 ES3_OPENGLES());
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500379
Corentin Wallez57e6d502016-12-09 14:46:39 -0500380class FramebufferTest_ES3 : public ANGLETest
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500381{
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500382};
383
384// Covers invalidating an incomplete framebuffer. This should be a no-op, but should not error.
Corentin Wallez57e6d502016-12-09 14:46:39 -0500385TEST_P(FramebufferTest_ES3, InvalidateIncomplete)
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500386{
Geoff Lang857c09d2017-05-16 15:55:04 -0400387 GLFramebuffer framebuffer;
388 GLRenderbuffer renderbuffer;
389
390 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
391 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
392 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500393 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
394 glCheckFramebufferStatus(GL_FRAMEBUFFER));
395
396 std::vector<GLenum> attachments;
397 attachments.push_back(GL_COLOR_ATTACHMENT0);
398
399 glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments.data());
400 EXPECT_GL_NO_ERROR();
401}
402
Corentin Wallez57e6d502016-12-09 14:46:39 -0500403// Test that the framebuffer state tracking robustly handles a depth-only attachment being set
404// as a depth-stencil attachment. It is equivalent to detaching the depth-stencil attachment.
405TEST_P(FramebufferTest_ES3, DepthOnlyAsDepthStencil)
406{
Geoff Lang857c09d2017-05-16 15:55:04 -0400407 GLFramebuffer framebuffer;
408 GLRenderbuffer renderbuffer;
409
410 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
411 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
Corentin Wallez57e6d502016-12-09 14:46:39 -0500412 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 4, 4);
413
414 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
Geoff Lang857c09d2017-05-16 15:55:04 -0400415 renderbuffer);
Corentin Wallez57e6d502016-12-09 14:46:39 -0500416 EXPECT_GLENUM_NE(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
417}
418
Geoff Lang857c09d2017-05-16 15:55:04 -0400419// Test that the framebuffer correctly returns that it is not complete if invalid texture mip levels
420// are bound
421TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevels)
422{
423 GLFramebuffer framebuffer;
424 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
425
426 GLTexture texture;
427 glBindTexture(GL_TEXTURE_2D, texture);
428
429 // Create a complete mip chain in mips 1 to 3
430 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
431 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
432 glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
433
434 // Create another complete mip chain in mips 4 to 5
435 glTexImage2D(GL_TEXTURE_2D, 4, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
436 glTexImage2D(GL_TEXTURE_2D, 5, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
437
438 // Create a non-complete mip chain in mip 6
439 glTexImage2D(GL_TEXTURE_2D, 6, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
440
441 // Incomplete, mipLevel != baseLevel and texture is not mip complete
442 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
443 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
444 glCheckFramebufferStatus(GL_FRAMEBUFFER));
445
446 // Complete, mipLevel == baseLevel
447 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
448 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
449
450 // Complete, mipLevel != baseLevel but texture is now mip complete
451 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 2);
452 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
453 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 3);
454 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
455
456 // Incomplete, attached level below the base level
457 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
458 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
459 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
460 glCheckFramebufferStatus(GL_FRAMEBUFFER));
461
462 // Incomplete, attached level is beyond effective max level
463 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 4);
464 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
465 glCheckFramebufferStatus(GL_FRAMEBUFFER));
466
467 // Complete, mipLevel == baseLevel
468 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 4);
469 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
470
471 // Complete, mipLevel != baseLevel but texture is now mip complete
472 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 5);
473 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
474
475 // Complete, mipLevel == baseLevel
476 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 6);
477 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 6);
478 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
479}
480
Corentin Wallez57e6d502016-12-09 14:46:39 -0500481ANGLE_INSTANTIATE_TEST(FramebufferTest_ES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
JiangYizhou461d9a32017-01-04 16:37:26 +0800482
483class FramebufferTest_ES31 : public ANGLETest
484{
485};
486
487// Test that without attachment, if either the value of FRAMEBUFFER_DEFAULT_WIDTH or
488// FRAMEBUFFER_DEFAULT_HEIGHT parameters is zero, the framebuffer is incomplete.
489TEST_P(FramebufferTest_ES31, IncompleteMissingAttachmentDefaultParam)
490{
491 GLFramebuffer mFramebuffer;
492 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
493
494 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 1);
495 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 1);
496 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
497
498 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
499 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 0);
500 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
501 glCheckFramebufferStatus(GL_FRAMEBUFFER));
502
503 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 1);
504 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 0);
505 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
506 glCheckFramebufferStatus(GL_FRAMEBUFFER));
507
508 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
509 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 1);
510 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
511 glCheckFramebufferStatus(GL_FRAMEBUFFER));
512
513 ASSERT_GL_NO_ERROR();
514}
515
516// Test that the sample count of a mix of texture and renderbuffer should be same.
517TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountMix)
518{
519 GLFramebuffer mFramebuffer;
520 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
521
522 GLTexture mTexture;
523 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture.get());
524 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, true);
525
526 GLRenderbuffer mRenderbuffer;
527 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer.get());
528 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 1, 1);
529 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
530 mTexture.get(), 0);
531 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
532 mRenderbuffer.get());
533 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
534 glCheckFramebufferStatus(GL_FRAMEBUFFER));
535
536 ASSERT_GL_NO_ERROR();
537}
538
539// Test that the sample count of texture attachments should be same.
540TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountTex)
541{
542 GLFramebuffer mFramebuffer;
543 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
544
545 GLTexture mTextures[2];
546 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[0].get());
547 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, true);
548 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[1].get());
549 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_RGBA8, 1, 1, true);
550 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
551 mTextures[0].get(), 0);
552 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
553 mTextures[1].get(), 0);
554 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
555 glCheckFramebufferStatus(GL_FRAMEBUFFER));
556
557 ASSERT_GL_NO_ERROR();
558}
559
560// Test that if the attached images are a mix of renderbuffers and textures, the value of
561// TEXTURE_FIXED_SAMPLE_LOCATIONS must be TRUE for all attached textures.
562TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsMix)
563{
564 GLFramebuffer mFramebuffer;
565 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
566
567 GLTexture mTexture;
568 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture.get());
569 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, false);
570
571 GLRenderbuffer mRenderbuffer;
572 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer.get());
573 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 1, GL_RGBA8, 1, 1);
574 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
575 mTexture.get(), 0);
576 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
577 mRenderbuffer.get());
578 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
579 glCheckFramebufferStatus(GL_FRAMEBUFFER));
580
581 ASSERT_GL_NO_ERROR();
582}
583
584// Test that the value of TEXTURE_FIXED_SAMPLE_LOCATIONS is the same for all attached textures.
585TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsTex)
586{
587 GLFramebuffer mFramebuffer;
588 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
589
590 GLTexture mTextures[2];
591 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[0].get());
592 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, false);
593 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
594 mTextures[0].get(), 0);
595 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[1].get());
596 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGB8, 1, 1, true);
597 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
598 mTextures[1].get(), 0);
599 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
600 glCheckFramebufferStatus(GL_FRAMEBUFFER));
601
602 ASSERT_GL_NO_ERROR();
603}
604
605ANGLE_INSTANTIATE_TEST(FramebufferTest_ES31, ES31_OPENGL(), ES31_OPENGLES());