blob: 0fa31828bbe34b330861115c7a56afc630f45a69 [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
Brandon Jones9fc87332017-12-13 15:46:52 -080010#include "platform/WorkaroundsD3D.h"
Corentin Wallezd3970de2015-05-14 11:07:48 -040011#include "test_utils/ANGLETest.h"
JiangYizhou461d9a32017-01-04 16:37:26 +080012#include "test_utils/gl_raii.h"
Geoff Langb6a673a2014-06-05 14:19:16 -040013
Jamie Madillfa05f602015-05-07 13:47:11 -040014using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070015
Geoff Lang857c09d2017-05-16 15:55:04 -040016namespace
17{
18
19void ExpectFramebufferCompleteOrUnsupported(GLenum binding)
20{
21 GLenum status = glCheckFramebufferStatus(binding);
22 EXPECT_TRUE(status == GL_FRAMEBUFFER_COMPLETE || status == GL_FRAMEBUFFER_UNSUPPORTED);
23}
24
25} // anonymous namespace
26
Geoff Langb6a673a2014-06-05 14:19:16 -040027class FramebufferFormatsTest : public ANGLETest
28{
Jamie Madillfa05f602015-05-07 13:47:11 -040029 protected:
Jamie Madill3215b202015-12-15 16:41:39 -050030 FramebufferFormatsTest() : mFramebuffer(0), mTexture(0), mRenderbuffer(0), mProgram(0)
Geoff Langb6a673a2014-06-05 14:19:16 -040031 {
32 setWindowWidth(128);
33 setWindowHeight(128);
34 setConfigRedBits(8);
35 setConfigGreenBits(8);
36 setConfigBlueBits(8);
37 setConfigAlphaBits(8);
38 }
39
40 void checkBitCount(GLuint fbo, GLenum channel, GLint minBits)
41 {
42 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
43
44 GLint bits = 0;
45 glGetIntegerv(channel, &bits);
46
47 if (minBits == 0)
48 {
49 EXPECT_EQ(minBits, bits);
50 }
51 else
52 {
53 EXPECT_GE(bits, minBits);
54 }
55 }
56
Jamie Madill1fbc59f2016-02-24 15:25:51 -050057 void testBitCounts(GLuint fbo,
58 GLint minRedBits,
59 GLint minGreenBits,
60 GLint minBlueBits,
61 GLint minAlphaBits,
62 GLint minDepthBits,
63 GLint minStencilBits)
Geoff Langb6a673a2014-06-05 14:19:16 -040064 {
65 checkBitCount(fbo, GL_RED_BITS, minRedBits);
66 checkBitCount(fbo, GL_GREEN_BITS, minGreenBits);
67 checkBitCount(fbo, GL_BLUE_BITS, minBlueBits);
68 checkBitCount(fbo, GL_ALPHA_BITS, minAlphaBits);
69 checkBitCount(fbo, GL_DEPTH_BITS, minDepthBits);
70 checkBitCount(fbo, GL_STENCIL_BITS, minStencilBits);
71 }
72
Jamie Madill1fbc59f2016-02-24 15:25:51 -050073 void testTextureFormat(GLenum internalFormat,
74 GLint minRedBits,
75 GLint minGreenBits,
76 GLint minBlueBits,
Geoff Langb6a673a2014-06-05 14:19:16 -040077 GLint minAlphaBits)
78 {
Jamie Madill3215b202015-12-15 16:41:39 -050079 glGenTextures(1, &mTexture);
80 glBindTexture(GL_TEXTURE_2D, mTexture);
Geoff Langc4e93662017-05-01 10:45:59 -040081
82 if (getClientMajorVersion() >= 3)
83 {
84 glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
85 }
86 else
87 {
88 glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
89 }
Geoff Langb6a673a2014-06-05 14:19:16 -040090
Jamie Madill3215b202015-12-15 16:41:39 -050091 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
Geoff Langb6a673a2014-06-05 14:19:16 -040092
Jamie Madill3215b202015-12-15 16:41:39 -050093 testBitCounts(mFramebuffer, minRedBits, minGreenBits, minBlueBits, minAlphaBits, 0, 0);
Geoff Langb6a673a2014-06-05 14:19:16 -040094 }
95
Jamie Madill1fbc59f2016-02-24 15:25:51 -050096 void testRenderbufferMultisampleFormat(int minESVersion,
97 GLenum attachmentType,
98 GLenum internalFormat)
Corentin Walleze0902642014-11-04 12:32:15 -080099 {
Martin Radev1be913c2016-07-11 17:59:16 +0300100 int clientVersion = getClientMajorVersion();
Jamie Madillfa05f602015-05-07 13:47:11 -0400101 if (clientVersion < minESVersion)
Corentin Walleze0902642014-11-04 12:32:15 -0800102 {
103 return;
104 }
105
106 // Check that multisample is supported with at least two samples (minimum required is 1)
107 bool supports2Samples = false;
108
Jamie Madillfa05f602015-05-07 13:47:11 -0400109 if (clientVersion == 2)
Corentin Walleze0902642014-11-04 12:32:15 -0800110 {
Jamie Madillb8149072019-04-30 16:14:44 -0400111 if (IsGLExtensionEnabled("ANGLE_framebuffer_multisample"))
Corentin Walleze0902642014-11-04 12:32:15 -0800112 {
113 int maxSamples;
114 glGetIntegerv(GL_MAX_SAMPLES_ANGLE, &maxSamples);
115 supports2Samples = maxSamples >= 2;
116 }
117 }
118 else
119 {
Jamie Madillfa05f602015-05-07 13:47:11 -0400120 assert(clientVersion >= 3);
Corentin Walleze0902642014-11-04 12:32:15 -0800121 int maxSamples;
122 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
123 supports2Samples = maxSamples >= 2;
124 }
125
126 if (!supports2Samples)
127 {
128 return;
129 }
130
Jamie Madill3215b202015-12-15 16:41:39 -0500131 glGenRenderbuffers(1, &mRenderbuffer);
132 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
Corentin Walleze0902642014-11-04 12:32:15 -0800133
134 EXPECT_GL_NO_ERROR();
135 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, internalFormat, 128, 128);
136 EXPECT_GL_NO_ERROR();
Jamie Madill3215b202015-12-15 16:41:39 -0500137 glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachmentType, GL_RENDERBUFFER, mRenderbuffer);
Corentin Walleze0902642014-11-04 12:32:15 -0800138 EXPECT_GL_NO_ERROR();
Corentin Walleze0902642014-11-04 12:32:15 -0800139 }
140
Olli Etuahobc21e182016-02-23 16:04:57 +0200141 void testZeroHeightRenderbuffer()
142 {
143 glGenRenderbuffers(1, &mRenderbuffer);
144 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
145 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 0);
146 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
147 mRenderbuffer);
148 EXPECT_GL_NO_ERROR();
149 }
150
Jamie Madill3215b202015-12-15 16:41:39 -0500151 void SetUp() override
Geoff Langb6a673a2014-06-05 14:19:16 -0400152 {
153 ANGLETest::SetUp();
Jamie Madill3215b202015-12-15 16:41:39 -0500154
155 glGenFramebuffers(1, &mFramebuffer);
156 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
Geoff Langb6a673a2014-06-05 14:19:16 -0400157 }
158
Jamie Madill3215b202015-12-15 16:41:39 -0500159 void TearDown() override
Geoff Langb6a673a2014-06-05 14:19:16 -0400160 {
161 ANGLETest::TearDown();
Jamie Madill3215b202015-12-15 16:41:39 -0500162
163 if (mTexture != 0)
164 {
165 glDeleteTextures(1, &mTexture);
166 mTexture = 0;
167 }
168
169 if (mRenderbuffer != 0)
170 {
171 glDeleteRenderbuffers(1, &mRenderbuffer);
172 mRenderbuffer = 0;
173 }
174
175 if (mFramebuffer != 0)
176 {
177 glDeleteFramebuffers(1, &mFramebuffer);
178 mFramebuffer = 0;
179 }
180
181 if (mProgram != 0)
182 {
183 glDeleteProgram(mProgram);
184 mProgram = 0;
185 }
Geoff Langb6a673a2014-06-05 14:19:16 -0400186 }
Jamie Madill3215b202015-12-15 16:41:39 -0500187
188 GLuint mFramebuffer;
189 GLuint mTexture;
190 GLuint mRenderbuffer;
191 GLuint mProgram;
Geoff Langb6a673a2014-06-05 14:19:16 -0400192};
193
Jamie Madillfa05f602015-05-07 13:47:11 -0400194TEST_P(FramebufferFormatsTest, RGBA4)
Geoff Langb6a673a2014-06-05 14:19:16 -0400195{
Jamie Madillb8149072019-04-30 16:14:44 -0400196 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
197 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
Geoff Langc4e93662017-05-01 10:45:59 -0400198
Geoff Langb6a673a2014-06-05 14:19:16 -0400199 testTextureFormat(GL_RGBA4, 4, 4, 4, 4);
200}
201
Jamie Madillfa05f602015-05-07 13:47:11 -0400202TEST_P(FramebufferFormatsTest, RGB565)
Geoff Langb6a673a2014-06-05 14:19:16 -0400203{
Jamie Madillb8149072019-04-30 16:14:44 -0400204 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
205 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
Geoff Langc4e93662017-05-01 10:45:59 -0400206
Geoff Langb6a673a2014-06-05 14:19:16 -0400207 testTextureFormat(GL_RGB565, 5, 6, 5, 0);
208}
209
Jamie Madillfa05f602015-05-07 13:47:11 -0400210TEST_P(FramebufferFormatsTest, RGB8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400211{
Jamie Madillb8149072019-04-30 16:14:44 -0400212 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
213 (!IsGLExtensionEnabled("GL_OES_rgb8_rgba8") ||
214 !IsGLExtensionEnabled("GL_EXT_texture_storage")));
Geoff Langf34d1db2015-05-20 14:10:46 -0400215
Geoff Langb6a673a2014-06-05 14:19:16 -0400216 testTextureFormat(GL_RGB8_OES, 8, 8, 8, 0);
217}
218
Jamie Madillfa05f602015-05-07 13:47:11 -0400219TEST_P(FramebufferFormatsTest, BGRA8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400220{
Yunchao He9550c602018-02-13 14:47:05 +0800221 ANGLE_SKIP_TEST_IF(
Jamie Madillb8149072019-04-30 16:14:44 -0400222 !IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888") ||
223 (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_texture_storage")));
Geoff Langf34d1db2015-05-20 14:10:46 -0400224
Geoff Langb6a673a2014-06-05 14:19:16 -0400225 testTextureFormat(GL_BGRA8_EXT, 8, 8, 8, 8);
226}
227
Jamie Madillfa05f602015-05-07 13:47:11 -0400228TEST_P(FramebufferFormatsTest, RGBA8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400229{
Jamie Madillb8149072019-04-30 16:14:44 -0400230 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
231 (!IsGLExtensionEnabled("GL_OES_rgb8_rgba8") ||
232 !IsGLExtensionEnabled("GL_EXT_texture_storage")));
Geoff Langf34d1db2015-05-20 14:10:46 -0400233
Geoff Langb6a673a2014-06-05 14:19:16 -0400234 testTextureFormat(GL_RGBA8_OES, 8, 8, 8, 8);
235}
236
Jamie Madillfa05f602015-05-07 13:47:11 -0400237TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH16)
Corentin Walleze0902642014-11-04 12:32:15 -0800238{
239 testRenderbufferMultisampleFormat(2, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16);
240}
241
Jamie Madillfa05f602015-05-07 13:47:11 -0400242TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24)
Corentin Walleze0902642014-11-04 12:32:15 -0800243{
244 testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24);
245}
246
Jamie Madillfa05f602015-05-07 13:47:11 -0400247TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F)
Corentin Walleze0902642014-11-04 12:32:15 -0800248{
Yunchao He9550c602018-02-13 14:47:05 +0800249 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
Geoff Langf34d1db2015-05-20 14:10:46 -0400250
Corentin Walleze0902642014-11-04 12:32:15 -0800251 testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32F);
252}
253
Jamie Madillfa05f602015-05-07 13:47:11 -0400254TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24_STENCIL8)
Corentin Walleze0902642014-11-04 12:32:15 -0800255{
256 testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8);
257}
258
Jamie Madillfa05f602015-05-07 13:47:11 -0400259TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F_STENCIL8)
Corentin Walleze0902642014-11-04 12:32:15 -0800260{
Yunchao He9550c602018-02-13 14:47:05 +0800261 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
Geoff Langf34d1db2015-05-20 14:10:46 -0400262
Corentin Walleze0902642014-11-04 12:32:15 -0800263 testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH32F_STENCIL8);
264}
265
Jamie Madillfa05f602015-05-07 13:47:11 -0400266TEST_P(FramebufferFormatsTest, RenderbufferMultisample_STENCIL_INDEX8)
Corentin Walleze0902642014-11-04 12:32:15 -0800267{
Geoff Langf34d1db2015-05-20 14:10:46 -0400268 // TODO(geofflang): Figure out how to support GLSTENCIL_INDEX8 on desktop GL
Yunchao He9550c602018-02-13 14:47:05 +0800269 ANGLE_SKIP_TEST_IF(IsDesktopOpenGL());
Geoff Langf34d1db2015-05-20 14:10:46 -0400270
Corentin Walleze0902642014-11-04 12:32:15 -0800271 testRenderbufferMultisampleFormat(2, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8);
272}
Jamie Madillfa05f602015-05-07 13:47:11 -0400273
Jamie Madill3215b202015-12-15 16:41:39 -0500274// Test that binding an incomplete cube map is rejected by ANGLE.
275TEST_P(FramebufferFormatsTest, IncompleteCubeMap)
276{
Michael Spangd8506c72019-01-29 15:35:09 -0500277 // http://anglebug.com/3145
278 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
279
Jamie Madill3215b202015-12-15 16:41:39 -0500280 // First make a complete CubeMap.
281 glGenTextures(1, &mTexture);
282 glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture);
283 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
284 nullptr);
285 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
286 nullptr);
287 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
288 nullptr);
289 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
290 nullptr);
291 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
292 nullptr);
293 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
294 nullptr);
295 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
296 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
297
298 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
299 mTexture, 0);
300
301 // Verify the framebuffer is complete.
302 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
303
304 // Make the CubeMap cube-incomplete.
305 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
306 nullptr);
307
308 // Verify the framebuffer is incomplete.
309 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
310 glCheckFramebufferStatus(GL_FRAMEBUFFER));
311
Jamie Madilld84b6732018-09-06 15:54:35 -0400312 ASSERT_GL_NO_ERROR();
313
Jamie Madill3215b202015-12-15 16:41:39 -0500314 // Verify drawing with the incomplete framebuffer produces a GL error
Olli Etuaho5804dc82018-04-13 14:11:46 +0300315 mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
Jamie Madill3215b202015-12-15 16:41:39 -0500316 ASSERT_NE(0u, mProgram);
Olli Etuaho5804dc82018-04-13 14:11:46 +0300317 drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
Jamie Madill3215b202015-12-15 16:41:39 -0500318 ASSERT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
319}
320
Olli Etuahobc21e182016-02-23 16:04:57 +0200321// Test that a renderbuffer with zero height but nonzero width is handled without crashes/asserts.
322TEST_P(FramebufferFormatsTest, ZeroHeightRenderbuffer)
323{
Yunchao He9550c602018-02-13 14:47:05 +0800324 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
Olli Etuahobc21e182016-02-23 16:04:57 +0200325
326 testZeroHeightRenderbuffer();
327}
328
Geoff Lang9bf86f02018-07-26 11:46:34 -0400329// Test to cover a bug where the read framebuffer affects the completeness of the draw framebuffer.
330TEST_P(FramebufferFormatsTest, ReadDrawCompleteness)
331{
332 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
333
334 GLTexture incompleteTexture;
335 glBindTexture(GL_TEXTURE_2D, incompleteTexture);
336
337 GLFramebuffer incompleteFBO;
338 glBindFramebuffer(GL_FRAMEBUFFER, incompleteFBO);
339 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, incompleteTexture,
340 0);
341 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
342 glCheckFramebufferStatus(GL_FRAMEBUFFER));
343
344 GLTexture completeTexture;
345 glBindTexture(GL_TEXTURE_2D, completeTexture);
346 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
347
348 GLFramebuffer completeFBO;
349 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, completeFBO);
350 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
351 completeTexture, 0);
352
353 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
354 glCheckFramebufferStatus(GL_READ_FRAMEBUFFER));
355 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
356
357 ASSERT_GL_NO_ERROR();
358
359 // Simple draw program.
360 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
361
362 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f, 1.0f, true);
363 EXPECT_GL_NO_ERROR();
364
365 glBindFramebuffer(GL_READ_FRAMEBUFFER, completeFBO);
366 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
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,
Luc Ferronfa7503c2018-05-08 11:25:06 -0400372 ES2_VULKAN(),
Geoff Lange0cc2a42016-01-20 10:58:17 -0500373 ES2_D3D9(),
374 ES2_D3D11(),
375 ES3_D3D11(),
376 ES2_OPENGL(),
377 ES3_OPENGL(),
378 ES2_OPENGLES(),
379 ES3_OPENGLES());
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500380
Corentin Wallez57e6d502016-12-09 14:46:39 -0500381class FramebufferTest_ES3 : public ANGLETest
Jamie Madillb980c562018-11-27 11:34:27 -0500382{};
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500383
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
Martin Radevd178aa42017-07-13 14:03:22 +0300481// Test that passing an attachment COLOR_ATTACHMENTm where m is equal to MAX_COLOR_ATTACHMENTS
482// generates an INVALID_OPERATION.
483// OpenGL ES Version 3.0.5 (November 3, 2016), 4.4.2.4 Attaching Texture Images to a Framebuffer, p.
484// 208
485TEST_P(FramebufferTest_ES3, ColorAttachmentIndexOutOfBounds)
486{
487 GLFramebuffer framebuffer;
488 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
489
490 GLint maxColorAttachments = 0;
491 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
492 GLenum attachment = static_cast<GLenum>(maxColorAttachments + GL_COLOR_ATTACHMENT0);
493
494 GLTexture texture;
495 glBindTexture(GL_TEXTURE_2D, texture.get());
496 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
497 glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture.get(), 0);
498 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
499}
500
Jamie Madilla0016b72017-07-14 14:30:46 -0400501// Check that depth-only attachments report the correct number of samples.
502TEST_P(FramebufferTest_ES3, MultisampleDepthOnly)
503{
504 GLRenderbuffer renderbuffer;
505 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
506 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 32, 32);
507
508 GLFramebuffer framebuffer;
509 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
510 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
511 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
512 EXPECT_GL_NO_ERROR();
513
514 GLint samples = 0;
515 glGetIntegerv(GL_SAMPLES, &samples);
516 EXPECT_GL_NO_ERROR();
517 EXPECT_GE(samples, 2);
518}
519
Jeff Gilbert8f8edd62017-10-31 14:26:30 -0700520// Check that we only compare width and height of attachments, not depth.
521TEST_P(FramebufferTest_ES3, AttachmentWith3DLayers)
522{
523 GLTexture texA;
524 glBindTexture(GL_TEXTURE_2D, texA);
525 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
526
527 GLTexture texB;
528 glBindTexture(GL_TEXTURE_3D, texB);
529 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 4, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
530
531 GLFramebuffer framebuffer;
532 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
533 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texA, 0);
534 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texB, 0, 0);
535 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
536 EXPECT_GL_NO_ERROR();
537}
538
Olli Etuahodbce1f82018-09-19 15:32:17 +0300539// Test that clearing the stencil buffer when the framebuffer only has a color attachment does not
540// crash.
541TEST_P(FramebufferTest_ES3, ClearNonexistentStencil)
542{
543 GLRenderbuffer rbo;
544 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
545 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
546
547 GLFramebuffer fbo;
548 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
549 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
550
551 GLint clearValue = 0;
552 glClearBufferiv(GL_STENCIL, 0, &clearValue);
553
554 // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
555 EXPECT_GL_NO_ERROR();
556}
557
558// Test that clearing the depth buffer when the framebuffer only has a color attachment does not
559// crash.
560TEST_P(FramebufferTest_ES3, ClearNonexistentDepth)
561{
562 GLRenderbuffer rbo;
563 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
564 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
565
566 GLFramebuffer fbo;
567 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
568 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
569
570 GLfloat clearValue = 0.0f;
571 glClearBufferfv(GL_DEPTH, 0, &clearValue);
572
573 // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
574 EXPECT_GL_NO_ERROR();
575}
576
577// Test that clearing a nonexistent color attachment does not crash.
578TEST_P(FramebufferTest_ES3, ClearNonexistentColor)
579{
580 GLRenderbuffer rbo;
581 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
582 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
583
584 GLFramebuffer fbo;
585 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
586 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
587
588 std::vector<GLfloat> clearValue = {{0.0f, 1.0f, 0.0f, 1.0f}};
589 glClearBufferfv(GL_COLOR, 1, clearValue.data());
590
591 // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
592 EXPECT_GL_NO_ERROR();
593}
594
595// Test that clearing the depth and stencil buffers when the framebuffer only has a color attachment
596// does not crash.
597TEST_P(FramebufferTest_ES3, ClearNonexistentDepthStencil)
598{
599 GLRenderbuffer rbo;
600 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
601 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
602
603 GLFramebuffer fbo;
604 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
605 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
606
607 glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0);
608
609 // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
610 EXPECT_GL_NO_ERROR();
611}
612
Olli Etuaho4ebd8f32018-09-20 11:12:46 +0300613// Test that clearing a color attachment that has been deleted doesn't crash.
614TEST_P(FramebufferTest_ES3, ClearDeletedAttachment)
615{
616 // An INVALID_FRAMEBUFFER_OPERATION error was seen in this test on Mac, not sure where it might
617 // be originating from. http://anglebug.com/2834
618 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
619
620 GLFramebuffer fbo;
621 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
622
623 // There used to be a bug where some draw buffer state used to remain set even after the
624 // attachment was detached via deletion. That's why we create, attach and delete this RBO here.
625 GLuint rbo = 0u;
626 glGenRenderbuffers(1, &rbo);
627 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
628 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
629 glDeleteRenderbuffers(1, &rbo);
630
631 // There needs to be at least one color attachment to prevent early out from the clear calls.
632 GLRenderbuffer rbo2;
633 glBindRenderbuffer(GL_RENDERBUFFER, rbo2);
634 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
635 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rbo2);
636
637 ASSERT_GL_NO_ERROR();
638
639 // There's no error specified for clearing nonexistent buffers, it's simply a no-op, so we
640 // expect no GL errors below.
641 std::array<GLfloat, 4> floatClearValue = {0.0f, 0.0f, 0.0f, 0.0f};
642 glClearBufferfv(GL_COLOR, 0, floatClearValue.data());
643 EXPECT_GL_NO_ERROR();
644 std::array<GLuint, 4> uintClearValue = {0u, 0u, 0u, 0u};
645 glClearBufferuiv(GL_COLOR, 0, uintClearValue.data());
646 EXPECT_GL_NO_ERROR();
647 std::array<GLint, 4> intClearValue = {0, 0, 0, 0};
648 glClearBufferiv(GL_COLOR, 0, intClearValue.data());
649 EXPECT_GL_NO_ERROR();
650}
651
Corentin Wallez57e6d502016-12-09 14:46:39 -0500652ANGLE_INSTANTIATE_TEST(FramebufferTest_ES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
JiangYizhou461d9a32017-01-04 16:37:26 +0800653
654class FramebufferTest_ES31 : public ANGLETest
655{
JiangYizhou511937d2017-08-03 15:41:29 +0800656 protected:
657 void validateSamplePass(GLuint &query, GLuint &passedCount, GLint width, GLint height)
658 {
659 glUniform2i(0, width - 1, height - 1);
660 glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
661 glDrawArrays(GL_TRIANGLES, 0, 6);
662 glEndQuery(GL_ANY_SAMPLES_PASSED);
663 glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
664 EXPECT_GT(static_cast<GLint>(passedCount), 0);
665
666 glUniform2i(0, width - 1, height);
667 glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
668 glDrawArrays(GL_TRIANGLES, 0, 6);
669 glEndQuery(GL_ANY_SAMPLES_PASSED);
670 glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
671 EXPECT_EQ(static_cast<GLint>(passedCount), 0);
672
673 glUniform2i(0, width, height - 1);
674 glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
675 glDrawArrays(GL_TRIANGLES, 0, 6);
676 glEndQuery(GL_ANY_SAMPLES_PASSED);
677 glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
678 EXPECT_EQ(static_cast<GLint>(passedCount), 0);
679 }
JiangYizhou461d9a32017-01-04 16:37:26 +0800680};
681
682// Test that without attachment, if either the value of FRAMEBUFFER_DEFAULT_WIDTH or
683// FRAMEBUFFER_DEFAULT_HEIGHT parameters is zero, the framebuffer is incomplete.
684TEST_P(FramebufferTest_ES31, IncompleteMissingAttachmentDefaultParam)
685{
686 GLFramebuffer mFramebuffer;
687 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
688
689 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 1);
690 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 1);
691 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
692
693 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
694 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 0);
695 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
696 glCheckFramebufferStatus(GL_FRAMEBUFFER));
697
698 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 1);
699 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 0);
700 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
701 glCheckFramebufferStatus(GL_FRAMEBUFFER));
702
703 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
704 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 1);
705 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
706 glCheckFramebufferStatus(GL_FRAMEBUFFER));
707
708 ASSERT_GL_NO_ERROR();
709}
710
711// Test that the sample count of a mix of texture and renderbuffer should be same.
712TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountMix)
713{
714 GLFramebuffer mFramebuffer;
715 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
716
717 GLTexture mTexture;
718 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture.get());
719 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, true);
720
721 GLRenderbuffer mRenderbuffer;
722 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer.get());
723 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 1, 1);
724 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
725 mTexture.get(), 0);
726 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
727 mRenderbuffer.get());
728 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
729 glCheckFramebufferStatus(GL_FRAMEBUFFER));
730
731 ASSERT_GL_NO_ERROR();
732}
733
734// Test that the sample count of texture attachments should be same.
735TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountTex)
736{
737 GLFramebuffer mFramebuffer;
738 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
739
740 GLTexture mTextures[2];
741 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[0].get());
742 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, true);
743 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[1].get());
744 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_RGBA8, 1, 1, true);
745 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
746 mTextures[0].get(), 0);
747 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
748 mTextures[1].get(), 0);
749 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
750 glCheckFramebufferStatus(GL_FRAMEBUFFER));
751
752 ASSERT_GL_NO_ERROR();
753}
754
755// Test that if the attached images are a mix of renderbuffers and textures, the value of
756// TEXTURE_FIXED_SAMPLE_LOCATIONS must be TRUE for all attached textures.
757TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsMix)
758{
759 GLFramebuffer mFramebuffer;
760 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
761
762 GLTexture mTexture;
763 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture.get());
764 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, false);
765
766 GLRenderbuffer mRenderbuffer;
767 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer.get());
768 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 1, GL_RGBA8, 1, 1);
769 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
770 mTexture.get(), 0);
771 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
772 mRenderbuffer.get());
773 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
774 glCheckFramebufferStatus(GL_FRAMEBUFFER));
775
776 ASSERT_GL_NO_ERROR();
777}
778
779// Test that the value of TEXTURE_FIXED_SAMPLE_LOCATIONS is the same for all attached textures.
780TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsTex)
781{
782 GLFramebuffer mFramebuffer;
783 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
784
785 GLTexture mTextures[2];
786 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[0].get());
787 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, false);
788 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
789 mTextures[0].get(), 0);
790 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[1].get());
791 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGB8, 1, 1, true);
792 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
793 mTextures[1].get(), 0);
794 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
795 glCheckFramebufferStatus(GL_FRAMEBUFFER));
796
797 ASSERT_GL_NO_ERROR();
798}
799
JiangYizhou511937d2017-08-03 15:41:29 +0800800// If there are no attachments, rendering will be limited to a rectangle having a lower left of
801// (0, 0) and an upper right of(width, height), where width and height are the framebuffer
802// object's default width and height.
JiangYizhou3db40722017-08-28 17:59:13 +0800803TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments)
JiangYizhou511937d2017-08-03 15:41:29 +0800804{
Yuly Novikov98f9f532017-11-15 19:16:19 -0500805 // anglebug.com/2253
806 ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
807
Jamie Madill35cd7332018-12-02 12:03:33 -0500808 constexpr char kVS1[] = R"(#version 310 es
809in layout(location = 0) highp vec2 a_position;
810void main()
811{
812 gl_Position = vec4(a_position, 0.0, 1.0);
813})";
JiangYizhou511937d2017-08-03 15:41:29 +0800814
Jamie Madill35cd7332018-12-02 12:03:33 -0500815 constexpr char kFS1[] = R"(#version 310 es
816uniform layout(location = 0) highp ivec2 u_expectedSize;
817out layout(location = 5) mediump vec4 f_color;
818void main()
819{
820 if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;
821 f_color = vec4(1.0, 0.5, 0.25, 1.0);
822})";
JiangYizhou511937d2017-08-03 15:41:29 +0800823
Jamie Madill35cd7332018-12-02 12:03:33 -0500824 constexpr char kVS2[] = R"(#version 310 es
825in layout(location = 0) highp vec2 a_position;
826void main()
827{
828 gl_Position = vec4(a_position, 0.0, 1.0);
829})";
JiangYizhou10d41392017-12-18 18:13:36 +0800830
Jamie Madill35cd7332018-12-02 12:03:33 -0500831 constexpr char kFS2[] = R"(#version 310 es
832uniform layout(location = 0) highp ivec2 u_expectedSize;
833out layout(location = 2) mediump vec4 f_color;
834void main()
835{
836 if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;
837 f_color = vec4(1.0, 0.5, 0.25, 1.0);
838})";
JiangYizhou10d41392017-12-18 18:13:36 +0800839
Jamie Madill35cd7332018-12-02 12:03:33 -0500840 GLuint program1 = CompileProgram(kVS1, kFS1);
JiangYizhou10d41392017-12-18 18:13:36 +0800841 ASSERT_NE(program1, 0u);
842
Jamie Madill35cd7332018-12-02 12:03:33 -0500843 GLuint program2 = CompileProgram(kVS2, kFS2);
JiangYizhou10d41392017-12-18 18:13:36 +0800844 ASSERT_NE(program2, 0u);
845
846 glUseProgram(program1);
JiangYizhou511937d2017-08-03 15:41:29 +0800847
848 GLFramebuffer mFramebuffer;
849 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
850 GLuint defaultWidth = 1;
851 GLuint defaultHeight = 1;
852
853 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, defaultWidth);
854 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, defaultHeight);
855 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
856
857 const float data[] = {
858 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f,
859 };
860
861 GLuint vertexArray = 0;
862 GLuint vertexBuffer = 0;
863 GLuint query = 0;
864 GLuint passedCount = 0;
865
866 glGenQueries(1, &query);
867 glGenVertexArrays(1, &vertexArray);
868 glBindVertexArray(vertexArray);
869
870 glGenBuffers(1, &vertexBuffer);
871 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
872 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
873
874 glEnableVertexAttribArray(0);
875 glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
JiangYizhou38d92b52017-09-13 13:47:52 +0800876 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
JiangYizhou511937d2017-08-03 15:41:29 +0800877
878 validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
879
JiangYizhou10d41392017-12-18 18:13:36 +0800880 glUseProgram(program2);
881 validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
882
883 glUseProgram(program1);
JiangYizhou511937d2017-08-03 15:41:29 +0800884 // If fbo has attachments, the rendering size should be the same as its attachment.
885 GLTexture mTexture;
886 GLuint width = 2;
887 GLuint height = 2;
888 glBindTexture(GL_TEXTURE_2D, mTexture.get());
889 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
JiangYizhou38d92b52017-09-13 13:47:52 +0800890
891 const GLenum bufs[] = {GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT5};
892
893 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, mTexture.get(),
JiangYizhou511937d2017-08-03 15:41:29 +0800894 0);
895 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
JiangYizhou38d92b52017-09-13 13:47:52 +0800896 glDrawBuffers(6, bufs);
JiangYizhou511937d2017-08-03 15:41:29 +0800897
898 validateSamplePass(query, passedCount, width, height);
899
900 // If fbo's attachment has been removed, the rendering size should be the same as framebuffer
901 // default size.
JiangYizhou38d92b52017-09-13 13:47:52 +0800902 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, 0, 0, 0);
JiangYizhou511937d2017-08-03 15:41:29 +0800903 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
904
905 validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
906
907 glDisableVertexAttribArray(0);
908 glBindBuffer(GL_ARRAY_BUFFER, 0);
909 glBindVertexArray(0);
910 glDeleteBuffers(1, &vertexBuffer);
911 glDeleteVertexArrays(1, &vertexArray);
912
913 ASSERT_GL_NO_ERROR();
914}
915
916ANGLE_INSTANTIATE_TEST(FramebufferTest_ES31, ES31_D3D11(), ES31_OPENGL(), ES31_OPENGLES());
Brandon Jones9fc87332017-12-13 15:46:52 -0800917
918class AddDummyTextureNoRenderTargetTest : public ANGLETest
919{
920 public:
921 AddDummyTextureNoRenderTargetTest()
922 {
923 setWindowWidth(512);
924 setWindowHeight(512);
925 setConfigRedBits(8);
926 setConfigGreenBits(8);
927 setConfigBlueBits(8);
928 setConfigAlphaBits(8);
929 }
930
931 void overrideWorkaroundsD3D(WorkaroundsD3D *workarounds) override
932 {
933 workarounds->addDummyTextureNoRenderTarget = true;
934 }
935};
936
937// Test to verify workaround succeeds when no program outputs exist http://anglebug.com/2283
938TEST_P(AddDummyTextureNoRenderTargetTest, NoProgramOutputWorkaround)
939{
Jamie Madill35cd7332018-12-02 12:03:33 -0500940 constexpr char kVS[] = "void main() {}";
941 constexpr char kFS[] = "void main() {}";
Brandon Jones9fc87332017-12-13 15:46:52 -0800942
Jamie Madill35cd7332018-12-02 12:03:33 -0500943 ANGLE_GL_PROGRAM(drawProgram, kVS, kFS);
Brandon Jones9fc87332017-12-13 15:46:52 -0800944
945 glUseProgram(drawProgram);
946
947 glDrawArrays(GL_TRIANGLES, 0, 6);
948
949 ASSERT_GL_NO_ERROR();
950}
951
952ANGLE_INSTANTIATE_TEST(AddDummyTextureNoRenderTargetTest, ES2_D3D11());