blob: ece99b062f8dced8a304181a43242cf4b69bd332 [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{
Geoff Langc4e93662017-05-01 10:45:59 -0400196 if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_storage"))
197 {
198 std::cout << "Test skipped due to missing ES3 or GL_EXT_texture_storage." << std::endl;
199 return;
200 }
201
Geoff Langb6a673a2014-06-05 14:19:16 -0400202 testTextureFormat(GL_RGBA4, 4, 4, 4, 4);
203}
204
Jamie Madillfa05f602015-05-07 13:47:11 -0400205TEST_P(FramebufferFormatsTest, RGB565)
Geoff Langb6a673a2014-06-05 14:19:16 -0400206{
Geoff Langc4e93662017-05-01 10:45:59 -0400207 if (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_storage"))
208 {
209 std::cout << "Test skipped due to missing ES3 or GL_EXT_texture_storage." << std::endl;
210 return;
211 }
212
Geoff Langb6a673a2014-06-05 14:19:16 -0400213 testTextureFormat(GL_RGB565, 5, 6, 5, 0);
214}
215
Jamie Madillfa05f602015-05-07 13:47:11 -0400216TEST_P(FramebufferFormatsTest, RGB8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400217{
Geoff Langc4e93662017-05-01 10:45:59 -0400218 if (getClientMajorVersion() < 3 &&
219 (!extensionEnabled("GL_OES_rgb8_rgba8") || !extensionEnabled("GL_EXT_texture_storage")))
Geoff Langf34d1db2015-05-20 14:10:46 -0400220 {
Geoff Langc4e93662017-05-01 10:45:59 -0400221 std::cout
222 << "Test skipped due to missing ES3 or GL_OES_rgb8_rgba8 and GL_EXT_texture_storage."
223 << std::endl;
Geoff Langf34d1db2015-05-20 14:10:46 -0400224 return;
225 }
226
Geoff Langb6a673a2014-06-05 14:19:16 -0400227 testTextureFormat(GL_RGB8_OES, 8, 8, 8, 0);
228}
229
Jamie Madillfa05f602015-05-07 13:47:11 -0400230TEST_P(FramebufferFormatsTest, BGRA8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400231{
Geoff Langc4e93662017-05-01 10:45:59 -0400232 if (!extensionEnabled("GL_EXT_texture_format_BGRA8888") ||
233 (getClientMajorVersion() < 3 && !extensionEnabled("GL_EXT_texture_storage")))
Geoff Langf34d1db2015-05-20 14:10:46 -0400234 {
Geoff Langc4e93662017-05-01 10:45:59 -0400235 std::cout << "Test skipped due to missing GL_EXT_texture_format_BGRA8888 or "
236 "GL_EXT_texture_storage."
237 << std::endl;
Geoff Langf34d1db2015-05-20 14:10:46 -0400238 return;
239 }
240
Geoff Langb6a673a2014-06-05 14:19:16 -0400241 testTextureFormat(GL_BGRA8_EXT, 8, 8, 8, 8);
242}
243
Jamie Madillfa05f602015-05-07 13:47:11 -0400244TEST_P(FramebufferFormatsTest, RGBA8)
Geoff Langb6a673a2014-06-05 14:19:16 -0400245{
Geoff Langc4e93662017-05-01 10:45:59 -0400246 if (getClientMajorVersion() < 3 &&
247 (!extensionEnabled("GL_OES_rgb8_rgba8") || !extensionEnabled("GL_EXT_texture_storage")))
Geoff Langf34d1db2015-05-20 14:10:46 -0400248 {
Geoff Langc4e93662017-05-01 10:45:59 -0400249 std::cout
250 << "Test skipped due to missing ES3 or GL_OES_rgb8_rgba8 and GL_EXT_texture_storage."
251 << std::endl;
Geoff Langf34d1db2015-05-20 14:10:46 -0400252 return;
253 }
254
Geoff Langb6a673a2014-06-05 14:19:16 -0400255 testTextureFormat(GL_RGBA8_OES, 8, 8, 8, 8);
256}
257
Jamie Madillfa05f602015-05-07 13:47:11 -0400258TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH16)
Corentin Walleze0902642014-11-04 12:32:15 -0800259{
260 testRenderbufferMultisampleFormat(2, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16);
261}
262
Jamie Madillfa05f602015-05-07 13:47:11 -0400263TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24)
Corentin Walleze0902642014-11-04 12:32:15 -0800264{
265 testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24);
266}
267
Jamie Madillfa05f602015-05-07 13:47:11 -0400268TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F)
Corentin Walleze0902642014-11-04 12:32:15 -0800269{
Martin Radev1be913c2016-07-11 17:59:16 +0300270 if (getClientMajorVersion() < 3)
Geoff Langf34d1db2015-05-20 14:10:46 -0400271 {
272 std::cout << "Test skipped due to missing ES3." << std::endl;
273 return;
274 }
275
Corentin Walleze0902642014-11-04 12:32:15 -0800276 testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32F);
277}
278
Jamie Madillfa05f602015-05-07 13:47:11 -0400279TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24_STENCIL8)
Corentin Walleze0902642014-11-04 12:32:15 -0800280{
281 testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8);
282}
283
Jamie Madillfa05f602015-05-07 13:47:11 -0400284TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F_STENCIL8)
Corentin Walleze0902642014-11-04 12:32:15 -0800285{
Martin Radev1be913c2016-07-11 17:59:16 +0300286 if (getClientMajorVersion() < 3)
Geoff Langf34d1db2015-05-20 14:10:46 -0400287 {
288 std::cout << "Test skipped due to missing ES3." << std::endl;
289 return;
290 }
291
Corentin Walleze0902642014-11-04 12:32:15 -0800292 testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH32F_STENCIL8);
293}
294
Jamie Madillfa05f602015-05-07 13:47:11 -0400295TEST_P(FramebufferFormatsTest, RenderbufferMultisample_STENCIL_INDEX8)
Corentin Walleze0902642014-11-04 12:32:15 -0800296{
Geoff Langf34d1db2015-05-20 14:10:46 -0400297 // TODO(geofflang): Figure out how to support GLSTENCIL_INDEX8 on desktop GL
Geoff Langdd323e92015-06-09 15:16:31 -0400298 if (GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
Geoff Langf34d1db2015-05-20 14:10:46 -0400299 {
300 std::cout << "Test skipped on Desktop OpenGL." << std::endl;
301 return;
302 }
303
Corentin Walleze0902642014-11-04 12:32:15 -0800304 testRenderbufferMultisampleFormat(2, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8);
305}
Jamie Madillfa05f602015-05-07 13:47:11 -0400306
Jamie Madill3215b202015-12-15 16:41:39 -0500307// Test that binding an incomplete cube map is rejected by ANGLE.
308TEST_P(FramebufferFormatsTest, IncompleteCubeMap)
309{
310 // First make a complete CubeMap.
311 glGenTextures(1, &mTexture);
312 glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture);
313 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
314 nullptr);
315 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
316 nullptr);
317 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
318 nullptr);
319 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
320 nullptr);
321 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
322 nullptr);
323 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
324 nullptr);
325 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
326 glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
327
328 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
329 mTexture, 0);
330
331 // Verify the framebuffer is complete.
332 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
333
334 // Make the CubeMap cube-incomplete.
335 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
336 nullptr);
337
338 // Verify the framebuffer is incomplete.
339 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
340 glCheckFramebufferStatus(GL_FRAMEBUFFER));
341
342 // Verify drawing with the incomplete framebuffer produces a GL error
343 const std::string &vs = "attribute vec4 position; void main() { gl_Position = position; }";
344 const std::string &ps = "void main() { gl_FragColor = vec4(1, 0, 0, 1); }";
345 mProgram = CompileProgram(vs, ps);
346 ASSERT_NE(0u, mProgram);
347 drawQuad(mProgram, "position", 0.5f);
348 ASSERT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
349}
350
Olli Etuahobc21e182016-02-23 16:04:57 +0200351// Test that a renderbuffer with zero height but nonzero width is handled without crashes/asserts.
352TEST_P(FramebufferFormatsTest, ZeroHeightRenderbuffer)
353{
Martin Radev1be913c2016-07-11 17:59:16 +0300354 if (getClientMajorVersion() < 3)
Olli Etuahobc21e182016-02-23 16:04:57 +0200355 {
356 std::cout << "Test skipped due to missing ES3" << std::endl;
357 return;
358 }
359
360 testZeroHeightRenderbuffer();
361}
362
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500363// Use this to select which configurations (e.g. which renderer, which GLES major version) these
364// tests should be run against.
Geoff Lange0cc2a42016-01-20 10:58:17 -0500365ANGLE_INSTANTIATE_TEST(FramebufferFormatsTest,
366 ES2_D3D9(),
367 ES2_D3D11(),
368 ES3_D3D11(),
369 ES2_OPENGL(),
370 ES3_OPENGL(),
371 ES2_OPENGLES(),
372 ES3_OPENGLES());
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500373
Corentin Wallez57e6d502016-12-09 14:46:39 -0500374class FramebufferTest_ES3 : public ANGLETest
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500375{
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500376};
377
378// Covers invalidating an incomplete framebuffer. This should be a no-op, but should not error.
Corentin Wallez57e6d502016-12-09 14:46:39 -0500379TEST_P(FramebufferTest_ES3, InvalidateIncomplete)
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500380{
Geoff Lang857c09d2017-05-16 15:55:04 -0400381 GLFramebuffer framebuffer;
382 GLRenderbuffer renderbuffer;
383
384 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
385 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
386 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
Jamie Madill1fbc59f2016-02-24 15:25:51 -0500387 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
388 glCheckFramebufferStatus(GL_FRAMEBUFFER));
389
390 std::vector<GLenum> attachments;
391 attachments.push_back(GL_COLOR_ATTACHMENT0);
392
393 glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments.data());
394 EXPECT_GL_NO_ERROR();
395}
396
Corentin Wallez57e6d502016-12-09 14:46:39 -0500397// Test that the framebuffer state tracking robustly handles a depth-only attachment being set
398// as a depth-stencil attachment. It is equivalent to detaching the depth-stencil attachment.
399TEST_P(FramebufferTest_ES3, DepthOnlyAsDepthStencil)
400{
Geoff Lang857c09d2017-05-16 15:55:04 -0400401 GLFramebuffer framebuffer;
402 GLRenderbuffer renderbuffer;
403
404 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
405 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
Corentin Wallez57e6d502016-12-09 14:46:39 -0500406 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 4, 4);
407
408 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
Geoff Lang857c09d2017-05-16 15:55:04 -0400409 renderbuffer);
Corentin Wallez57e6d502016-12-09 14:46:39 -0500410 EXPECT_GLENUM_NE(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
411}
412
Geoff Lang857c09d2017-05-16 15:55:04 -0400413// Test that the framebuffer correctly returns that it is not complete if invalid texture mip levels
414// are bound
415TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevels)
416{
417 GLFramebuffer framebuffer;
418 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
419
420 GLTexture texture;
421 glBindTexture(GL_TEXTURE_2D, texture);
422
423 // Create a complete mip chain in mips 1 to 3
424 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
425 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
426 glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
427
428 // Create another complete mip chain in mips 4 to 5
429 glTexImage2D(GL_TEXTURE_2D, 4, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
430 glTexImage2D(GL_TEXTURE_2D, 5, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
431
432 // Create a non-complete mip chain in mip 6
433 glTexImage2D(GL_TEXTURE_2D, 6, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
434
435 // Incomplete, mipLevel != baseLevel and texture is not mip complete
436 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
437 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
438 glCheckFramebufferStatus(GL_FRAMEBUFFER));
439
440 // Complete, mipLevel == baseLevel
441 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
442 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
443
444 // Complete, mipLevel != baseLevel but texture is now mip complete
445 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 2);
446 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
447 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 3);
448 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
449
450 // Incomplete, attached level below the base level
451 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
452 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
453 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
454 glCheckFramebufferStatus(GL_FRAMEBUFFER));
455
456 // Incomplete, attached level is beyond effective max level
457 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 4);
458 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
459 glCheckFramebufferStatus(GL_FRAMEBUFFER));
460
461 // Complete, mipLevel == baseLevel
462 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 4);
463 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
464
465 // Complete, mipLevel != baseLevel but texture is now mip complete
466 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 5);
467 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
468
469 // Complete, mipLevel == baseLevel
470 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 6);
471 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 6);
472 ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
473}
474
Martin Radevd178aa42017-07-13 14:03:22 +0300475// Test that passing an attachment COLOR_ATTACHMENTm where m is equal to MAX_COLOR_ATTACHMENTS
476// generates an INVALID_OPERATION.
477// OpenGL ES Version 3.0.5 (November 3, 2016), 4.4.2.4 Attaching Texture Images to a Framebuffer, p.
478// 208
479TEST_P(FramebufferTest_ES3, ColorAttachmentIndexOutOfBounds)
480{
481 GLFramebuffer framebuffer;
482 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
483
484 GLint maxColorAttachments = 0;
485 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
486 GLenum attachment = static_cast<GLenum>(maxColorAttachments + GL_COLOR_ATTACHMENT0);
487
488 GLTexture texture;
489 glBindTexture(GL_TEXTURE_2D, texture.get());
490 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
491 glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture.get(), 0);
492 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
493}
494
Jamie Madilla0016b72017-07-14 14:30:46 -0400495// Check that depth-only attachments report the correct number of samples.
496TEST_P(FramebufferTest_ES3, MultisampleDepthOnly)
497{
498 GLRenderbuffer renderbuffer;
499 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
500 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 32, 32);
501
502 GLFramebuffer framebuffer;
503 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
504 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
505 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
506 EXPECT_GL_NO_ERROR();
507
508 GLint samples = 0;
509 glGetIntegerv(GL_SAMPLES, &samples);
510 EXPECT_GL_NO_ERROR();
511 EXPECT_GE(samples, 2);
512}
513
Jeff Gilbert8f8edd62017-10-31 14:26:30 -0700514// Check that we only compare width and height of attachments, not depth.
515TEST_P(FramebufferTest_ES3, AttachmentWith3DLayers)
516{
517 GLTexture texA;
518 glBindTexture(GL_TEXTURE_2D, texA);
519 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
520
521 GLTexture texB;
522 glBindTexture(GL_TEXTURE_3D, texB);
523 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 4, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
524
525 GLFramebuffer framebuffer;
526 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
527 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texA, 0);
528 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texB, 0, 0);
529 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
530 EXPECT_GL_NO_ERROR();
531}
532
Corentin Wallez57e6d502016-12-09 14:46:39 -0500533ANGLE_INSTANTIATE_TEST(FramebufferTest_ES3, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
JiangYizhou461d9a32017-01-04 16:37:26 +0800534
535class FramebufferTest_ES31 : public ANGLETest
536{
JiangYizhou511937d2017-08-03 15:41:29 +0800537 protected:
538 void validateSamplePass(GLuint &query, GLuint &passedCount, GLint width, GLint height)
539 {
540 glUniform2i(0, width - 1, height - 1);
541 glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
542 glDrawArrays(GL_TRIANGLES, 0, 6);
543 glEndQuery(GL_ANY_SAMPLES_PASSED);
544 glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
545 EXPECT_GT(static_cast<GLint>(passedCount), 0);
546
547 glUniform2i(0, width - 1, height);
548 glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
549 glDrawArrays(GL_TRIANGLES, 0, 6);
550 glEndQuery(GL_ANY_SAMPLES_PASSED);
551 glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
552 EXPECT_EQ(static_cast<GLint>(passedCount), 0);
553
554 glUniform2i(0, width, height - 1);
555 glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
556 glDrawArrays(GL_TRIANGLES, 0, 6);
557 glEndQuery(GL_ANY_SAMPLES_PASSED);
558 glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
559 EXPECT_EQ(static_cast<GLint>(passedCount), 0);
560 }
JiangYizhou461d9a32017-01-04 16:37:26 +0800561};
562
563// Test that without attachment, if either the value of FRAMEBUFFER_DEFAULT_WIDTH or
564// FRAMEBUFFER_DEFAULT_HEIGHT parameters is zero, the framebuffer is incomplete.
565TEST_P(FramebufferTest_ES31, IncompleteMissingAttachmentDefaultParam)
566{
567 GLFramebuffer mFramebuffer;
568 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
569
570 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 1);
571 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 1);
572 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
573
574 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
575 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 0);
576 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
577 glCheckFramebufferStatus(GL_FRAMEBUFFER));
578
579 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 1);
580 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 0);
581 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
582 glCheckFramebufferStatus(GL_FRAMEBUFFER));
583
584 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
585 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 1);
586 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
587 glCheckFramebufferStatus(GL_FRAMEBUFFER));
588
589 ASSERT_GL_NO_ERROR();
590}
591
592// Test that the sample count of a mix of texture and renderbuffer should be same.
593TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountMix)
594{
595 GLFramebuffer mFramebuffer;
596 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
597
598 GLTexture mTexture;
599 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture.get());
600 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, true);
601
602 GLRenderbuffer mRenderbuffer;
603 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer.get());
604 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 1, 1);
605 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
606 mTexture.get(), 0);
607 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
608 mRenderbuffer.get());
609 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
610 glCheckFramebufferStatus(GL_FRAMEBUFFER));
611
612 ASSERT_GL_NO_ERROR();
613}
614
615// Test that the sample count of texture attachments should be same.
616TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountTex)
617{
618 GLFramebuffer mFramebuffer;
619 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
620
621 GLTexture mTextures[2];
622 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[0].get());
623 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, true);
624 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[1].get());
625 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_RGBA8, 1, 1, true);
626 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
627 mTextures[0].get(), 0);
628 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
629 mTextures[1].get(), 0);
630 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
631 glCheckFramebufferStatus(GL_FRAMEBUFFER));
632
633 ASSERT_GL_NO_ERROR();
634}
635
636// Test that if the attached images are a mix of renderbuffers and textures, the value of
637// TEXTURE_FIXED_SAMPLE_LOCATIONS must be TRUE for all attached textures.
638TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsMix)
639{
640 GLFramebuffer mFramebuffer;
641 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
642
643 GLTexture mTexture;
644 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture.get());
645 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, false);
646
647 GLRenderbuffer mRenderbuffer;
648 glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer.get());
649 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 1, GL_RGBA8, 1, 1);
650 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
651 mTexture.get(), 0);
652 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
653 mRenderbuffer.get());
654 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
655 glCheckFramebufferStatus(GL_FRAMEBUFFER));
656
657 ASSERT_GL_NO_ERROR();
658}
659
660// Test that the value of TEXTURE_FIXED_SAMPLE_LOCATIONS is the same for all attached textures.
661TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsTex)
662{
663 GLFramebuffer mFramebuffer;
664 glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
665
666 GLTexture mTextures[2];
667 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[0].get());
668 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, false);
669 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
670 mTextures[0].get(), 0);
671 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[1].get());
672 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGB8, 1, 1, true);
673 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
674 mTextures[1].get(), 0);
675 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
676 glCheckFramebufferStatus(GL_FRAMEBUFFER));
677
678 ASSERT_GL_NO_ERROR();
679}
680
JiangYizhou511937d2017-08-03 15:41:29 +0800681// If there are no attachments, rendering will be limited to a rectangle having a lower left of
682// (0, 0) and an upper right of(width, height), where width and height are the framebuffer
683// object's default width and height.
JiangYizhou3db40722017-08-28 17:59:13 +0800684TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments)
JiangYizhou511937d2017-08-03 15:41:29 +0800685{
Yuly Novikov98f9f532017-11-15 19:16:19 -0500686 // anglebug.com/2253
687 ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
688
JiangYizhou10d41392017-12-18 18:13:36 +0800689 const std::string &vertexShader1 =
690 R"(#version 310 es
691 in layout(location = 0) highp vec2 a_position;
692 void main()
693 {
694 gl_Position = vec4(a_position, 0.0, 1.0);
695 })";
JiangYizhou511937d2017-08-03 15:41:29 +0800696
JiangYizhou10d41392017-12-18 18:13:36 +0800697 const std::string &fragShader1 =
698 R"(#version 310 es
699 uniform layout(location = 0) highp ivec2 u_expectedSize;
700 out layout(location = 5) mediump vec4 f_color;
701 void main()
702 {
703 if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;
704 f_color = vec4(1.0, 0.5, 0.25, 1.0);
705 })";
JiangYizhou511937d2017-08-03 15:41:29 +0800706
JiangYizhou10d41392017-12-18 18:13:36 +0800707 const std::string &vertexShader2 =
708 R"(#version 310 es
709 in layout(location = 0) highp vec2 a_position;
710 void main()
711 {
712 gl_Position = vec4(a_position, 0.0, 1.0);
713 })";
714
715 const std::string &fragShader2 =
716 R"(#version 310 es
717 uniform layout(location = 0) highp ivec2 u_expectedSize;
718 out layout(location = 2) mediump vec4 f_color;
719 void main()
720 {
721 if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;
722 f_color = vec4(1.0, 0.5, 0.25, 1.0);
723 })";
724
725 GLuint program1 = CompileProgram(vertexShader1, fragShader1);
726 ASSERT_NE(program1, 0u);
727
728 GLuint program2 = CompileProgram(vertexShader2, fragShader2);
729 ASSERT_NE(program2, 0u);
730
731 glUseProgram(program1);
JiangYizhou511937d2017-08-03 15:41:29 +0800732
733 GLFramebuffer mFramebuffer;
734 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
735 GLuint defaultWidth = 1;
736 GLuint defaultHeight = 1;
737
738 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, defaultWidth);
739 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, defaultHeight);
740 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
741
742 const float data[] = {
743 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f,
744 };
745
746 GLuint vertexArray = 0;
747 GLuint vertexBuffer = 0;
748 GLuint query = 0;
749 GLuint passedCount = 0;
750
751 glGenQueries(1, &query);
752 glGenVertexArrays(1, &vertexArray);
753 glBindVertexArray(vertexArray);
754
755 glGenBuffers(1, &vertexBuffer);
756 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
757 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
758
759 glEnableVertexAttribArray(0);
760 glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
JiangYizhou38d92b52017-09-13 13:47:52 +0800761 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
JiangYizhou511937d2017-08-03 15:41:29 +0800762
763 validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
764
JiangYizhou10d41392017-12-18 18:13:36 +0800765 glUseProgram(program2);
766 validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
767
768 glUseProgram(program1);
JiangYizhou511937d2017-08-03 15:41:29 +0800769 // If fbo has attachments, the rendering size should be the same as its attachment.
770 GLTexture mTexture;
771 GLuint width = 2;
772 GLuint height = 2;
773 glBindTexture(GL_TEXTURE_2D, mTexture.get());
774 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
JiangYizhou38d92b52017-09-13 13:47:52 +0800775
776 const GLenum bufs[] = {GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT5};
777
778 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, mTexture.get(),
JiangYizhou511937d2017-08-03 15:41:29 +0800779 0);
780 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
JiangYizhou38d92b52017-09-13 13:47:52 +0800781 glDrawBuffers(6, bufs);
JiangYizhou511937d2017-08-03 15:41:29 +0800782
783 validateSamplePass(query, passedCount, width, height);
784
785 // If fbo's attachment has been removed, the rendering size should be the same as framebuffer
786 // default size.
JiangYizhou38d92b52017-09-13 13:47:52 +0800787 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, 0, 0, 0);
JiangYizhou511937d2017-08-03 15:41:29 +0800788 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
789
790 validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
791
792 glDisableVertexAttribArray(0);
793 glBindBuffer(GL_ARRAY_BUFFER, 0);
794 glBindVertexArray(0);
795 glDeleteBuffers(1, &vertexBuffer);
796 glDeleteVertexArrays(1, &vertexArray);
797
798 ASSERT_GL_NO_ERROR();
799}
800
801ANGLE_INSTANTIATE_TEST(FramebufferTest_ES31, ES31_D3D11(), ES31_OPENGL(), ES31_OPENGLES());
Brandon Jones9fc87332017-12-13 15:46:52 -0800802
803class AddDummyTextureNoRenderTargetTest : public ANGLETest
804{
805 public:
806 AddDummyTextureNoRenderTargetTest()
807 {
808 setWindowWidth(512);
809 setWindowHeight(512);
810 setConfigRedBits(8);
811 setConfigGreenBits(8);
812 setConfigBlueBits(8);
813 setConfigAlphaBits(8);
814 }
815
816 void overrideWorkaroundsD3D(WorkaroundsD3D *workarounds) override
817 {
818 workarounds->addDummyTextureNoRenderTarget = true;
819 }
820};
821
822// Test to verify workaround succeeds when no program outputs exist http://anglebug.com/2283
823TEST_P(AddDummyTextureNoRenderTargetTest, NoProgramOutputWorkaround)
824{
825 const std::string &vShader = "void main() {}";
826 const std::string &fShader = "void main() {}";
827
828 ANGLE_GL_PROGRAM(drawProgram, vShader, fShader);
829
830 glUseProgram(drawProgram);
831
832 glDrawArrays(GL_TRIANGLES, 0, 6);
833
834 ASSERT_GL_NO_ERROR();
835}
836
837ANGLE_INSTANTIATE_TEST(AddDummyTextureNoRenderTargetTest, ES2_D3D11());