blob: 69ffbc4ff318f0a64131b3d6096a5f6b315bce4e [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 {
111 if (extensionEnabled("ANGLE_framebuffer_multisample"))
112 {
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{
Yunchao He9550c602018-02-13 14:47:05 +0800196 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_storage"));
Geoff Langc4e93662017-05-01 10:45:59 -0400197
Geoff Langb6a673a2014-06-05 14:19:16 -0400198 testTextureFormat(GL_RGBA4, 4, 4, 4, 4);
199}
200
Jamie Madillfa05f602015-05-07 13:47:11 -0400201TEST_P(FramebufferFormatsTest, RGB565)
Geoff Langb6a673a2014-06-05 14:19:16 -0400202{
Yunchao He9550c602018-02-13 14:47:05 +0800203 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_storage"));
Geoff Langc4e93662017-05-01 10:45:59 -0400204
Geoff Langb6a673a2014-06-05 14:19:16 -0400205 testTextureFormat(GL_RGB565, 5, 6, 5, 0);
206}
207
Jamie Madillfa05f602015-05-07 13:47:11 -0400208TEST_P(FramebufferFormatsTest, RGB8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400209{
Yunchao He9550c602018-02-13 14:47:05 +0800210 ANGLE_SKIP_TEST_IF(
211 getClientMajorVersion() < 3 &&
212 (!extensionEnabled("GL_OES_rgb8_rgba8") || !extensionEnabled("GL_EXT_texture_storage")));
Geoff Langf34d1db2015-05-20 14:10:46 -0400213
Geoff Langb6a673a2014-06-05 14:19:16 -0400214 testTextureFormat(GL_RGB8_OES, 8, 8, 8, 0);
215}
216
Jamie Madillfa05f602015-05-07 13:47:11 -0400217TEST_P(FramebufferFormatsTest, BGRA8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400218{
Yunchao He9550c602018-02-13 14:47:05 +0800219 ANGLE_SKIP_TEST_IF(
220 !extensionEnabled("GL_EXT_texture_format_BGRA8888") ||
221 (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_storage")));
Geoff Langf34d1db2015-05-20 14:10:46 -0400222
Geoff Langb6a673a2014-06-05 14:19:16 -0400223 testTextureFormat(GL_BGRA8_EXT, 8, 8, 8, 8);
224}
225
Jamie Madillfa05f602015-05-07 13:47:11 -0400226TEST_P(FramebufferFormatsTest, RGBA8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400227{
Yunchao He9550c602018-02-13 14:47:05 +0800228 ANGLE_SKIP_TEST_IF(
229 getClientMajorVersion() < 3 &&
230 (!extensionEnabled("GL_OES_rgb8_rgba8") || !extensionEnabled("GL_EXT_texture_storage")));
Geoff Langf34d1db2015-05-20 14:10:46 -0400231
Geoff Langb6a673a2014-06-05 14:19:16 -0400232 testTextureFormat(GL_RGBA8_OES, 8, 8, 8, 8);
233}
234
Jamie Madillfa05f602015-05-07 13:47:11 -0400235TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH16)
Corentin Walleze0902642014-11-04 12:32:15 -0800236{
237 testRenderbufferMultisampleFormat(2, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16);
238}
239
Jamie Madillfa05f602015-05-07 13:47:11 -0400240TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24)
Corentin Walleze0902642014-11-04 12:32:15 -0800241{
242 testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24);
243}
244
Jamie Madillfa05f602015-05-07 13:47:11 -0400245TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F)
Corentin Walleze0902642014-11-04 12:32:15 -0800246{
Yunchao He9550c602018-02-13 14:47:05 +0800247 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
Geoff Langf34d1db2015-05-20 14:10:46 -0400248
Corentin Walleze0902642014-11-04 12:32:15 -0800249 testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32F);
250}
251
Jamie Madillfa05f602015-05-07 13:47:11 -0400252TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24_STENCIL8)
Corentin Walleze0902642014-11-04 12:32:15 -0800253{
254 testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8);
255}
256
Jamie Madillfa05f602015-05-07 13:47:11 -0400257TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F_STENCIL8)
Corentin Walleze0902642014-11-04 12:32:15 -0800258{
Yunchao He9550c602018-02-13 14:47:05 +0800259 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
Geoff Langf34d1db2015-05-20 14:10:46 -0400260
Corentin Walleze0902642014-11-04 12:32:15 -0800261 testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH32F_STENCIL8);
262}
263
Jamie Madillfa05f602015-05-07 13:47:11 -0400264TEST_P(FramebufferFormatsTest, RenderbufferMultisample_STENCIL_INDEX8)
Corentin Walleze0902642014-11-04 12:32:15 -0800265{
Geoff Langf34d1db2015-05-20 14:10:46 -0400266 // TODO(geofflang): Figure out how to support GLSTENCIL_INDEX8 on desktop GL
Yunchao He9550c602018-02-13 14:47:05 +0800267 ANGLE_SKIP_TEST_IF(IsDesktopOpenGL());
Geoff Langf34d1db2015-05-20 14:10:46 -0400268
Corentin Walleze0902642014-11-04 12:32:15 -0800269 testRenderbufferMultisampleFormat(2, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8);
270}
Jamie Madillfa05f602015-05-07 13:47:11 -0400271
Jamie Madill3215b202015-12-15 16:41:39 -0500272// Test that binding an incomplete cube map is rejected by ANGLE.
273TEST_P(FramebufferFormatsTest, IncompleteCubeMap)
274{
275 // First make a complete CubeMap.
276 glGenTextures(1, &mTexture);
277 glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture);
278 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
279 nullptr);
280 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
281 nullptr);
282 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
283 nullptr);
284 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
285 nullptr);
286 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
287 nullptr);
288 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
289 nullptr);
290 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
291 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
292
293 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
294 mTexture, 0);
295
296 // Verify the framebuffer is complete.
297 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
298
299 // Make the CubeMap cube-incomplete.
300 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
301 nullptr);
302
303 // Verify the framebuffer is incomplete.
304 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
305 glCheckFramebufferStatus(GL_FRAMEBUFFER));
306
Jamie Madilld84b6732018-09-06 15:54:35 -0400307 ASSERT_GL_NO_ERROR();
308
Jamie Madill3215b202015-12-15 16:41:39 -0500309 // Verify drawing with the incomplete framebuffer produces a GL error
Olli Etuaho5804dc82018-04-13 14:11:46 +0300310 mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
Jamie Madill3215b202015-12-15 16:41:39 -0500311 ASSERT_NE(0u, mProgram);
Olli Etuaho5804dc82018-04-13 14:11:46 +0300312 drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
Jamie Madill3215b202015-12-15 16:41:39 -0500313 ASSERT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
314}
315
Olli Etuahobc21e182016-02-23 16:04:57 +0200316// Test that a renderbuffer with zero height but nonzero width is handled without crashes/asserts.
317TEST_P(FramebufferFormatsTest, ZeroHeightRenderbuffer)
318{
Yunchao He9550c602018-02-13 14:47:05 +0800319 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
Olli Etuahobc21e182016-02-23 16:04:57 +0200320
321 testZeroHeightRenderbuffer();
322}
323
Geoff Lang9bf86f02018-07-26 11:46:34 -0400324// Test to cover a bug where the read framebuffer affects the completeness of the draw framebuffer.
325TEST_P(FramebufferFormatsTest, ReadDrawCompleteness)
326{
327 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
328
329 GLTexture incompleteTexture;
330 glBindTexture(GL_TEXTURE_2D, incompleteTexture);
331
332 GLFramebuffer incompleteFBO;
333 glBindFramebuffer(GL_FRAMEBUFFER, incompleteFBO);
334 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, incompleteTexture,
335 0);
336 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
337 glCheckFramebufferStatus(GL_FRAMEBUFFER));
338
339 GLTexture completeTexture;
340 glBindTexture(GL_TEXTURE_2D, completeTexture);
341 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
342
343 GLFramebuffer completeFBO;
344 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, completeFBO);
345 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
346 completeTexture, 0);
347
348 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
349 glCheckFramebufferStatus(GL_READ_FRAMEBUFFER));
350 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
351
352 ASSERT_GL_NO_ERROR();
353
354 // Simple draw program.
355 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
356
357 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f, 1.0f, true);
358 EXPECT_GL_NO_ERROR();
359
360 glBindFramebuffer(GL_READ_FRAMEBUFFER, completeFBO);
361 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
362}
363
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500364// Use this to select which configurations (e.g. which renderer, which GLES major version) these
365// tests should be run against.
Geoff Lange0cc2a42016-01-20 10:58:17 -0500366ANGLE_INSTANTIATE_TEST(FramebufferFormatsTest,
Luc Ferronfa7503c2018-05-08 11:25:06 -0400367 ES2_VULKAN(),
Geoff Lange0cc2a42016-01-20 10:58:17 -0500368 ES2_D3D9(),
369 ES2_D3D11(),
370 ES3_D3D11(),
371 ES2_OPENGL(),
372 ES3_OPENGL(),
373 ES2_OPENGLES(),
374 ES3_OPENGLES());
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500375
Corentin Wallez57e6d502016-12-09 14:46:39 -0500376class FramebufferTest_ES3 : public ANGLETest
Jamie Madillb980c562018-11-27 11:34:27 -0500377{};
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500378
379// Covers invalidating an incomplete framebuffer. This should be a no-op, but should not error.
Corentin Wallez57e6d502016-12-09 14:46:39 -0500380TEST_P(FramebufferTest_ES3, InvalidateIncomplete)
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500381{
Geoff Lang857c09d2017-05-16 15:55:04 -0400382 GLFramebuffer framebuffer;
383 GLRenderbuffer renderbuffer;
384
385 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
386 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
387 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500388 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
389 glCheckFramebufferStatus(GL_FRAMEBUFFER));
390
391 std::vector<GLenum> attachments;
392 attachments.push_back(GL_COLOR_ATTACHMENT0);
393
394 glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments.data());
395 EXPECT_GL_NO_ERROR();
396}
397
Corentin Wallez57e6d502016-12-09 14:46:39 -0500398// Test that the framebuffer state tracking robustly handles a depth-only attachment being set
399// as a depth-stencil attachment. It is equivalent to detaching the depth-stencil attachment.
400TEST_P(FramebufferTest_ES3, DepthOnlyAsDepthStencil)
401{
Geoff Lang857c09d2017-05-16 15:55:04 -0400402 GLFramebuffer framebuffer;
403 GLRenderbuffer renderbuffer;
404
405 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
406 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
Corentin Wallez57e6d502016-12-09 14:46:39 -0500407 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 4, 4);
408
409 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
Geoff Lang857c09d2017-05-16 15:55:04 -0400410 renderbuffer);
Corentin Wallez57e6d502016-12-09 14:46:39 -0500411 EXPECT_GLENUM_NE(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
412}
413
Geoff Lang857c09d2017-05-16 15:55:04 -0400414// Test that the framebuffer correctly returns that it is not complete if invalid texture mip levels
415// are bound
416TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevels)
417{
418 GLFramebuffer framebuffer;
419 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
420
421 GLTexture texture;
422 glBindTexture(GL_TEXTURE_2D, texture);
423
424 // Create a complete mip chain in mips 1 to 3
425 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
426 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
427 glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
428
429 // Create another complete mip chain in mips 4 to 5
430 glTexImage2D(GL_TEXTURE_2D, 4, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
431 glTexImage2D(GL_TEXTURE_2D, 5, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
432
433 // Create a non-complete mip chain in mip 6
434 glTexImage2D(GL_TEXTURE_2D, 6, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
435
436 // Incomplete, mipLevel != baseLevel and texture is not mip complete
437 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
438 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
439 glCheckFramebufferStatus(GL_FRAMEBUFFER));
440
441 // Complete, mipLevel == baseLevel
442 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
443 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
444
445 // Complete, mipLevel != baseLevel but texture is now mip complete
446 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 2);
447 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
448 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 3);
449 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
450
451 // Incomplete, attached level below the base level
452 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
453 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
454 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
455 glCheckFramebufferStatus(GL_FRAMEBUFFER));
456
457 // Incomplete, attached level is beyond effective max level
458 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 4);
459 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
460 glCheckFramebufferStatus(GL_FRAMEBUFFER));
461
462 // Complete, mipLevel == baseLevel
463 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 4);
464 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
465
466 // Complete, mipLevel != baseLevel but texture is now mip complete
467 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 5);
468 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
469
470 // Complete, mipLevel == baseLevel
471 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 6);
472 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 6);
473 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
474}
475
Martin Radevd178aa42017-07-13 14:03:22 +0300476// Test that passing an attachment COLOR_ATTACHMENTm where m is equal to MAX_COLOR_ATTACHMENTS
477// generates an INVALID_OPERATION.
478// OpenGL ES Version 3.0.5 (November 3, 2016), 4.4.2.4 Attaching Texture Images to a Framebuffer, p.
479// 208
480TEST_P(FramebufferTest_ES3, ColorAttachmentIndexOutOfBounds)
481{
482 GLFramebuffer framebuffer;
483 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
484
485 GLint maxColorAttachments = 0;
486 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
487 GLenum attachment = static_cast<GLenum>(maxColorAttachments + GL_COLOR_ATTACHMENT0);
488
489 GLTexture texture;
490 glBindTexture(GL_TEXTURE_2D, texture.get());
491 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
492 glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture.get(), 0);
493 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
494}
495
Jamie Madilla0016b72017-07-14 14:30:46 -0400496// Check that depth-only attachments report the correct number of samples.
497TEST_P(FramebufferTest_ES3, MultisampleDepthOnly)
498{
499 GLRenderbuffer renderbuffer;
500 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
501 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 32, 32);
502
503 GLFramebuffer framebuffer;
504 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
505 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
506 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
507 EXPECT_GL_NO_ERROR();
508
509 GLint samples = 0;
510 glGetIntegerv(GL_SAMPLES, &samples);
511 EXPECT_GL_NO_ERROR();
512 EXPECT_GE(samples, 2);
513}
514
Jeff Gilbert8f8edd62017-10-31 14:26:30 -0700515// Check that we only compare width and height of attachments, not depth.
516TEST_P(FramebufferTest_ES3, AttachmentWith3DLayers)
517{
518 GLTexture texA;
519 glBindTexture(GL_TEXTURE_2D, texA);
520 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
521
522 GLTexture texB;
523 glBindTexture(GL_TEXTURE_3D, texB);
524 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 4, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
525
526 GLFramebuffer framebuffer;
527 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
528 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texA, 0);
529 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texB, 0, 0);
530 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
531 EXPECT_GL_NO_ERROR();
532}
533
Olli Etuahodbce1f82018-09-19 15:32:17 +0300534// Test that clearing the stencil buffer when the framebuffer only has a color attachment does not
535// crash.
536TEST_P(FramebufferTest_ES3, ClearNonexistentStencil)
537{
538 GLRenderbuffer rbo;
539 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
540 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
541
542 GLFramebuffer fbo;
543 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
544 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
545
546 GLint clearValue = 0;
547 glClearBufferiv(GL_STENCIL, 0, &clearValue);
548
549 // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
550 EXPECT_GL_NO_ERROR();
551}
552
553// Test that clearing the depth buffer when the framebuffer only has a color attachment does not
554// crash.
555TEST_P(FramebufferTest_ES3, ClearNonexistentDepth)
556{
557 GLRenderbuffer rbo;
558 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
559 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
560
561 GLFramebuffer fbo;
562 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
563 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
564
565 GLfloat clearValue = 0.0f;
566 glClearBufferfv(GL_DEPTH, 0, &clearValue);
567
568 // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
569 EXPECT_GL_NO_ERROR();
570}
571
572// Test that clearing a nonexistent color attachment does not crash.
573TEST_P(FramebufferTest_ES3, ClearNonexistentColor)
574{
575 GLRenderbuffer rbo;
576 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
577 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
578
579 GLFramebuffer fbo;
580 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
581 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
582
583 std::vector<GLfloat> clearValue = {{0.0f, 1.0f, 0.0f, 1.0f}};
584 glClearBufferfv(GL_COLOR, 1, clearValue.data());
585
586 // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
587 EXPECT_GL_NO_ERROR();
588}
589
590// Test that clearing the depth and stencil buffers when the framebuffer only has a color attachment
591// does not crash.
592TEST_P(FramebufferTest_ES3, ClearNonexistentDepthStencil)
593{
594 GLRenderbuffer rbo;
595 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
596 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
597
598 GLFramebuffer fbo;
599 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
600 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
601
602 glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0);
603
604 // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
605 EXPECT_GL_NO_ERROR();
606}
607
Olli Etuaho4ebd8f32018-09-20 11:12:46 +0300608// Test that clearing a color attachment that has been deleted doesn't crash.
609TEST_P(FramebufferTest_ES3, ClearDeletedAttachment)
610{
611 // An INVALID_FRAMEBUFFER_OPERATION error was seen in this test on Mac, not sure where it might
612 // be originating from. http://anglebug.com/2834
613 ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
614
615 GLFramebuffer fbo;
616 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
617
618 // There used to be a bug where some draw buffer state used to remain set even after the
619 // attachment was detached via deletion. That's why we create, attach and delete this RBO here.
620 GLuint rbo = 0u;
621 glGenRenderbuffers(1, &rbo);
622 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
623 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
624 glDeleteRenderbuffers(1, &rbo);
625
626 // There needs to be at least one color attachment to prevent early out from the clear calls.
627 GLRenderbuffer rbo2;
628 glBindRenderbuffer(GL_RENDERBUFFER, rbo2);
629 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
630 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rbo2);
631
632 ASSERT_GL_NO_ERROR();
633
634 // There's no error specified for clearing nonexistent buffers, it's simply a no-op, so we
635 // expect no GL errors below.
636 std::array<GLfloat, 4> floatClearValue = {0.0f, 0.0f, 0.0f, 0.0f};
637 glClearBufferfv(GL_COLOR, 0, floatClearValue.data());
638 EXPECT_GL_NO_ERROR();
639 std::array<GLuint, 4> uintClearValue = {0u, 0u, 0u, 0u};
640 glClearBufferuiv(GL_COLOR, 0, uintClearValue.data());
641 EXPECT_GL_NO_ERROR();
642 std::array<GLint, 4> intClearValue = {0, 0, 0, 0};
643 glClearBufferiv(GL_COLOR, 0, intClearValue.data());
644 EXPECT_GL_NO_ERROR();
645}
646
Corentin Wallez57e6d502016-12-09 14:46:39 -0500647ANGLE_INSTANTIATE_TEST(FramebufferTest_ES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
JiangYizhou461d9a32017-01-04 16:37:26 +0800648
649class FramebufferTest_ES31 : public ANGLETest
650{
JiangYizhou511937d2017-08-03 15:41:29 +0800651 protected:
652 void validateSamplePass(GLuint &query, GLuint &passedCount, GLint width, GLint height)
653 {
654 glUniform2i(0, width - 1, height - 1);
655 glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
656 glDrawArrays(GL_TRIANGLES, 0, 6);
657 glEndQuery(GL_ANY_SAMPLES_PASSED);
658 glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
659 EXPECT_GT(static_cast<GLint>(passedCount), 0);
660
661 glUniform2i(0, width - 1, height);
662 glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
663 glDrawArrays(GL_TRIANGLES, 0, 6);
664 glEndQuery(GL_ANY_SAMPLES_PASSED);
665 glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
666 EXPECT_EQ(static_cast<GLint>(passedCount), 0);
667
668 glUniform2i(0, width, height - 1);
669 glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
670 glDrawArrays(GL_TRIANGLES, 0, 6);
671 glEndQuery(GL_ANY_SAMPLES_PASSED);
672 glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
673 EXPECT_EQ(static_cast<GLint>(passedCount), 0);
674 }
JiangYizhou461d9a32017-01-04 16:37:26 +0800675};
676
677// Test that without attachment, if either the value of FRAMEBUFFER_DEFAULT_WIDTH or
678// FRAMEBUFFER_DEFAULT_HEIGHT parameters is zero, the framebuffer is incomplete.
679TEST_P(FramebufferTest_ES31, IncompleteMissingAttachmentDefaultParam)
680{
681 GLFramebuffer mFramebuffer;
682 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
683
684 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 1);
685 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 1);
686 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
687
688 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
689 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 0);
690 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
691 glCheckFramebufferStatus(GL_FRAMEBUFFER));
692
693 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 1);
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, 0);
699 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 1);
700 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
701 glCheckFramebufferStatus(GL_FRAMEBUFFER));
702
703 ASSERT_GL_NO_ERROR();
704}
705
706// Test that the sample count of a mix of texture and renderbuffer should be same.
707TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountMix)
708{
709 GLFramebuffer mFramebuffer;
710 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
711
712 GLTexture mTexture;
713 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture.get());
714 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, true);
715
716 GLRenderbuffer mRenderbuffer;
717 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer.get());
718 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 1, 1);
719 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
720 mTexture.get(), 0);
721 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
722 mRenderbuffer.get());
723 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
724 glCheckFramebufferStatus(GL_FRAMEBUFFER));
725
726 ASSERT_GL_NO_ERROR();
727}
728
729// Test that the sample count of texture attachments should be same.
730TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountTex)
731{
732 GLFramebuffer mFramebuffer;
733 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
734
735 GLTexture mTextures[2];
736 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[0].get());
737 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, true);
738 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[1].get());
739 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_RGBA8, 1, 1, true);
740 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
741 mTextures[0].get(), 0);
742 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
743 mTextures[1].get(), 0);
744 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
745 glCheckFramebufferStatus(GL_FRAMEBUFFER));
746
747 ASSERT_GL_NO_ERROR();
748}
749
750// Test that if the attached images are a mix of renderbuffers and textures, the value of
751// TEXTURE_FIXED_SAMPLE_LOCATIONS must be TRUE for all attached textures.
752TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsMix)
753{
754 GLFramebuffer mFramebuffer;
755 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
756
757 GLTexture mTexture;
758 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture.get());
759 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, false);
760
761 GLRenderbuffer mRenderbuffer;
762 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer.get());
763 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 1, GL_RGBA8, 1, 1);
764 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
765 mTexture.get(), 0);
766 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
767 mRenderbuffer.get());
768 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
769 glCheckFramebufferStatus(GL_FRAMEBUFFER));
770
771 ASSERT_GL_NO_ERROR();
772}
773
774// Test that the value of TEXTURE_FIXED_SAMPLE_LOCATIONS is the same for all attached textures.
775TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsTex)
776{
777 GLFramebuffer mFramebuffer;
778 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
779
780 GLTexture mTextures[2];
781 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[0].get());
782 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, false);
783 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
784 mTextures[0].get(), 0);
785 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[1].get());
786 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGB8, 1, 1, true);
787 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
788 mTextures[1].get(), 0);
789 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
790 glCheckFramebufferStatus(GL_FRAMEBUFFER));
791
792 ASSERT_GL_NO_ERROR();
793}
794
JiangYizhou511937d2017-08-03 15:41:29 +0800795// If there are no attachments, rendering will be limited to a rectangle having a lower left of
796// (0, 0) and an upper right of(width, height), where width and height are the framebuffer
797// object's default width and height.
JiangYizhou3db40722017-08-28 17:59:13 +0800798TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments)
JiangYizhou511937d2017-08-03 15:41:29 +0800799{
Yuly Novikov98f9f532017-11-15 19:16:19 -0500800 // anglebug.com/2253
801 ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
802
JiangYizhou10d41392017-12-18 18:13:36 +0800803 const std::string &vertexShader1 =
804 R"(#version 310 es
805 in layout(location = 0) highp vec2 a_position;
806 void main()
807 {
808 gl_Position = vec4(a_position, 0.0, 1.0);
809 })";
JiangYizhou511937d2017-08-03 15:41:29 +0800810
JiangYizhou10d41392017-12-18 18:13:36 +0800811 const std::string &fragShader1 =
812 R"(#version 310 es
813 uniform layout(location = 0) highp ivec2 u_expectedSize;
814 out layout(location = 5) mediump vec4 f_color;
815 void main()
816 {
817 if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;
818 f_color = vec4(1.0, 0.5, 0.25, 1.0);
819 })";
JiangYizhou511937d2017-08-03 15:41:29 +0800820
JiangYizhou10d41392017-12-18 18:13:36 +0800821 const std::string &vertexShader2 =
822 R"(#version 310 es
823 in layout(location = 0) highp vec2 a_position;
824 void main()
825 {
826 gl_Position = vec4(a_position, 0.0, 1.0);
827 })";
828
829 const std::string &fragShader2 =
830 R"(#version 310 es
831 uniform layout(location = 0) highp ivec2 u_expectedSize;
832 out layout(location = 2) mediump vec4 f_color;
833 void main()
834 {
835 if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;
836 f_color = vec4(1.0, 0.5, 0.25, 1.0);
837 })";
838
839 GLuint program1 = CompileProgram(vertexShader1, fragShader1);
840 ASSERT_NE(program1, 0u);
841
842 GLuint program2 = CompileProgram(vertexShader2, fragShader2);
843 ASSERT_NE(program2, 0u);
844
845 glUseProgram(program1);
JiangYizhou511937d2017-08-03 15:41:29 +0800846
847 GLFramebuffer mFramebuffer;
848 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
849 GLuint defaultWidth = 1;
850 GLuint defaultHeight = 1;
851
852 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, defaultWidth);
853 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, defaultHeight);
854 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
855
856 const float data[] = {
857 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f,
858 };
859
860 GLuint vertexArray = 0;
861 GLuint vertexBuffer = 0;
862 GLuint query = 0;
863 GLuint passedCount = 0;
864
865 glGenQueries(1, &query);
866 glGenVertexArrays(1, &vertexArray);
867 glBindVertexArray(vertexArray);
868
869 glGenBuffers(1, &vertexBuffer);
870 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
871 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
872
873 glEnableVertexAttribArray(0);
874 glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
JiangYizhou38d92b52017-09-13 13:47:52 +0800875 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
JiangYizhou511937d2017-08-03 15:41:29 +0800876
877 validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
878
JiangYizhou10d41392017-12-18 18:13:36 +0800879 glUseProgram(program2);
880 validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
881
882 glUseProgram(program1);
JiangYizhou511937d2017-08-03 15:41:29 +0800883 // If fbo has attachments, the rendering size should be the same as its attachment.
884 GLTexture mTexture;
885 GLuint width = 2;
886 GLuint height = 2;
887 glBindTexture(GL_TEXTURE_2D, mTexture.get());
888 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
JiangYizhou38d92b52017-09-13 13:47:52 +0800889
890 const GLenum bufs[] = {GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT5};
891
892 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, mTexture.get(),
JiangYizhou511937d2017-08-03 15:41:29 +0800893 0);
894 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
JiangYizhou38d92b52017-09-13 13:47:52 +0800895 glDrawBuffers(6, bufs);
JiangYizhou511937d2017-08-03 15:41:29 +0800896
897 validateSamplePass(query, passedCount, width, height);
898
899 // If fbo's attachment has been removed, the rendering size should be the same as framebuffer
900 // default size.
JiangYizhou38d92b52017-09-13 13:47:52 +0800901 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, 0, 0, 0);
JiangYizhou511937d2017-08-03 15:41:29 +0800902 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
903
904 validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
905
906 glDisableVertexAttribArray(0);
907 glBindBuffer(GL_ARRAY_BUFFER, 0);
908 glBindVertexArray(0);
909 glDeleteBuffers(1, &vertexBuffer);
910 glDeleteVertexArrays(1, &vertexArray);
911
912 ASSERT_GL_NO_ERROR();
913}
914
915ANGLE_INSTANTIATE_TEST(FramebufferTest_ES31, ES31_D3D11(), ES31_OPENGL(), ES31_OPENGLES());
Brandon Jones9fc87332017-12-13 15:46:52 -0800916
917class AddDummyTextureNoRenderTargetTest : public ANGLETest
918{
919 public:
920 AddDummyTextureNoRenderTargetTest()
921 {
922 setWindowWidth(512);
923 setWindowHeight(512);
924 setConfigRedBits(8);
925 setConfigGreenBits(8);
926 setConfigBlueBits(8);
927 setConfigAlphaBits(8);
928 }
929
930 void overrideWorkaroundsD3D(WorkaroundsD3D *workarounds) override
931 {
932 workarounds->addDummyTextureNoRenderTarget = true;
933 }
934};
935
936// Test to verify workaround succeeds when no program outputs exist http://anglebug.com/2283
937TEST_P(AddDummyTextureNoRenderTargetTest, NoProgramOutputWorkaround)
938{
939 const std::string &vShader = "void main() {}";
940 const std::string &fShader = "void main() {}";
941
942 ANGLE_GL_PROGRAM(drawProgram, vShader, fShader);
943
944 glUseProgram(drawProgram);
945
946 glDrawArrays(GL_TRIANGLES, 0, 6);
947
948 ASSERT_GL_NO_ERROR();
949}
950
951ANGLE_INSTANTIATE_TEST(AddDummyTextureNoRenderTargetTest, ES2_D3D11());