blob: 2f9139a1cea694dc9cd59e289d0da1eb9b3fc470 [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
Jonah Ryan-Davisbeb0eb22019-06-14 15:10:33 -040010#include "platform/FeaturesD3D.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 Madill5cbaa3f2019-05-07 15:49:22 -0400151 void testSetUp() override
Geoff Langb6a673a2014-06-05 14:19:16 -0400152 {
Jamie Madill3215b202015-12-15 16:41:39 -0500153 glGenFramebuffers(1, &mFramebuffer);
154 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
Geoff Langb6a673a2014-06-05 14:19:16 -0400155 }
156
Jamie Madill5cbaa3f2019-05-07 15:49:22 -0400157 void testTearDown() override
Geoff Langb6a673a2014-06-05 14:19:16 -0400158 {
Jamie Madill3215b202015-12-15 16:41:39 -0500159 if (mTexture != 0)
160 {
161 glDeleteTextures(1, &mTexture);
162 mTexture = 0;
163 }
164
165 if (mRenderbuffer != 0)
166 {
167 glDeleteRenderbuffers(1, &mRenderbuffer);
168 mRenderbuffer = 0;
169 }
170
171 if (mFramebuffer != 0)
172 {
173 glDeleteFramebuffers(1, &mFramebuffer);
174 mFramebuffer = 0;
175 }
176
177 if (mProgram != 0)
178 {
179 glDeleteProgram(mProgram);
180 mProgram = 0;
181 }
Geoff Langb6a673a2014-06-05 14:19:16 -0400182 }
Jamie Madill3215b202015-12-15 16:41:39 -0500183
184 GLuint mFramebuffer;
185 GLuint mTexture;
186 GLuint mRenderbuffer;
187 GLuint mProgram;
Geoff Langb6a673a2014-06-05 14:19:16 -0400188};
189
Jamie Madillfa05f602015-05-07 13:47:11 -0400190TEST_P(FramebufferFormatsTest, RGBA4)
Geoff Langb6a673a2014-06-05 14:19:16 -0400191{
Jamie Madillb8149072019-04-30 16:14:44 -0400192 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
193 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
Geoff Langc4e93662017-05-01 10:45:59 -0400194
Geoff Langb6a673a2014-06-05 14:19:16 -0400195 testTextureFormat(GL_RGBA4, 4, 4, 4, 4);
196}
197
Jamie Madillfa05f602015-05-07 13:47:11 -0400198TEST_P(FramebufferFormatsTest, RGB565)
Geoff Langb6a673a2014-06-05 14:19:16 -0400199{
Jamie Madillb8149072019-04-30 16:14:44 -0400200 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
201 !IsGLExtensionEnabled("GL_EXT_texture_storage"));
Geoff Langc4e93662017-05-01 10:45:59 -0400202
Geoff Langb6a673a2014-06-05 14:19:16 -0400203 testTextureFormat(GL_RGB565, 5, 6, 5, 0);
204}
205
Jamie Madillfa05f602015-05-07 13:47:11 -0400206TEST_P(FramebufferFormatsTest, RGB8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400207{
Jamie Madillb8149072019-04-30 16:14:44 -0400208 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
209 (!IsGLExtensionEnabled("GL_OES_rgb8_rgba8") ||
210 !IsGLExtensionEnabled("GL_EXT_texture_storage")));
Geoff Langf34d1db2015-05-20 14:10:46 -0400211
Geoff Langb6a673a2014-06-05 14:19:16 -0400212 testTextureFormat(GL_RGB8_OES, 8, 8, 8, 0);
213}
214
Jamie Madillfa05f602015-05-07 13:47:11 -0400215TEST_P(FramebufferFormatsTest, BGRA8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400216{
Yunchao He9550c602018-02-13 14:47:05 +0800217 ANGLE_SKIP_TEST_IF(
Jamie Madillb8149072019-04-30 16:14:44 -0400218 !IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888") ||
219 (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_texture_storage")));
Geoff Langf34d1db2015-05-20 14:10:46 -0400220
Geoff Langb6a673a2014-06-05 14:19:16 -0400221 testTextureFormat(GL_BGRA8_EXT, 8, 8, 8, 8);
222}
223
Jamie Madillfa05f602015-05-07 13:47:11 -0400224TEST_P(FramebufferFormatsTest, RGBA8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400225{
Jamie Madillb8149072019-04-30 16:14:44 -0400226 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
227 (!IsGLExtensionEnabled("GL_OES_rgb8_rgba8") ||
228 !IsGLExtensionEnabled("GL_EXT_texture_storage")));
Geoff Langf34d1db2015-05-20 14:10:46 -0400229
Geoff Langb6a673a2014-06-05 14:19:16 -0400230 testTextureFormat(GL_RGBA8_OES, 8, 8, 8, 8);
231}
232
Jamie Madillfa05f602015-05-07 13:47:11 -0400233TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH16)
Corentin Walleze0902642014-11-04 12:32:15 -0800234{
235 testRenderbufferMultisampleFormat(2, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16);
236}
237
Jamie Madillfa05f602015-05-07 13:47:11 -0400238TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24)
Corentin Walleze0902642014-11-04 12:32:15 -0800239{
240 testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24);
241}
242
Jamie Madillfa05f602015-05-07 13:47:11 -0400243TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F)
Corentin Walleze0902642014-11-04 12:32:15 -0800244{
Yunchao He9550c602018-02-13 14:47:05 +0800245 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
Geoff Langf34d1db2015-05-20 14:10:46 -0400246
Corentin Walleze0902642014-11-04 12:32:15 -0800247 testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32F);
248}
249
Jamie Madillfa05f602015-05-07 13:47:11 -0400250TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24_STENCIL8)
Corentin Walleze0902642014-11-04 12:32:15 -0800251{
252 testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8);
253}
254
Jamie Madillfa05f602015-05-07 13:47:11 -0400255TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F_STENCIL8)
Corentin Walleze0902642014-11-04 12:32:15 -0800256{
Yunchao He9550c602018-02-13 14:47:05 +0800257 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
Geoff Langf34d1db2015-05-20 14:10:46 -0400258
Corentin Walleze0902642014-11-04 12:32:15 -0800259 testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH32F_STENCIL8);
260}
261
Jamie Madillfa05f602015-05-07 13:47:11 -0400262TEST_P(FramebufferFormatsTest, RenderbufferMultisample_STENCIL_INDEX8)
Corentin Walleze0902642014-11-04 12:32:15 -0800263{
Geoff Langf34d1db2015-05-20 14:10:46 -0400264 // TODO(geofflang): Figure out how to support GLSTENCIL_INDEX8 on desktop GL
Yunchao He9550c602018-02-13 14:47:05 +0800265 ANGLE_SKIP_TEST_IF(IsDesktopOpenGL());
Geoff Langf34d1db2015-05-20 14:10:46 -0400266
Corentin Walleze0902642014-11-04 12:32:15 -0800267 testRenderbufferMultisampleFormat(2, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8);
268}
Jamie Madillfa05f602015-05-07 13:47:11 -0400269
Jamie Madill3215b202015-12-15 16:41:39 -0500270// Test that binding an incomplete cube map is rejected by ANGLE.
271TEST_P(FramebufferFormatsTest, IncompleteCubeMap)
272{
Michael Spangd8506c72019-01-29 15:35:09 -0500273 // http://anglebug.com/3145
274 ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
275
Jamie Madill3215b202015-12-15 16:41:39 -0500276 // First make a complete CubeMap.
277 glGenTextures(1, &mTexture);
278 glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture);
279 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
280 nullptr);
281 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
282 nullptr);
283 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
284 nullptr);
285 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
286 nullptr);
287 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
288 nullptr);
289 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
290 nullptr);
291 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
292 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
293
294 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
295 mTexture, 0);
296
297 // Verify the framebuffer is complete.
298 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
299
300 // Make the CubeMap cube-incomplete.
301 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
302 nullptr);
303
304 // Verify the framebuffer is incomplete.
305 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
306 glCheckFramebufferStatus(GL_FRAMEBUFFER));
307
Jamie Madilld84b6732018-09-06 15:54:35 -0400308 ASSERT_GL_NO_ERROR();
309
Jamie Madill3215b202015-12-15 16:41:39 -0500310 // Verify drawing with the incomplete framebuffer produces a GL error
Olli Etuaho5804dc82018-04-13 14:11:46 +0300311 mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
Jamie Madill3215b202015-12-15 16:41:39 -0500312 ASSERT_NE(0u, mProgram);
Olli Etuaho5804dc82018-04-13 14:11:46 +0300313 drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
Jamie Madill3215b202015-12-15 16:41:39 -0500314 ASSERT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
315}
316
Olli Etuahobc21e182016-02-23 16:04:57 +0200317// Test that a renderbuffer with zero height but nonzero width is handled without crashes/asserts.
318TEST_P(FramebufferFormatsTest, ZeroHeightRenderbuffer)
319{
Yunchao He9550c602018-02-13 14:47:05 +0800320 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
Olli Etuahobc21e182016-02-23 16:04:57 +0200321
322 testZeroHeightRenderbuffer();
323}
324
Geoff Lang9bf86f02018-07-26 11:46:34 -0400325// Test to cover a bug where the read framebuffer affects the completeness of the draw framebuffer.
326TEST_P(FramebufferFormatsTest, ReadDrawCompleteness)
327{
328 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
329
330 GLTexture incompleteTexture;
331 glBindTexture(GL_TEXTURE_2D, incompleteTexture);
332
333 GLFramebuffer incompleteFBO;
334 glBindFramebuffer(GL_FRAMEBUFFER, incompleteFBO);
335 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, incompleteTexture,
336 0);
337 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
338 glCheckFramebufferStatus(GL_FRAMEBUFFER));
339
340 GLTexture completeTexture;
341 glBindTexture(GL_TEXTURE_2D, completeTexture);
342 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
343
344 GLFramebuffer completeFBO;
345 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, completeFBO);
346 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
347 completeTexture, 0);
348
349 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
350 glCheckFramebufferStatus(GL_READ_FRAMEBUFFER));
351 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
352
353 ASSERT_GL_NO_ERROR();
354
355 // Simple draw program.
356 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
357
358 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f, 1.0f, true);
359 EXPECT_GL_NO_ERROR();
360
361 glBindFramebuffer(GL_READ_FRAMEBUFFER, completeFBO);
362 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
363}
364
Le Hoang Quyen349b6612020-07-08 12:50:00 +0800365// Test that a renderbuffer with RGB565 format works as expected. This test is intended for some
366// back-end having no support for native RGB565 renderbuffer and thus having to emulate using RGBA
367// format.
368TEST_P(FramebufferFormatsTest, RGB565Renderbuffer)
369{
370 GLRenderbuffer rbo;
371 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
372 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB565, 1, 1);
373
374 GLFramebuffer completeFBO;
375 glBindFramebuffer(GL_FRAMEBUFFER, completeFBO);
376 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
377
378 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
379
380 ASSERT_GL_NO_ERROR();
381
382 glClearColor(1, 0, 0, 0.5f);
383 glClear(GL_COLOR_BUFFER_BIT);
384 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
385}
386
Corentin Wallez57e6d502016-12-09 14:46:39 -0500387class FramebufferTest_ES3 : public ANGLETest
Jamie Madillb980c562018-11-27 11:34:27 -0500388{};
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500389
390// Covers invalidating an incomplete framebuffer. This should be a no-op, but should not error.
Corentin Wallez57e6d502016-12-09 14:46:39 -0500391TEST_P(FramebufferTest_ES3, InvalidateIncomplete)
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500392{
Geoff Lang857c09d2017-05-16 15:55:04 -0400393 GLFramebuffer framebuffer;
394 GLRenderbuffer renderbuffer;
395
396 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
397 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
398 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500399 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
400 glCheckFramebufferStatus(GL_FRAMEBUFFER));
401
402 std::vector<GLenum> attachments;
403 attachments.push_back(GL_COLOR_ATTACHMENT0);
404
405 glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments.data());
406 EXPECT_GL_NO_ERROR();
407}
408
Corentin Wallez57e6d502016-12-09 14:46:39 -0500409// Test that the framebuffer state tracking robustly handles a depth-only attachment being set
410// as a depth-stencil attachment. It is equivalent to detaching the depth-stencil attachment.
411TEST_P(FramebufferTest_ES3, DepthOnlyAsDepthStencil)
412{
Geoff Lang857c09d2017-05-16 15:55:04 -0400413 GLFramebuffer framebuffer;
414 GLRenderbuffer renderbuffer;
415
416 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
417 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
Corentin Wallez57e6d502016-12-09 14:46:39 -0500418 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 4, 4);
419
420 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
Geoff Lang857c09d2017-05-16 15:55:04 -0400421 renderbuffer);
Corentin Wallez57e6d502016-12-09 14:46:39 -0500422 EXPECT_GLENUM_NE(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
423}
424
Geoff Lang857c09d2017-05-16 15:55:04 -0400425// Test that the framebuffer correctly returns that it is not complete if invalid texture mip levels
426// are bound
427TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevels)
428{
429 GLFramebuffer framebuffer;
430 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
431
432 GLTexture texture;
433 glBindTexture(GL_TEXTURE_2D, texture);
434
435 // Create a complete mip chain in mips 1 to 3
436 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
437 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
438 glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
439
440 // Create another complete mip chain in mips 4 to 5
441 glTexImage2D(GL_TEXTURE_2D, 4, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
442 glTexImage2D(GL_TEXTURE_2D, 5, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
443
444 // Create a non-complete mip chain in mip 6
445 glTexImage2D(GL_TEXTURE_2D, 6, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
446
447 // Incomplete, mipLevel != baseLevel and texture is not mip complete
448 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
449 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
450 glCheckFramebufferStatus(GL_FRAMEBUFFER));
451
452 // Complete, mipLevel == baseLevel
453 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
454 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
455
456 // Complete, mipLevel != baseLevel but texture is now mip complete
457 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 2);
458 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
459 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 3);
460 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
461
462 // Incomplete, attached level below the base level
463 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
464 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
465 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
466 glCheckFramebufferStatus(GL_FRAMEBUFFER));
467
468 // Incomplete, attached level is beyond effective max level
469 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 4);
470 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
471 glCheckFramebufferStatus(GL_FRAMEBUFFER));
472
473 // Complete, mipLevel == baseLevel
474 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 4);
475 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
476
477 // Complete, mipLevel != baseLevel but texture is now mip complete
478 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 5);
479 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
480
481 // Complete, mipLevel == baseLevel
482 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 6);
483 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 6);
484 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
485}
486
Shahbaz Youssefidbb18b52020-06-05 15:23:17 -0400487TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevelsReadBack)
488{
Kenneth Russell0bd0a912020-06-12 15:24:55 -0700489#if defined(ADDRESS_SANITIZER)
490 // http://anglebug.com/4737
491 ANGLE_SKIP_TEST_IF(IsOSX());
492#endif
493
Shahbaz Youssefidbb18b52020-06-05 15:23:17 -0400494 GLFramebuffer framebuffer;
495 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
496
497 GLTexture texture;
498 glBindTexture(GL_TEXTURE_2D, texture);
499
500 const std::array<GLColor, 2 * 2> mip0Data = {GLColor::red, GLColor::red, GLColor::red,
501 GLColor::red};
502 const std::array<GLColor, 1 * 1> mip1Data = {GLColor::green};
503
504 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip0Data.data());
505 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip1Data.data());
506
507 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
508 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
509 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
510
511 glClearColor(0, 0, 1.0f, 1.0f);
512 glClear(GL_COLOR_BUFFER_BIT);
513 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
514}
515
Martin Radevd178aa42017-07-13 14:03:22 +0300516// Test that passing an attachment COLOR_ATTACHMENTm where m is equal to MAX_COLOR_ATTACHMENTS
517// generates an INVALID_OPERATION.
518// OpenGL ES Version 3.0.5 (November 3, 2016), 4.4.2.4 Attaching Texture Images to a Framebuffer, p.
519// 208
520TEST_P(FramebufferTest_ES3, ColorAttachmentIndexOutOfBounds)
521{
522 GLFramebuffer framebuffer;
523 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
524
525 GLint maxColorAttachments = 0;
526 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
527 GLenum attachment = static_cast<GLenum>(maxColorAttachments + GL_COLOR_ATTACHMENT0);
528
529 GLTexture texture;
530 glBindTexture(GL_TEXTURE_2D, texture.get());
531 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
532 glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture.get(), 0);
533 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
534}
535
Jamie Madilla0016b72017-07-14 14:30:46 -0400536// Check that depth-only attachments report the correct number of samples.
537TEST_P(FramebufferTest_ES3, MultisampleDepthOnly)
538{
539 GLRenderbuffer renderbuffer;
540 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
541 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 32, 32);
542
543 GLFramebuffer framebuffer;
544 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
545 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
546 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
547 EXPECT_GL_NO_ERROR();
548
549 GLint samples = 0;
550 glGetIntegerv(GL_SAMPLES, &samples);
551 EXPECT_GL_NO_ERROR();
552 EXPECT_GE(samples, 2);
553}
554
Jeff Gilbert8f8edd62017-10-31 14:26:30 -0700555// Check that we only compare width and height of attachments, not depth.
556TEST_P(FramebufferTest_ES3, AttachmentWith3DLayers)
557{
558 GLTexture texA;
559 glBindTexture(GL_TEXTURE_2D, texA);
560 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
561
562 GLTexture texB;
563 glBindTexture(GL_TEXTURE_3D, texB);
564 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 4, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
565
566 GLFramebuffer framebuffer;
567 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
568 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texA, 0);
569 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texB, 0, 0);
570 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
571 EXPECT_GL_NO_ERROR();
572}
573
Olli Etuahodbce1f82018-09-19 15:32:17 +0300574// Test that clearing the stencil buffer when the framebuffer only has a color attachment does not
575// crash.
576TEST_P(FramebufferTest_ES3, ClearNonexistentStencil)
577{
578 GLRenderbuffer rbo;
579 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
580 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
581
582 GLFramebuffer fbo;
583 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
584 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
585
586 GLint clearValue = 0;
587 glClearBufferiv(GL_STENCIL, 0, &clearValue);
588
589 // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
590 EXPECT_GL_NO_ERROR();
591}
592
593// Test that clearing the depth buffer when the framebuffer only has a color attachment does not
594// crash.
595TEST_P(FramebufferTest_ES3, ClearNonexistentDepth)
596{
597 GLRenderbuffer rbo;
598 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
599 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
600
601 GLFramebuffer fbo;
602 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
603 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
604
605 GLfloat clearValue = 0.0f;
606 glClearBufferfv(GL_DEPTH, 0, &clearValue);
607
608 // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
609 EXPECT_GL_NO_ERROR();
610}
611
612// Test that clearing a nonexistent color attachment does not crash.
613TEST_P(FramebufferTest_ES3, ClearNonexistentColor)
614{
615 GLRenderbuffer rbo;
616 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
617 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
618
619 GLFramebuffer fbo;
620 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
621 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
622
623 std::vector<GLfloat> clearValue = {{0.0f, 1.0f, 0.0f, 1.0f}};
624 glClearBufferfv(GL_COLOR, 1, clearValue.data());
625
626 // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
627 EXPECT_GL_NO_ERROR();
628}
629
630// Test that clearing the depth and stencil buffers when the framebuffer only has a color attachment
631// does not crash.
632TEST_P(FramebufferTest_ES3, ClearNonexistentDepthStencil)
633{
634 GLRenderbuffer rbo;
635 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
636 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
637
638 GLFramebuffer fbo;
639 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
640 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
641
642 glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0);
643
644 // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
645 EXPECT_GL_NO_ERROR();
646}
647
Olli Etuaho4ebd8f32018-09-20 11:12:46 +0300648// Test that clearing a color attachment that has been deleted doesn't crash.
649TEST_P(FramebufferTest_ES3, ClearDeletedAttachment)
650{
651 // An INVALID_FRAMEBUFFER_OPERATION error was seen in this test on Mac, not sure where it might
652 // be originating from. http://anglebug.com/2834
653 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
654
655 GLFramebuffer fbo;
656 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
657
658 // There used to be a bug where some draw buffer state used to remain set even after the
659 // attachment was detached via deletion. That's why we create, attach and delete this RBO here.
660 GLuint rbo = 0u;
661 glGenRenderbuffers(1, &rbo);
662 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
663 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
664 glDeleteRenderbuffers(1, &rbo);
665
666 // There needs to be at least one color attachment to prevent early out from the clear calls.
667 GLRenderbuffer rbo2;
668 glBindRenderbuffer(GL_RENDERBUFFER, rbo2);
669 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
670 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rbo2);
671
672 ASSERT_GL_NO_ERROR();
673
674 // There's no error specified for clearing nonexistent buffers, it's simply a no-op, so we
675 // expect no GL errors below.
676 std::array<GLfloat, 4> floatClearValue = {0.0f, 0.0f, 0.0f, 0.0f};
677 glClearBufferfv(GL_COLOR, 0, floatClearValue.data());
678 EXPECT_GL_NO_ERROR();
679 std::array<GLuint, 4> uintClearValue = {0u, 0u, 0u, 0u};
680 glClearBufferuiv(GL_COLOR, 0, uintClearValue.data());
681 EXPECT_GL_NO_ERROR();
682 std::array<GLint, 4> intClearValue = {0, 0, 0, 0};
683 glClearBufferiv(GL_COLOR, 0, intClearValue.data());
684 EXPECT_GL_NO_ERROR();
685}
686
Tim Van Pattene600ac22019-10-04 14:31:57 -0600687// Test that resizing the color attachment is handled correctly.
688TEST_P(FramebufferTest_ES3, ResizeColorAttachmentSmallToLarge)
689{
690 GLFramebuffer fbo;
691 GLTexture smallTexture;
692 GLTexture largeTexture;
693
694 ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
695 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
696
697 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
698
699 // Bind the small texture
700 glBindTexture(GL_TEXTURE_2D, smallTexture);
701 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth() / 2, getWindowHeight() / 2, 0, GL_RGBA,
702 GL_UNSIGNED_BYTE, nullptr);
703 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
704 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
705 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, smallTexture, 0);
706 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
707
708 // Draw to FBO backed by the small texture
709 glUseProgram(greenProgram);
710 drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
711 ASSERT_GL_NO_ERROR();
712 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
713 EXPECT_PIXEL_COLOR_EQ((getWindowWidth() / 2) - 1, (getWindowHeight() / 2) - 1, GLColor::green);
714
715 // Change the attachment to the larger texture that fills the window
716 glBindTexture(GL_TEXTURE_2D, largeTexture);
717 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
718 GL_UNSIGNED_BYTE, nullptr);
719 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
720 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
721 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, largeTexture, 0);
722 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
723
724 // Draw to FBO backed by the large texture
725 glUseProgram(blueProgram);
726 drawQuad(blueProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
727 ASSERT_GL_NO_ERROR();
728 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
729 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::blue);
730}
731
732// Test that resizing the color attachment is handled correctly.
733TEST_P(FramebufferTest_ES3, ResizeColorAttachmentLargeToSmall)
734{
735 GLFramebuffer fbo;
736 GLTexture smallTexture;
737 GLTexture largeTexture;
738
739 ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
740 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
741
742 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
743
744 // Bind the large texture
745 glBindTexture(GL_TEXTURE_2D, largeTexture);
746 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
747 GL_UNSIGNED_BYTE, nullptr);
748 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
749 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
750 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, largeTexture, 0);
751 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
752
753 // Draw to FBO backed by the large texture
754 glUseProgram(blueProgram);
755 drawQuad(blueProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
756 ASSERT_GL_NO_ERROR();
757 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
758 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::blue);
759
760 // Change the attachment to the smaller texture
761 glBindTexture(GL_TEXTURE_2D, smallTexture);
762 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth() / 2, getWindowHeight() / 2, 0, GL_RGBA,
763 GL_UNSIGNED_BYTE, nullptr);
764 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
765 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
766 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, smallTexture, 0);
767 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
768
769 // Draw to FBO backed by the small texture
770 glUseProgram(greenProgram);
771 drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
772 ASSERT_GL_NO_ERROR();
773 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
774 EXPECT_PIXEL_COLOR_EQ((getWindowWidth() / 2) - 1, (getWindowHeight() / 2) - 1, GLColor::green);
775}
776
777// Test that resizing the texture is handled correctly.
778TEST_P(FramebufferTest_ES3, ResizeTextureLargeToSmall)
779{
780 GLFramebuffer fbo;
781 GLTexture texture;
782
783 ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
784 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
785
786 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
787
788 // Allocate a large texture
789 glBindTexture(GL_TEXTURE_2D, texture);
790 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
791 GL_UNSIGNED_BYTE, nullptr);
792 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
793 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
794 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
795 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
796
797 // Draw to FBO backed by the large texture
798 glUseProgram(blueProgram);
799 drawQuad(blueProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
800 ASSERT_GL_NO_ERROR();
801 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
802 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::blue);
803
804 // Shrink the texture
805 glBindTexture(GL_TEXTURE_2D, texture);
806 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth() / 2, getWindowHeight() / 2, 0, GL_RGBA,
807 GL_UNSIGNED_BYTE, nullptr);
808 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
809 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
810 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
811 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
812
813 // Draw to FBO backed by the small texture
814 glUseProgram(greenProgram);
815 drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
816 ASSERT_GL_NO_ERROR();
817 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
818 EXPECT_PIXEL_COLOR_EQ((getWindowWidth() / 2) - 1, (getWindowHeight() / 2) - 1, GLColor::green);
819}
820
821// Test that resizing the texture is handled correctly.
822TEST_P(FramebufferTest_ES3, ResizeTextureSmallToLarge)
823{
824 GLFramebuffer fbo;
825 GLTexture texture;
826
827 ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
828 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
829
830 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
831
832 // Allocate a small texture
833 glBindTexture(GL_TEXTURE_2D, texture);
834 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth() / 2, getWindowHeight() / 2, 0, GL_RGBA,
835 GL_UNSIGNED_BYTE, nullptr);
836 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
837 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
838 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
839 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
840
841 // Draw to FBO backed by the large texture
842 glUseProgram(blueProgram);
843 drawQuad(blueProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
844 ASSERT_GL_NO_ERROR();
845 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
846 EXPECT_PIXEL_COLOR_EQ((getWindowWidth() / 2) - 1, (getWindowHeight() / 2) - 1, GLColor::blue);
847
848 // Grow the texture
849 glBindTexture(GL_TEXTURE_2D, texture);
850 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
851 GL_UNSIGNED_BYTE, nullptr);
852 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
853 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
854 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
855 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
856
857 // Draw to FBO backed by the small texture
858 glUseProgram(greenProgram);
859 drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
860 ASSERT_GL_NO_ERROR();
861 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
862 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
863}
864
Shahbaz Youssefie28883d2020-01-25 23:25:43 -0500865// Test that fewer outputs than framebuffer attachments doesn't crash. This causes a Vulkan
866// validation warning, but should not be fatal.
867TEST_P(FramebufferTest_ES3, FewerShaderOutputsThanAttachments)
868{
869 constexpr char kFS[] = R"(#version 300 es
870precision highp float;
871
872layout(location = 0) out vec4 color0;
873layout(location = 1) out vec4 color1;
874layout(location = 2) out vec4 color2;
875
876void main()
877{
878 color0 = vec4(1.0, 0.0, 0.0, 1.0);
879 color1 = vec4(0.0, 1.0, 0.0, 1.0);
880 color2 = vec4(0.0, 0.0, 1.0, 1.0);
881}
882)";
883
884 ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
885
886 constexpr GLint kDrawBufferCount = 4;
887
888 GLint maxDrawBuffers;
889 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
890 ASSERT_GE(maxDrawBuffers, kDrawBufferCount);
891
892 GLTexture textures[kDrawBufferCount];
893
894 for (GLint texIndex = 0; texIndex < kDrawBufferCount; ++texIndex)
895 {
896 glBindTexture(GL_TEXTURE_2D, textures[texIndex]);
897 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
898 GL_UNSIGNED_BYTE, nullptr);
899 }
900
901 GLenum allBufs[kDrawBufferCount] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
902 GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
903
904 GLFramebuffer fbo;
905 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
906
907 // Enable all draw buffers.
908 for (GLint texIndex = 0; texIndex < kDrawBufferCount; ++texIndex)
909 {
910 glBindTexture(GL_TEXTURE_2D, textures[texIndex]);
911 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + texIndex, GL_TEXTURE_2D,
912 textures[texIndex], 0);
913 }
914 glDrawBuffers(kDrawBufferCount, allBufs);
915
916 // Draw with simple program.
917 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f, 1.0f, true);
918 ASSERT_GL_NO_ERROR();
919}
JiangYizhou461d9a32017-01-04 16:37:26 +0800920
921class FramebufferTest_ES31 : public ANGLETest
922{
JiangYizhou511937d2017-08-03 15:41:29 +0800923 protected:
924 void validateSamplePass(GLuint &query, GLuint &passedCount, GLint width, GLint height)
925 {
926 glUniform2i(0, width - 1, height - 1);
927 glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
928 glDrawArrays(GL_TRIANGLES, 0, 6);
929 glEndQuery(GL_ANY_SAMPLES_PASSED);
930 glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
931 EXPECT_GT(static_cast<GLint>(passedCount), 0);
932
933 glUniform2i(0, width - 1, height);
934 glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
935 glDrawArrays(GL_TRIANGLES, 0, 6);
936 glEndQuery(GL_ANY_SAMPLES_PASSED);
937 glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
938 EXPECT_EQ(static_cast<GLint>(passedCount), 0);
939
940 glUniform2i(0, width, height - 1);
941 glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
942 glDrawArrays(GL_TRIANGLES, 0, 6);
943 glEndQuery(GL_ANY_SAMPLES_PASSED);
944 glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
945 EXPECT_EQ(static_cast<GLint>(passedCount), 0);
946 }
JiangYizhou461d9a32017-01-04 16:37:26 +0800947};
948
949// Test that without attachment, if either the value of FRAMEBUFFER_DEFAULT_WIDTH or
950// FRAMEBUFFER_DEFAULT_HEIGHT parameters is zero, the framebuffer is incomplete.
951TEST_P(FramebufferTest_ES31, IncompleteMissingAttachmentDefaultParam)
952{
953 GLFramebuffer mFramebuffer;
954 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
955
956 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 1);
957 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 1);
958 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
959
960 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
961 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 0);
962 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
963 glCheckFramebufferStatus(GL_FRAMEBUFFER));
964
965 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 1);
966 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 0);
967 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
968 glCheckFramebufferStatus(GL_FRAMEBUFFER));
969
970 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
971 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 1);
972 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
973 glCheckFramebufferStatus(GL_FRAMEBUFFER));
974
975 ASSERT_GL_NO_ERROR();
976}
977
978// Test that the sample count of a mix of texture and renderbuffer should be same.
979TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountMix)
980{
981 GLFramebuffer mFramebuffer;
982 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
983
Ian Elliott5f857832019-12-04 15:30:50 -0700984 // Lookup the supported number of sample counts (rely on fact that ANGLE uses the same set of
985 // sample counts for textures and renderbuffers)
986 GLint numSampleCounts = 0;
987 std::vector<GLint> sampleCounts;
988 GLsizei queryBufferSize = 1;
989 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_NUM_SAMPLE_COUNTS,
990 queryBufferSize, &numSampleCounts);
991 ANGLE_SKIP_TEST_IF((numSampleCounts < 2));
992 sampleCounts.resize(numSampleCounts);
993 queryBufferSize = numSampleCounts;
994 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_SAMPLES, queryBufferSize,
995 sampleCounts.data());
996
JiangYizhou461d9a32017-01-04 16:37:26 +0800997 GLTexture mTexture;
998 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture.get());
Ian Elliott5f857832019-12-04 15:30:50 -0700999 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCounts[0], GL_RGBA8, 1, 1, true);
JiangYizhou461d9a32017-01-04 16:37:26 +08001000
1001 GLRenderbuffer mRenderbuffer;
1002 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer.get());
Ian Elliott5f857832019-12-04 15:30:50 -07001003 glRenderbufferStorageMultisample(GL_RENDERBUFFER, sampleCounts[1], GL_RGBA8, 1, 1);
JiangYizhou461d9a32017-01-04 16:37:26 +08001004 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
1005 mTexture.get(), 0);
1006 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
1007 mRenderbuffer.get());
1008 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
1009 glCheckFramebufferStatus(GL_FRAMEBUFFER));
1010
1011 ASSERT_GL_NO_ERROR();
1012}
1013
1014// Test that the sample count of texture attachments should be same.
1015TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountTex)
1016{
1017 GLFramebuffer mFramebuffer;
1018 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
1019
Ian Elliott5f857832019-12-04 15:30:50 -07001020 // Lookup the supported number of sample counts
1021 GLint numSampleCounts = 0;
1022 std::vector<GLint> sampleCounts;
1023 GLsizei queryBufferSize = 1;
1024 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_NUM_SAMPLE_COUNTS,
1025 queryBufferSize, &numSampleCounts);
1026 ANGLE_SKIP_TEST_IF((numSampleCounts < 2));
1027 sampleCounts.resize(numSampleCounts);
1028 queryBufferSize = numSampleCounts;
1029 glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_SAMPLES, queryBufferSize,
1030 sampleCounts.data());
1031
JiangYizhou461d9a32017-01-04 16:37:26 +08001032 GLTexture mTextures[2];
1033 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[0].get());
Ian Elliott5f857832019-12-04 15:30:50 -07001034 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCounts[0], GL_RGBA8, 1, 1, true);
JiangYizhou461d9a32017-01-04 16:37:26 +08001035 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[1].get());
Ian Elliott5f857832019-12-04 15:30:50 -07001036 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCounts[1], GL_RGBA8, 1, 1, true);
JiangYizhou461d9a32017-01-04 16:37:26 +08001037 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
1038 mTextures[0].get(), 0);
1039 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
1040 mTextures[1].get(), 0);
1041 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
1042 glCheckFramebufferStatus(GL_FRAMEBUFFER));
1043
1044 ASSERT_GL_NO_ERROR();
1045}
1046
1047// Test that if the attached images are a mix of renderbuffers and textures, the value of
1048// TEXTURE_FIXED_SAMPLE_LOCATIONS must be TRUE for all attached textures.
1049TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsMix)
1050{
1051 GLFramebuffer mFramebuffer;
1052 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
1053
1054 GLTexture mTexture;
1055 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture.get());
1056 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, false);
1057
1058 GLRenderbuffer mRenderbuffer;
1059 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer.get());
1060 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 1, GL_RGBA8, 1, 1);
1061 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
1062 mTexture.get(), 0);
1063 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
1064 mRenderbuffer.get());
1065 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
1066 glCheckFramebufferStatus(GL_FRAMEBUFFER));
1067
1068 ASSERT_GL_NO_ERROR();
1069}
1070
1071// Test that the value of TEXTURE_FIXED_SAMPLE_LOCATIONS is the same for all attached textures.
1072TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsTex)
1073{
1074 GLFramebuffer mFramebuffer;
1075 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
1076
1077 GLTexture mTextures[2];
1078 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[0].get());
1079 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, false);
1080 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
1081 mTextures[0].get(), 0);
1082 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[1].get());
1083 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGB8, 1, 1, true);
1084 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
1085 mTextures[1].get(), 0);
1086 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
1087 glCheckFramebufferStatus(GL_FRAMEBUFFER));
1088
1089 ASSERT_GL_NO_ERROR();
1090}
1091
JiangYizhou511937d2017-08-03 15:41:29 +08001092// If there are no attachments, rendering will be limited to a rectangle having a lower left of
1093// (0, 0) and an upper right of(width, height), where width and height are the framebuffer
1094// object's default width and height.
JiangYizhou3db40722017-08-28 17:59:13 +08001095TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments)
JiangYizhou511937d2017-08-03 15:41:29 +08001096{
Yuly Novikov98f9f532017-11-15 19:16:19 -05001097 // anglebug.com/2253
1098 ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
Tim Van Patten626a7282019-07-08 15:11:59 -06001099 // Occlusion query reports fragments outside the render area are still rendered
1100 ANGLE_SKIP_TEST_IF(IsAndroid() || (IsWindows() && (IsIntel() || IsAMD())));
Yuly Novikov98f9f532017-11-15 19:16:19 -05001101
Jamie Madill35cd7332018-12-02 12:03:33 -05001102 constexpr char kVS1[] = R"(#version 310 es
1103in layout(location = 0) highp vec2 a_position;
1104void main()
1105{
1106 gl_Position = vec4(a_position, 0.0, 1.0);
1107})";
JiangYizhou511937d2017-08-03 15:41:29 +08001108
Jamie Madill35cd7332018-12-02 12:03:33 -05001109 constexpr char kFS1[] = R"(#version 310 es
1110uniform layout(location = 0) highp ivec2 u_expectedSize;
Shahbaz Youssefi190d9a82019-11-29 09:57:40 -05001111out layout(location = 3) mediump vec4 f_color;
Jamie Madill35cd7332018-12-02 12:03:33 -05001112void main()
1113{
1114 if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;
1115 f_color = vec4(1.0, 0.5, 0.25, 1.0);
1116})";
JiangYizhou511937d2017-08-03 15:41:29 +08001117
Jamie Madill35cd7332018-12-02 12:03:33 -05001118 constexpr char kVS2[] = R"(#version 310 es
1119in layout(location = 0) highp vec2 a_position;
1120void main()
1121{
1122 gl_Position = vec4(a_position, 0.0, 1.0);
1123})";
JiangYizhou10d41392017-12-18 18:13:36 +08001124
Jamie Madill35cd7332018-12-02 12:03:33 -05001125 constexpr char kFS2[] = R"(#version 310 es
1126uniform layout(location = 0) highp ivec2 u_expectedSize;
1127out layout(location = 2) mediump vec4 f_color;
1128void main()
1129{
1130 if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;
1131 f_color = vec4(1.0, 0.5, 0.25, 1.0);
1132})";
JiangYizhou10d41392017-12-18 18:13:36 +08001133
Jamie Madill35cd7332018-12-02 12:03:33 -05001134 GLuint program1 = CompileProgram(kVS1, kFS1);
JiangYizhou10d41392017-12-18 18:13:36 +08001135 ASSERT_NE(program1, 0u);
1136
Jamie Madill35cd7332018-12-02 12:03:33 -05001137 GLuint program2 = CompileProgram(kVS2, kFS2);
JiangYizhou10d41392017-12-18 18:13:36 +08001138 ASSERT_NE(program2, 0u);
1139
1140 glUseProgram(program1);
JiangYizhou511937d2017-08-03 15:41:29 +08001141
1142 GLFramebuffer mFramebuffer;
1143 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
1144 GLuint defaultWidth = 1;
1145 GLuint defaultHeight = 1;
1146
1147 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, defaultWidth);
1148 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, defaultHeight);
1149 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1150
1151 const float data[] = {
1152 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f,
1153 };
1154
1155 GLuint vertexArray = 0;
1156 GLuint vertexBuffer = 0;
1157 GLuint query = 0;
1158 GLuint passedCount = 0;
1159
1160 glGenQueries(1, &query);
1161 glGenVertexArrays(1, &vertexArray);
1162 glBindVertexArray(vertexArray);
1163
1164 glGenBuffers(1, &vertexBuffer);
1165 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
1166 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
1167
1168 glEnableVertexAttribArray(0);
1169 glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
JiangYizhou38d92b52017-09-13 13:47:52 +08001170 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
JiangYizhou511937d2017-08-03 15:41:29 +08001171
1172 validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
1173
JiangYizhou10d41392017-12-18 18:13:36 +08001174 glUseProgram(program2);
1175 validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
1176
1177 glUseProgram(program1);
JiangYizhou511937d2017-08-03 15:41:29 +08001178 // If fbo has attachments, the rendering size should be the same as its attachment.
1179 GLTexture mTexture;
1180 GLuint width = 2;
1181 GLuint height = 2;
1182 glBindTexture(GL_TEXTURE_2D, mTexture.get());
1183 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
JiangYizhou38d92b52017-09-13 13:47:52 +08001184
Shahbaz Youssefi190d9a82019-11-29 09:57:40 -05001185 const GLenum bufs[] = {GL_NONE, GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT3};
JiangYizhou38d92b52017-09-13 13:47:52 +08001186
Shahbaz Youssefi190d9a82019-11-29 09:57:40 -05001187 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, mTexture.get(),
JiangYizhou511937d2017-08-03 15:41:29 +08001188 0);
1189 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
Shahbaz Youssefi190d9a82019-11-29 09:57:40 -05001190 glDrawBuffers(4, bufs);
JiangYizhou511937d2017-08-03 15:41:29 +08001191
1192 validateSamplePass(query, passedCount, width, height);
1193
1194 // If fbo's attachment has been removed, the rendering size should be the same as framebuffer
1195 // default size.
Shahbaz Youssefi190d9a82019-11-29 09:57:40 -05001196 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, 0, 0, 0);
JiangYizhou511937d2017-08-03 15:41:29 +08001197 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1198
1199 validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
1200
1201 glDisableVertexAttribArray(0);
1202 glBindBuffer(GL_ARRAY_BUFFER, 0);
1203 glBindVertexArray(0);
1204 glDeleteBuffers(1, &vertexBuffer);
1205 glDeleteVertexArrays(1, &vertexArray);
1206
1207 ASSERT_GL_NO_ERROR();
1208}
1209
Brandon Jones9fc87332017-12-13 15:46:52 -08001210class AddDummyTextureNoRenderTargetTest : public ANGLETest
1211{
1212 public:
1213 AddDummyTextureNoRenderTargetTest()
1214 {
1215 setWindowWidth(512);
1216 setWindowHeight(512);
1217 setConfigRedBits(8);
1218 setConfigGreenBits(8);
1219 setConfigBlueBits(8);
1220 setConfigAlphaBits(8);
1221 }
1222
Jonah Ryan-Daviseee67c62019-06-18 13:00:43 -04001223 void overrideWorkaroundsD3D(FeaturesD3D *features) override
Brandon Jones9fc87332017-12-13 15:46:52 -08001224 {
Jonah Ryan-Davisbeb0eb22019-06-14 15:10:33 -04001225 features->overrideFeatures({"add_dummy_texture_no_render_target"}, true);
Brandon Jones9fc87332017-12-13 15:46:52 -08001226 }
1227};
1228
1229// Test to verify workaround succeeds when no program outputs exist http://anglebug.com/2283
1230TEST_P(AddDummyTextureNoRenderTargetTest, NoProgramOutputWorkaround)
1231{
Jamie Madill35cd7332018-12-02 12:03:33 -05001232 constexpr char kVS[] = "void main() {}";
1233 constexpr char kFS[] = "void main() {}";
Brandon Jones9fc87332017-12-13 15:46:52 -08001234
Jamie Madill35cd7332018-12-02 12:03:33 -05001235 ANGLE_GL_PROGRAM(drawProgram, kVS, kFS);
Brandon Jones9fc87332017-12-13 15:46:52 -08001236
1237 glUseProgram(drawProgram);
1238
1239 glDrawArrays(GL_TRIANGLES, 0, 6);
1240
1241 ASSERT_GL_NO_ERROR();
1242}
1243
Jamie Madill4fb3c282020-03-19 19:10:45 -04001244// Covers a bug in ANGLE's Vulkan back-end framebuffer cache which ignored depth/stencil after
1245// calls to DrawBuffers.
1246TEST_P(FramebufferTest_ES3, AttachmentStateChange)
1247{
1248 constexpr GLuint kSize = 2;
1249
1250 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1251
1252 GLTexture colorTexture;
1253 glBindTexture(GL_TEXTURE_2D, colorTexture);
1254 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1255
1256 GLFramebuffer fbo;
1257 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1258 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
1259
1260 ASSERT_GL_NO_ERROR();
1261 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1262
1263 // First draw without a depth buffer.
1264 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
1265
1266 GLRenderbuffer depthBuffer;
1267 glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
1268 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, kSize, kSize);
1269
1270 // Bind just a renderbuffer and draw.
1271 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
1272
1273 ASSERT_GL_NO_ERROR();
1274 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1275
1276 glDrawBuffers(0, nullptr);
1277 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
1278
1279 // Re-enable color buffer and draw one final time. This previously triggered a crash.
1280 GLenum drawBuffs = {GL_COLOR_ATTACHMENT0};
1281 glDrawBuffers(1, &drawBuffs);
1282
1283 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
1284 ASSERT_GL_NO_ERROR();
1285 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1286}
1287
Jamie Madilld03b15b2020-03-26 17:22:18 -04001288// Tests that we can support a feedback loop between a depth textures and the depth buffer.
1289// Does not totally mirror the case used in Manhattan. The Manhattan case seems to handle
1290// "clear" specially instead of rendering to depth in the same RP.
1291TEST_P(FramebufferTest_ES3, DepthFeedbackLoopSupported)
1292{
1293 // Feedback loops not supported on D3D11 and may not ever be.
1294 ANGLE_SKIP_TEST_IF(IsD3D11());
1295
1296 // Also this particular test doesn't work on Android despite similar support in Manhattan.
1297 ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
1298
1299 constexpr GLuint kSize = 2;
1300 glViewport(0, 0, kSize, kSize);
1301
1302 constexpr char kFS[] = R"(precision mediump float;
1303varying vec2 v_texCoord;
1304uniform sampler2D depth;
1305void main()
1306{
1307 if (abs(texture2D(depth, v_texCoord).x - 0.5) < 0.1)
1308 {
1309 gl_FragColor = vec4(0, 1, 0, 1);
1310 }
1311 else
1312 {
1313 gl_FragColor = vec4(1, 0, 0, 1);
1314 }
1315})";
1316
1317 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), kFS);
1318
1319 GLFramebuffer framebuffer;
1320 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1321
1322 GLTexture colorTexture;
1323 glBindTexture(GL_TEXTURE_2D, colorTexture);
1324 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1325
1326 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1327 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1328 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
1329
1330 GLTexture depthTexture;
1331 glBindTexture(GL_TEXTURE_2D, depthTexture);
1332 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, kSize, kSize, 0, GL_DEPTH_COMPONENT,
1333 GL_UNSIGNED_INT, nullptr);
1334 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1335 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1336 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
1337
1338 ASSERT_GL_NO_ERROR();
1339 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1340
1341 // Clear depth to 0.5.
1342 glClearDepthf(0.5f);
1343 glClear(GL_DEPTH_BUFFER_BIT);
1344
1345 // Disable the depth mask. Although this does not remove the feedback loop as defined by the
1346 // spec it mimics what gfxbench does in its rendering tests.
1347 glDepthMask(false);
1348
1349 // Verify we can sample the depth texture and get 0.5.
1350 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
1351
1352 ASSERT_GL_NO_ERROR();
1353 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1354}
1355
Jamie Madilldd00f162020-04-02 14:04:44 -04001356// Covers a bug in ANGLE's Vulkan back-end. Our VkFramebuffer cache would in some cases forget to
1357// check the draw states when computing a cache key.
1358TEST_P(FramebufferTest_ES3, DisabledAttachmentRedefinition)
1359{
1360 constexpr GLuint kSize = 2;
1361
1362 // Make a Framebuffer with two attachments with one enabled and one disabled.
1363 GLTexture texA, texB;
1364 glBindTexture(GL_TEXTURE_2D, texA);
1365 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1366 glBindTexture(GL_TEXTURE_2D, texB);
1367 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1368
1369 GLFramebuffer fbo;
1370 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1371 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texA, 0);
1372 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, texB, 0);
1373
1374 // Mask out the second texture.
1375 constexpr GLenum kOneDrawBuf = GL_COLOR_ATTACHMENT0;
1376 glDrawBuffers(1, &kOneDrawBuf);
1377
1378 ASSERT_GL_NO_ERROR();
1379 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1380
1381 // Set up a very simple shader.
1382 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1383 glViewport(0, 0, kSize, kSize);
1384
1385 // Draw
1386 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f, 1.0f, true);
1387 ASSERT_GL_NO_ERROR();
1388 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1389
1390 // Update the masked out attachment and draw again.
1391 std::vector<GLColor> redPixels(kSize * kSize, GLColor::red);
1392 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE,
1393 redPixels.data());
1394
1395 // Draw
1396 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f, 1.0f, true);
1397 ASSERT_GL_NO_ERROR();
1398 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1399
1400 glReadBuffer(GL_COLOR_ATTACHMENT1);
1401 ASSERT_GL_NO_ERROR();
1402 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1403}
1404
Jamie Madillc9c4e4e2020-04-02 10:29:52 -04001405class FramebufferTest : public ANGLETest
1406{};
1407
1408template <typename T>
1409void FillTexture2D(GLuint texture,
1410 GLsizei width,
1411 GLsizei height,
1412 const T &onePixelData,
1413 GLint level,
1414 GLint internalFormat,
1415 GLenum format,
1416 GLenum type)
1417{
1418 std::vector<T> allPixelsData(width * height, onePixelData);
1419
1420 glBindTexture(GL_TEXTURE_2D, texture);
1421 glTexImage2D(GL_TEXTURE_2D, level, internalFormat, width, height, 0, format, type,
1422 allPixelsData.data());
1423 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1424 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1425 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1426 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1427}
1428
1429// Multi-context uses of textures should not cause rendering feedback loops.
1430TEST_P(FramebufferTest, MultiContextNoRenderingFeedbackLoops)
1431{
1432 constexpr char kTextureVS[] =
1433 R"(attribute vec4 a_position;
1434varying vec2 v_texCoord;
1435void main() {
1436 gl_Position = a_position;
1437 v_texCoord = (a_position.xy * 0.5) + 0.5;
1438})";
1439
1440 constexpr char kTextureFS[] =
1441 R"(precision mediump float;
1442varying vec2 v_texCoord;
1443uniform sampler2D u_texture;
1444void main() {
1445 gl_FragColor = texture2D(u_texture, v_texCoord).rgba;
1446})";
1447
1448 ANGLE_GL_PROGRAM(textureProgram, kTextureVS, kTextureFS);
1449
1450 glUseProgram(textureProgram.get());
1451 GLint uniformLoc = glGetUniformLocation(textureProgram.get(), "u_texture");
1452 ASSERT_NE(-1, uniformLoc);
1453 glUniform1i(uniformLoc, 0);
1454
1455 GLTexture texture;
1456 FillTexture2D(texture.get(), 1, 1, GLColor::red, 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
1457 glBindTexture(GL_TEXTURE_2D, texture.get());
1458 // Note that _texture_ is still bound to GL_TEXTURE_2D in this context at this point.
1459
1460 EGLWindow *window = getEGLWindow();
1461 EGLDisplay display = window->getDisplay();
1462 EGLConfig config = window->getConfig();
1463 EGLSurface surface = window->getSurface();
1464 EGLint contextAttributes[] = {
1465 EGL_CONTEXT_MAJOR_VERSION_KHR,
1466 GetParam().majorVersion,
1467 EGL_CONTEXT_MINOR_VERSION_KHR,
1468 GetParam().minorVersion,
1469 EGL_NONE,
1470 };
1471 EGLContext context1 = eglGetCurrentContext();
1472 // Create context2, sharing resources with context1.
1473 EGLContext context2 = eglCreateContext(display, config, context1, contextAttributes);
1474 ASSERT_NE(context2, EGL_NO_CONTEXT);
1475 eglMakeCurrent(display, surface, surface, context2);
1476
1477 constexpr char kVS[] =
1478 R"(attribute vec4 a_position;
1479void main() {
1480 gl_Position = a_position;
1481})";
1482
1483 constexpr char kFS[] =
1484 R"(precision mediump float;
1485void main() {
1486 gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
1487})";
1488
1489 ANGLE_GL_PROGRAM(program, kVS, kFS);
1490 glUseProgram(program.get());
1491
1492 ASSERT_GL_NO_ERROR();
1493
1494 // Render to the texture in context2.
1495 GLFramebuffer framebuffer;
1496 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
1497 // Texture is still a valid name in context2.
1498 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.get(), 0);
1499 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1500 // There is no rendering feedback loop at this point.
1501
1502 glDisable(GL_BLEND);
1503 glDisable(GL_DEPTH_TEST);
1504 ASSERT_GL_NO_ERROR();
1505
1506 // If draw is no-op'ed, texture will not be filled appropriately.
1507 drawQuad(program.get(), "a_position", 0.5f, 1.0f, true);
1508 ASSERT_GL_NO_ERROR();
1509 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1510
1511 // Make context1 current again.
1512 eglMakeCurrent(display, surface, surface, context1);
1513
1514 // Render texture to screen.
1515 drawQuad(textureProgram.get(), "a_position", 0.5f, 1.0f, true);
1516 ASSERT_GL_NO_ERROR();
1517 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1518
1519 eglDestroyContext(display, context2);
1520}
1521
Jamie Madill2a0c3592020-03-31 15:36:45 -04001522// Ensure cube-incomplete attachments cause incomplete Framebuffers.
1523TEST_P(FramebufferTest, IncompleteCubeMap)
1524{
1525 constexpr GLuint kSize = 2;
1526
1527 GLTexture srcTex;
1528 glBindTexture(GL_TEXTURE_CUBE_MAP, srcTex);
1529 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA,
1530 GL_UNSIGNED_BYTE, nullptr);
1531
1532 GLFramebuffer fbo;
1533 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1534 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
1535 srcTex, 0);
1536
1537 ASSERT_GL_NO_ERROR();
1538 ASSERT_GLENUM_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
1539 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
1540}
1541
Tobin Ehlis1a01b4b2019-11-11 16:41:07 -07001542ANGLE_INSTANTIATE_TEST_ES2(AddDummyTextureNoRenderTargetTest);
Jamie Madillc9c4e4e2020-04-02 10:29:52 -04001543ANGLE_INSTANTIATE_TEST_ES2(FramebufferTest);
Shahbaz Youssefie28883d2020-01-25 23:25:43 -05001544ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(FramebufferFormatsTest);
1545ANGLE_INSTANTIATE_TEST_ES3(FramebufferTest_ES3);
1546ANGLE_INSTANTIATE_TEST_ES31(FramebufferTest_ES31);