• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2021 Google Inc.
6  * Copyright (c) 2021 The Khronos Group Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file glcFramebuffercompleteness.cpp
22  * \brief Tests for OpenGL ES frame buffer completeness
23  *//*--------------------------------------------------------------------*/
24 #include "glcFramebufferCompleteness.hpp"
25 #include "deInt32.h"
26 #include "gluDefs.hpp"
27 #include "gluContextInfo.hpp"
28 #include "glwEnums.hpp"
29 #include "glwFunctions.hpp"
30 #include "tcuStringTemplate.hpp"
31 
32 #include <algorithm>
33 #include <functional>
34 #include <map>
35 #include <memory>
36 #include <sstream>
37 #include <string>
38 #include <vector>
39 
40 namespace glcts
41 {
42 namespace
43 {
44 
45 using namespace glw;
46 using namespace std;
47 
48 struct TestContext
49 {
50 	const glu::RenderContext&	renderContext;
51 	const glw::Functions&		gl;
52 	vector<GLuint>&				fboIds;
53 	vector<GLuint>&				texIds;
54 	vector<GLuint>&				rboIds;
55 
56 	void texParameteri					(GLuint texId, GLenum target, GLenum pname, GLint parameter);
57 	void bindTexture					(GLenum target, GLuint texId);
58 	void texImage2D						(GLenum target, GLuint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border,
59 										 GLenum format, GLenum type, const void* data);
60 	void texImage2D						(GLuint texId, GLenum target, GLuint level, GLint internalFormat, GLsizei width, GLsizei height,
61 										 GLint border, GLenum format, GLenum type, const void* data);
62 	void texImage3D						(GLuint texId, GLenum target, GLuint level, GLint internalFormat, GLsizei width, GLsizei height,
63 										 GLsizei depth, GLint border, GLenum format, GLenum type, const void* data);
64 	void renderbufferStorage			(GLuint rboId, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height);
65 	void renderbufferStorageMultisample	(GLuint rboId, GLenum target, GLsizei samples, GLenum internalFormat,
66 										 GLsizei width, GLsizei height);
67 	void bindFramebuffer				(GLenum target, GLuint fboId);
68 	void framebufferTexture2D			(GLenum target, GLenum attachment, GLenum textarget, GLuint texId, GLint level);
69 	void framebufferTextureLayer		(GLenum target, GLenum attachment, GLuint texId, GLint level, GLint layer);
70 	void framebufferRenderbuffer		(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint rboId);
71 };
72 
texParameteri(GLuint texId,GLenum target,GLenum pname,GLint parameter)73 void TestContext::texParameteri(GLuint texId, GLenum target, GLenum pname, GLint parameter)
74 {
75 	bindTexture(target, texId);
76 	gl.texParameteri(target, pname, parameter);
77 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri() failed");
78 	bindTexture(target, 0);
79 }
80 
bindTexture(GLenum target,GLuint texId)81 void TestContext::bindTexture(GLenum target, GLuint texId)
82 {
83 	gl.bindTexture(target, texId);
84 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed");
85 }
86 
texImage2D(GLenum target,GLuint level,GLint internalFormat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const void * data)87 void TestContext::texImage2D(GLenum target, GLuint level, GLint internalFormat, GLsizei width, GLsizei height,
88 							 GLint border, GLenum format, GLenum type, const void* data)
89 {
90 	gl.texImage2D(target, level, internalFormat, width, height, border, format, type, data);
91 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D() failed");
92 }
93 
texImage2D(GLuint texId,GLenum target,GLuint level,GLint internalFormat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const void * data)94 void TestContext::texImage2D(GLuint texId, GLenum target, GLuint level, GLint internalFormat, GLsizei width,
95 							 GLsizei height, GLint border, GLenum format, GLenum type, const void* data)
96 {
97 	bindTexture(target, texId);
98 	texImage2D(target, level, internalFormat, width, height, border, format, type, data);
99 	bindTexture(target, 0);
100 }
101 
texImage3D(GLuint texId,GLenum target,GLuint level,GLint internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const void * data)102 void TestContext::texImage3D(GLuint texId, GLenum target, GLuint level, GLint internalFormat, GLsizei width,
103 							 GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* data)
104 {
105 	bindTexture(target, texId);
106 	gl.texImage3D(target, level, internalFormat, width, height, depth, border, format, type, data);
107 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D() failed");
108 	bindTexture(target, 0);
109 }
110 
renderbufferStorage(GLuint rboId,GLenum target,GLenum internalFormat,GLsizei width,GLsizei height)111 void TestContext::renderbufferStorage(GLuint rboId, GLenum target, GLenum internalFormat, GLsizei width, GLsizei height)
112 {
113 	gl.bindRenderbuffer(GL_RENDERBUFFER, rboId);
114 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed");
115 	gl.renderbufferStorage(target, internalFormat, width, height);
116 	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage() failed");
117 	gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
118 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed");
119 }
120 
renderbufferStorageMultisample(GLuint rboId,GLenum target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height)121 void TestContext::renderbufferStorageMultisample(GLuint rboId, GLenum target, GLsizei samples, GLenum internalFormat,
122 												 GLsizei width, GLsizei height)
123 {
124 	gl.bindRenderbuffer(GL_RENDERBUFFER, rboId);
125 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed");
126 	gl.renderbufferStorageMultisample(target, samples, internalFormat, width, height);
127 	GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorageMultisample() failed");
128 	gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
129 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed");
130 }
131 
bindFramebuffer(GLenum target,GLuint fboId)132 void TestContext::bindFramebuffer(GLenum target, GLuint fboId)
133 {
134 	gl.bindFramebuffer(target, fboId);
135 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() failed");
136 }
137 
framebufferTexture2D(GLenum target,GLenum attachment,GLenum textarget,GLuint texId,GLint level)138 void TestContext::framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texId, GLint level)
139 {
140 	gl.framebufferTexture2D(target, attachment, textarget, texId, level);
141 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() failed");
142 }
143 
framebufferTextureLayer(GLenum target,GLenum attachment,GLuint texId,GLint level,GLint layer)144 void TestContext::framebufferTextureLayer(GLenum target, GLenum attachment, GLuint texId, GLint level, GLint layer)
145 {
146 	gl.framebufferTextureLayer(target, attachment, texId, level, layer);
147 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() failed");
148 }
149 
framebufferRenderbuffer(GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint rboId)150 void TestContext::framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint rboId)
151 {
152 	gl.framebufferRenderbuffer(target, attachment, renderbuffertarget, rboId);
153 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer() failed");
154 }
155 
156 typedef function<GLenum(const glu::ContextInfo& contextInfo)>		ExpectedStatusFn;
157 typedef function<void(TestContext& context)>						TestFn;
158 
expectedStatusConstant(GLenum expectedStatus)159 ExpectedStatusFn expectedStatusConstant(GLenum expectedStatus)
160 {
161 	return [expectedStatus] (const glu::ContextInfo&) { return expectedStatus; };
162 }
163 
expectedStatusWithExtension(const string & extension,GLenum statusIfSupported,GLenum statusIfNotSupported)164 ExpectedStatusFn expectedStatusWithExtension(const string& extension, GLenum statusIfSupported, GLenum statusIfNotSupported)
165 {
166 	return [extension, statusIfSupported, statusIfNotSupported](const glu::ContextInfo &contextInfo)
167 	{
168 		if (contextInfo.isExtensionSupported(extension.c_str()))
169 			return statusIfSupported;
170 		else
171 			return statusIfNotSupported;
172 	};
173 }
174 
175 struct TestStep
176 {
177 	TestFn				testFn;
178 	ExpectedStatusFn	expectedFbStatus;
179 };
180 
181 typedef function<void(vector<TestStep>&, TestContext& context)>		StepsGeneratorFn;
182 
183 struct ExtensionEntry
184 {
185 	string				name;
186 	bool				supportedStatus;
187 };
188 
189 struct TestParams
190 {
191 	string					name;
192 	string					description;
193 	glu::ApiType			apiType;
194 	size_t					numFboIds;
195 	size_t					numTexIds;
196 	size_t					numRboIds;
197 	vector<TestStep>		initialSteps;
198 	StepsGeneratorFn		stepsGenerator;
199 };
200 
201 const GLuint			TEXTURE_WIDTH			= 16;
202 const GLuint			TEXTURE_HEIGHT			= 16;
203 const GLuint			TEXTURE_DEPTH			= 16;
204 
205 static const GLenum		cubemapTextureTargets[]	=
206 {
207 	GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
208 	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
209 	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_TEXTURE_CUBE_MAP_POSITIVE_Z
210 };
211 
212 const glu::ApiType		apiES30					= glu::ApiType::es(3, 0);
213 const glu::ApiType		apiES31					= glu::ApiType::es(3, 1);
214 const glu::ApiType		apiES32					= glu::ApiType::es(3, 2);
215 
isDifferentRboSampleCountsSupported(TestContext & testContext,GLint & maxSamples)216 bool isDifferentRboSampleCountsSupported(TestContext& testContext, GLint& maxSamples)
217 {
218 	const auto&	gl				= testContext.gl;
219 	gl.getIntegerv(GL_MAX_SAMPLES, &maxSamples);
220 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed");
221 
222 	if (maxSamples < 4)
223 		TCU_FAIL("GL_MAX_SAMPLES needs to be >= 4");
224 
225 	testContext.renderbufferStorageMultisample(testContext.rboIds[0], GL_RENDERBUFFER, 1, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT);
226 	gl.bindRenderbuffer(GL_RENDERBUFFER, testContext.rboIds[0]);
227 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed");
228 
229 	GLint		minSamplesRbo;
230 	gl.getRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &minSamplesRbo);
231 	GLU_EXPECT_NO_ERROR(gl.getError(), "getRenderbufferParameteriv() failed");
232 	gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
233 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer() failed");
234 
235 	return minSamplesRbo < maxSamples;
236 }
237 
isDifferentTextureSampleCountsSupported(TestContext & testContext,GLint & maxSamples)238 bool isDifferentTextureSampleCountsSupported(TestContext& testContext, GLint& maxSamples)
239 {
240 	if (glu::contextSupports(testContext.renderContext.getType(), apiES31))
241 	{
242 		const auto&	gl				= testContext.gl;
243 		GLint	maxColorSamples;
244 		gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &maxColorSamples);
245 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed");
246 
247 		GLint	maxDepthSamples;
248 		gl.getIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &maxDepthSamples);
249 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed");
250 
251 		maxSamples = min(maxColorSamples, maxDepthSamples);
252 
253 		GLuint	tempTexId;
254 		gl.genTextures(1, &tempTexId);
255 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
256 
257 		testContext.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, tempTexId);
258 		gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_TRUE);
259 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() failed");
260 
261 		GLint	minSamplesTex;
262 		gl.getTexLevelParameteriv(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_TEXTURE_SAMPLES, &minSamplesTex);
263 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexLevelParameteriv() failed");
264 
265 		testContext.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
266 		gl.deleteTextures(1, &tempTexId);
267 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() failed");
268 
269 		return minSamplesTex < maxSamples;
270 	}
271 	return false;
272 }
273 
274 /* Tests are defined as ordered series of steps that each expect a specific current framebuffer status
275    after being executed. A new TestContext instance (parameter) is created for each test but all steps
276    within a test use the same context. No code in addition to the framebuffer status check is executed
277    between steps. */
278 const TestParams		tests[]					=
279 {
280 	{
281 		"incomplete_missing_attachment",														// string					name
282 		"No attachments",																		// string					description
283 		apiES30,																				// glu::ApiType				apiType
284 		1,																						// size_t					numFboIds
285 		0,																						// size_t					numTexIds
286 		0,																						// size_t					numRboIds
287 		{																						// vector<TestStep>			initialSteps
288 			{
__anond6e629770402() 289 				[](TestContext& context) {
290 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
291 				},
292 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
293 			}
294 		},
295 		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
296 	},
297 	{
298 		"incomplete_image_zero_width",															// string					name
299 		"Zero width attachment image",															// string					description
300 		apiES30,																				// glu::ApiType				apiType
301 		1,																						// size_t					numFboIds
302 		1,																						// size_t					numTexIds
303 		0,																						// size_t					numRboIds
304 		{																						// vector<TestStep>			initialSteps
305 			{
306 				[](TestContext& context)
__anond6e629770502() 307 				{
308 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
309 				},
310 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
311 			},
312 			{
313 				[](TestContext& context)
__anond6e629770602() 314 				{
315 					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 0, TEXTURE_HEIGHT, 0,
316 									   GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, DE_NULL);
317 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, context.texIds[0], 0);
318 				},
319 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
320 			}
321 		},
322 		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
323 	},
324 	{
325 		"incomplete_image_zero_height",															// string					name
326 		"Zero height attachment image",															// string					description
327 		apiES30,																				// glu::ApiType				apiType
328 		1,																						// size_t					numFboIds
329 		1,																						// size_t					numTexIds
330 		0,																						// size_t					numRboIds
331 		{																						// vector<TestStep>			initialSteps
332 			{
333 				[](TestContext& context)
__anond6e629770702() 334 				{
335 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
336 				},
337 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
338 			},
339 			{
340 				[](TestContext& context)
__anond6e629770802() 341 				{
342 					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 0, TEXTURE_WIDTH, 0,
343 									   GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, DE_NULL);
344 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, context.texIds[0], 0);
345 				},
346 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
347 			}
348 		},
349 		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
350 	},
351 	{
352 		"incomplete_texture_3d_layer_oob",														// string					name
353 		"3D texture layer out of bounds",														// string					description
354 		apiES30,																				// glu::ApiType				apiType
355 		1,																						// size_t					numFboIds
356 		1,																						// size_t					numTexIds
357 		0,																						// size_t					numRboIds
358 		{																						// vector<TestStep>			initialSteps
359 			{
360 				[](TestContext& context)
__anond6e629770902() 361 				{
362 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
363 				},
364 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
365 			},
366 			{
367 				[](TestContext& context)
__anond6e629770a02() 368 				{
369 					context.texImage3D(context.texIds[0], GL_TEXTURE_3D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT,
370 									   TEXTURE_DEPTH, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
371 					context.framebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, context.texIds[0], 0,
372 													TEXTURE_DEPTH + 1);
373 				},
374 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
375 			}
376 		},
377 		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
378 	},
379 	{
380 		"incomplete_texture_2d_layer_oob",														// string					name
381 		"2D texture layer out of bounds",														// string					description
382 		apiES30,																				// glu::ApiType				apiType
383 		1,																						// size_t					numFboIds
384 		1,																						// size_t					numTexIds
385 		0,																						// size_t					numRboIds
386 		{																						// vector<TestStep>			initialSteps
387 			{
388 				[](TestContext& context)
__anond6e629770b02() 389 				{
390 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
391 				},
392 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
393 			},
394 			{
395 				[](TestContext& context)
__anond6e629770c02() 396 				{
397 					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
398 									   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
399 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 1);
400 				},
401 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
402 			}
403 		},
404 		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
405 	},
406 	{
407 		"incomplete_texture_2d_mm_layer_oob",													// string					name
408 		"2D mipmapped texture layer out of bounds",												// string					description
409 		apiES30,																				// glu::ApiType				apiType
410 		1,																						// size_t					numFboIds
411 		1,																						// size_t					numTexIds
412 		0,																						// size_t					numRboIds
413 		{																						// vector<TestStep>			initialSteps
414 			{
415 				[](TestContext& context)
__anond6e629770d02() 416 				{
417 					context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
418 										  GL_LINEAR_MIPMAP_LINEAR);
419 					context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
420 					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 1, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
421 									   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
422 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
423 				},
424 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
425 			},
426 			{
427 				[](TestContext& context)
__anond6e629770e02() 428 				{
429 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 0);
430 				},
431 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
432 			},
433 			{
434 				[](TestContext& context)
__anond6e629770f02() 435 				{
436 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 1);
437 				},
438 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
439 			},
440 			{
441 				[](TestContext& context)
__anond6e629771002() 442 				{
443 					const deUint32 maxMipmapLevel = deLog2Floor32(de::max(TEXTURE_WIDTH, TEXTURE_HEIGHT));
444 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0],
445 												 maxMipmapLevel + 2);
446 				},
447 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
448 			},
449 		},
450 		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
451 	},
452 	{
453 		"mutable_nbl_texture_expect_mipmap_complete",											// string					name
454 		"Mutable non base level texture as framebuffer attachment must be mipmap complete",		// string					description
455 		apiES30,																				// glu::ApiType				apiType
456 		1,																						// size_t					numFboIds
457 		1,																						// size_t					numTexIds
458 		0,																						// size_t					numRboIds
459 		{																						// vector<TestStep>			initialSteps
460 			{
461 				[](TestContext& context)
__anond6e629771102() 462 				{
463 					DE_ASSERT(TEXTURE_WIDTH >= 8 && TEXTURE_HEIGHT >= 8);
464 
465 					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
466 									   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
467 					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 1, GL_RGBA8, TEXTURE_WIDTH >> 1,
468 									   TEXTURE_HEIGHT >> 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
469 					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 3, GL_RGBA8, TEXTURE_WIDTH >> 3,
470 									   TEXTURE_HEIGHT >> 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
471 					context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3);
472 					context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
473 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
474 				},
475 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
476 			},
477 			{
478 				[](TestContext& context)
__anond6e629771202() 479 				{
480 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 1);
481 				},
482 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
483 			},
484 			{
485 				[](TestContext& context)
__anond6e629771302() 486 				{
487 					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 2, GL_RGBA8, TEXTURE_WIDTH >> 2,
488 									   TEXTURE_HEIGHT >> 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
489 				},
490 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
491 			}
492 		},
493 		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
494 	},
495 	{
496 		"mutable_nbl_texture_expect_cube_complete",												// string					name
497 		"Mutable non base level texture as framebuffer attachment must be cube complete",		// string					description
498 		apiES30,																				// glu::ApiType				apiType
499 		1,																						// size_t					numFboIds
500 		1,																						// size_t					numTexIds
501 		0,																						// size_t					numRboIds
502 		{																						// vector<TestStep>			initialSteps
503 			{
504 				[](TestContext& context)
__anond6e629771402() 505 				{
506 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
507 				},
508 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
509 			},
510 			{
511 				[](TestContext& context)
__anond6e629771502() 512 				{
513 					context.texParameteri(context.texIds[0], GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 1);
514 					context.texParameteri(context.texIds[0], GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
515 
516 					context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
517 					for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(cubemapTextureTargets); ++i)
518 					{
519 						if (i % 2)
520 							continue;
521 						context.texImage2D(cubemapTextureTargets[i], 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA,
522 										   GL_UNSIGNED_BYTE, DE_NULL);
523 						context.texImage2D(cubemapTextureTargets[i], 1, GL_RGBA8, TEXTURE_WIDTH >> 1, TEXTURE_HEIGHT >> 1, 0, GL_RGBA,
524 										   GL_UNSIGNED_BYTE, DE_NULL);
525 					}
526 					context.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
527 
528 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, cubemapTextureTargets[0],
529 												 context.texIds[0], 1);
530 				},
531 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
532 			},
533 			{
534 				[](TestContext& context)
__anond6e629771602() 535 				{
536 					context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
537 					for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(cubemapTextureTargets); ++i)
538 					{
539 						if (i % 2 == 0)
540 							continue;
541 						context.texImage2D(cubemapTextureTargets[i], 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA,
542 										   GL_UNSIGNED_BYTE, DE_NULL);
543 						context.texImage2D(cubemapTextureTargets[i], 1, GL_RGBA8, TEXTURE_WIDTH >> 1, TEXTURE_HEIGHT >> 1, 0, GL_RGBA,
544 										   GL_UNSIGNED_BYTE, DE_NULL);
545 					}
546 					context.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
547 				},
548 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
549 			}
550 		},
551 		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
552 	},
553 	{
554 		"expect_renderable_internal_format",													// string					name
555 		"Color/Depth/Stencil attachment texture must have a color/depth/stencil"				// string					description
556 		" renderable internal format",
557 		apiES30,																				// glu::ApiType				apiType
558 		1,																						// size_t					numFboIds
559 		3,																						// size_t					numTexIds
560 		0,																						// size_t					numRboIds
561 		{																						// vector<TestStep>			initialSteps
562 			{
563 				[](TestContext& context)
__anond6e629771702() 564 				{
565 					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
566 									   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
567 					context.texImage2D(context.texIds[1], GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, TEXTURE_WIDTH,
568 									   TEXTURE_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, DE_NULL);
569 					context.texImage2D(context.texIds[2], GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, TEXTURE_WIDTH, TEXTURE_HEIGHT,
570 									   0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, DE_NULL);
571 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
572 				},
573 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
574 			},
575 			{
576 				[](TestContext& context)
__anond6e629771802() 577 				{
578 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, context.texIds[0], 0);
579 				},
580 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
581 			},
582 			{
583 				[](TestContext& context)
__anond6e629771902() 584 				{
585 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, context.texIds[1], 0);
586 				},
587 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
588 			},
589 			{
590 				[](TestContext& context)
__anond6e629771a02() 591 				{
592 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, context.texIds[0], 0);
593 				},
594 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
595 			},
596 			{
597 				[](TestContext& context)
__anond6e629771b02() 598 				{
599 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, context.texIds[2], 0);
600 				},
601 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
602 			}
603 		},
604 		[](vector<TestStep>& steps, TestContext& testContext)									// StepsGeneratorFn			stepsGenerator
__anond6e629771c02() 605 		{
606 			GLint	maxColorAttachmentsCount;
607 			testContext.gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachmentsCount);
608 			GLU_EXPECT_NO_ERROR(testContext.gl.getError(), "glGetInteger() failed");
609 
610 			steps.reserve(steps.size() + 2 * maxColorAttachmentsCount);
611 			for (GLint i = 0; i < maxColorAttachmentsCount; ++i)
612 			{
613 				steps.push_back(
614 					{
615 						[i](TestContext& context)
616 						{
617 							context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D,
618 														 context.texIds[1], 0);
619 						},
620 						expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
621 					});
622 				steps.push_back(
623 					{
624 						[i](TestContext& context)
625 						{
626 							context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D,
627 														 context.texIds[0], 0);
628 						},
629 						expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
630 					});
631 			}
632 		},
633 	},
634 	{
635 		"all_rbos_expect_same_numsamples",														// string					name
636 		"Same value of FRAMEBUFFER_SAMPLES for all attached render buffers",					// string					description
637 		apiES30,																				// glu::ApiType				apiType
638 		1,																						// size_t					numFboIds
639 		0,																						// size_t					numTexIds
640 		2,																						// size_t					numRboIds
641 		{},																						// vector<TestStep>			initialSteps
642 		[](vector<TestStep>& steps, TestContext& testContext)									// StepsGeneratorFn			stepsGenerator
__anond6e629771f02() 643 		{
644 			GLint	maxSamples;
645 			if (!isDifferentRboSampleCountsSupported(testContext, maxSamples))
646 				return;
647 
648 			steps.push_back(
649 				{
650 					[](TestContext& context)
651 					{
652 						context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
653 					},
654 					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
655 				});
656 			steps.push_back(
657 				{
658 					[](TestContext& context)
659 					{
660 						context.renderbufferStorage(context.rboIds[0], GL_RENDERBUFFER, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT);
661 						context.renderbufferStorage(context.rboIds[1], GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, TEXTURE_WIDTH,
662 													TEXTURE_HEIGHT);
663 
664 						context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
665 														context.rboIds[0]);
666 						context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
667 														context.rboIds[1]);
668 					},
669 					expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
670 				});
671 			steps.push_back(
672 				{
673 					[maxSamples](TestContext& context)
674 					{
675 						context.renderbufferStorageMultisample(context.rboIds[0], GL_RENDERBUFFER, maxSamples, GL_RGBA8, TEXTURE_WIDTH,
676 															   TEXTURE_HEIGHT);
677 						context.renderbufferStorageMultisample(context.rboIds[1], GL_RENDERBUFFER, 1, GL_DEPTH24_STENCIL8,
678 															   TEXTURE_WIDTH, TEXTURE_HEIGHT);
679 					},
680 					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
681 				});
682 		},
683 	},
684 	{
685 		"rbo_and_texture_expect_zero_numsamples",												// string					name
686 		"When using mixed renderbuffer and texture attachments, the value of"					// string					description
687 		" FRAMEBUFFER_SAMPLES needs to be zero for all attached renderbuffers",
688 		apiES30,																				// glu::ApiType				apiType
689 		1,																						// size_t					numFboIds
690 		2,																						// size_t					numTexIds
691 		2,																						// size_t	u				numRboIds
692 		{																						// vector<TestStep>			initialSteps
693 			{
694 				[](TestContext& context)
__anond6e629772302() 695 				{
696 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
697 				},
698 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
699 			},
700 			{
701 				[](TestContext& context)
__anond6e629772402() 702 				{
703 					context.renderbufferStorage(context.rboIds[0], GL_RENDERBUFFER, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT);
704 					context.texImage2D(context.texIds[1], GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, TEXTURE_WIDTH,
705 									   TEXTURE_HEIGHT, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, DE_NULL);
706 
707 					context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
708 													context.rboIds[0]);
709 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
710 												 context.texIds[1], 0);
711 				},
712 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
713 			},
714 			{
715 				[](TestContext& context)
__anond6e629772502() 716 				{
717 					context.renderbufferStorage(context.rboIds[1], GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, TEXTURE_WIDTH,
718 												TEXTURE_HEIGHT);
719 					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
720 									   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
721 
722 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 0);
723 					context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
724 													context.rboIds[1]);
725 				},
726 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
727 			},
728 			{
729 				[](TestContext& context)
__anond6e629772602() 730 				{
731 					context.renderbufferStorageMultisample(context.rboIds[1], GL_RENDERBUFFER, 2, GL_DEPTH24_STENCIL8,
732 														   TEXTURE_WIDTH, TEXTURE_HEIGHT);
733 				},
734 				expectedStatusWithExtension("GL_NV_framebuffer_mixed_samples", GL_FRAMEBUFFER_COMPLETE, GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
735 			},
736 			{
737 				[](TestContext& context)
__anond6e629772702() 738 				{
739 					context.renderbufferStorageMultisample(context.rboIds[0], GL_RENDERBUFFER, 3, GL_RGBA8, TEXTURE_WIDTH,
740 														   TEXTURE_HEIGHT);
741 
742 					context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
743 													context.rboIds[0]);
744 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
745 												 context.texIds[1], 0);
746 				},
747 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
748 			},
749 			{
750 				[](TestContext& context)
__anond6e629772802() 751 				{
752 					context.renderbufferStorageMultisample(context.rboIds[0], GL_RENDERBUFFER, 0, GL_RGBA8, TEXTURE_WIDTH,
753 														   TEXTURE_HEIGHT);
754 				},
755 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
756 			}
757 		},
758 		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
759 	},
760 	{
761 		"expect_equal_numsamples",																// string					name
762 		"The value of samples for each attached target must be equal",							// string					description
763 		apiES31,																				// glu::ApiType				apiType
764 		1,																						// size_t					numFboIds
765 		4,																						// size_t					numTexIds
766 		2,																						// size_t					numRboIds
767 		{},																						// vector<TestStep>			initialSteps
768 		[](vector<TestStep>& steps, TestContext& testContext)									// StepsGeneratorFn			stepsGenerator
__anond6e629772902() 769 		{
770 			GLint	maxRboSamples, maxTextureSamples;
771 			if (!isDifferentRboSampleCountsSupported(testContext, maxRboSamples) || !isDifferentTextureSampleCountsSupported(testContext, maxTextureSamples))
772 				return;
773 
774 			steps.push_back(
775 				{
776 					[maxRboSamples, maxTextureSamples](TestContext& context)
777 					{
778 						// Set up textures and renderbuffers for all following steps, complete = (tex0, rbo1) or (tex1, rbo0) */
779 						context.renderbufferStorageMultisample(context.rboIds[0], GL_RENDERBUFFER, maxRboSamples, GL_RGBA8,
780 															   TEXTURE_WIDTH, TEXTURE_HEIGHT);
781 						context.renderbufferStorageMultisample(context.rboIds[1], GL_RENDERBUFFER, 1, GL_DEPTH24_STENCIL8,
782 															   TEXTURE_WIDTH, TEXTURE_HEIGHT);
783 
784 						const auto&	gl	= context.gl;
785 						context.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, context.texIds[0]);
786 						gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_TRUE);
787 						GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() failed");
788 
789 						context.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, context.texIds[1]);
790 						gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_DEPTH24_STENCIL8, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_TRUE);
791 						GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() failed");
792 
793 						context.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, context.texIds[2]);
794 						gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, maxTextureSamples, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_TRUE);
795 						GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() failed");
796 
797 						context.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, context.texIds[3]);
798 						gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, maxTextureSamples, GL_DEPTH24_STENCIL8, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_TRUE);
799 						GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() failed");
800 
801 						context.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
802 
803 						// Framebuffer binding for rest of this test
804 						context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
805 					},
806 					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
807 				});
808 			steps.push_back(
809 				{
810 					[](TestContext& context)
811 					{
812 						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
813 													 context.texIds[0], 0);
814 						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE,
815 													 context.texIds[1], 0);
816 					},
817 					expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
818 				});
819 			steps.push_back(
820 				{
821 					[](TestContext& context)
822 					{
823 						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE,
824 													 context.texIds[3], 0);
825 					},
826 					expectedStatusWithExtension("GL_NV_framebuffer_mixed_samples", GL_FRAMEBUFFER_COMPLETE, GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
827 				});
828 			steps.push_back(
829 				{
830 					[](TestContext& context)
831 					{
832 						context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
833 														context.rboIds[1]);
834 					},
835 					expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
836 				});
837 			steps.push_back(
838 				{
839 					[](TestContext& context)
840 					{
841 						context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
842 														context.rboIds[0]);
843 					},
844 					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
845 				});
846 			steps.push_back(
847 				{
848 					[](TestContext& context)
849 					{
850 						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
851 													 context.texIds[2], 0);
852 						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE,
853 													 context.texIds[3], 0);
854 					},
855 					expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
856 				});
857 			steps.push_back(
858 				{
859 					[](TestContext& context)
860 					{
861 						const auto&	gl	= context.gl;
862 						gl.deleteTextures(1, &context.texIds[0]);
863 						GLU_EXPECT_NO_ERROR(context.gl.getError(), "glDeleteTextures() failed");
864 						gl.genTextures(1, &context.texIds[0]);
865 						GLU_EXPECT_NO_ERROR(context.gl.getError(), "glGenTextures() failed");
866 						context.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, context.texIds[0]);
867 						gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_FALSE);
868 						GLU_EXPECT_NO_ERROR(context.gl.getError(), "glTexStorage2DMultisample() failed");
869 						context.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
870 						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
871 													 context.texIds[0], 0);
872 						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE,
873 													 context.texIds[1], 0);
874 					},
875 					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
876 				});
877 		},																						// StepsGeneratorFn			stepsGenerator
878 	},
879 	{
880 		"status_tracking",																		// string					name
881 		"Modifying framebuffer attached objects correctly updates the fbo status",				// string					description
882 		apiES30,																				// glu::ApiType				apiType
883 		3,																						// size_t					numFboIds
884 		2,																						// size_t					numTexIds
885 		1,																						// size_t					numRboIds
886 		{																						// vector<TestStep>			initialSteps
887 			{
888 				// Initial status -> missing_attachment
889 				[](TestContext& context)
__anond6e629773102() 890 				{
891 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
892 				},
893 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
894 			},
895 			{
896 				// Allocate and attach texture -> complete
897 				[](TestContext& context)
__anond6e629773202() 898 				{
899 					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
900 									   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
901 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 0);
902 				},
903 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
904 			},
905 			{
906 				// Detach texture from fbo -> missing_attachment
907 				[](TestContext& context)
__anond6e629773302() 908 				{
909 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
910 				},
911 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
912 			},
913 			{
914 				// Allocate and attach renderbuffer -> complete
915 				[](TestContext& context)
__anond6e629773402() 916 				{
917 					context.renderbufferStorage(context.rboIds[0], GL_RENDERBUFFER, GL_RGBA8, TEXTURE_WIDTH,
918 												TEXTURE_HEIGHT);
919 					context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
920 													context.rboIds[0]);
921 				},
922 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
923 			},
924 			{
925 				// Detach renderbuffer -> incomplete
926 				[](TestContext& context)
__anond6e629773502() 927 				{
928 					context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0);
929 				},
930 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
931 			},
932 			{
933 				// Switch to incomplete fb -> missing_attachment
934 				[](TestContext& context)
__anond6e629773602() 935 				{
936 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[1]);
937 				},
938 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
939 			},
940 			{
941 				// Attach texture to fbo -> complete
942 				[](TestContext& context)
__anond6e629773702() 943 				{
944 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 0);
945 				},
946 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
947 			},
948 			{
949 				// Change image format of attached texture -> incomplete_attachment
950 				[](TestContext& context)
__anond6e629773802() 951 				{
952 					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, TEXTURE_WIDTH,
953 									   TEXTURE_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, DE_NULL);
954 				},
955 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
956 			},
957 			{
958 				// Change image format (tex storage) -> complete
959 				[](TestContext& context)
__anond6e629773902() 960 				{
961 					context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
962 					context.gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT);
963 					GLU_EXPECT_NO_ERROR(context.gl.getError(), "glTexStorage2D() failed");
964 					context.bindTexture(GL_TEXTURE_2D, 0);
965 				},
966 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
967 			},
968 			{
969 				// Delete image -> missing_attachment
970 				[](TestContext& context)
__anond6e629773a02() 971 				{
972 					context.gl.deleteTextures(1, &context.texIds[0]);
973 					GLU_EXPECT_NO_ERROR(context.gl.getError(), "glDeleteTextures() failed");
974 					context.texIds.erase(context.texIds.begin());
975 				},
976 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
977 			},
978 			{
979 				// Recreate image in wrong format, attach to color attachment -> incomplete_attachment
980 				[](TestContext& context)
__anond6e629773b02() 981 				{
982 					const auto&	gl		= context.gl;
983 					GLuint		texId;
984 					gl.genTextures(1, &texId);
985 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
986 					context.texIds.push_back(texId);
987 
988 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
989 					context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, TEXTURE_WIDTH,
990 									   TEXTURE_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, DE_NULL);
991 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 0);
992 				},
993 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
994 			},
995 			{
996 				// Format to rgba8 using copyTexImage2D from compatible fbo -> framebuffer_complete
997 				[](TestContext& context)
__anond6e629773c02() 998 				{
999 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[2]);
1000 					context.texImage2D(context.texIds[1], GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1001 					context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[1], 0);
1002 
1003 					context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
1004 					const auto&	gl	= context.gl;
1005 					gl.copyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0);
1006 					GLU_EXPECT_NO_ERROR(gl.getError(), "glCopyTexImage2D() failed");
1007 
1008 					context.bindTexture(GL_TEXTURE_2D, 0);
1009 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
1010 				},
1011 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
1012 			},
1013 			{
1014 				// Change currently attached texture's format to compressed tex image -> incomplete_attachment (non color renderable)
1015 				[](TestContext& context)
__anond6e629773d02() 1016 				{
1017 					DE_ASSERT(TEXTURE_WIDTH == 16 && TEXTURE_HEIGHT == 16);
1018 					static const glw::GLubyte textureDataETC2[] = // 16x16 all black RGBA8 texture in ETC2 format
1019 					{
1020 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1021 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1022 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1023 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1024 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1025 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1026 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1027 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1028 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1029 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1030 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1031 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1032 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1033 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1034 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00,
1035 						0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x00
1036 					};
1037 					const auto&	gl	= context.gl;
1038 					context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
1039 
1040 					gl.compressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA8_ETC2_EAC, TEXTURE_WIDTH, TEXTURE_HEIGHT,
1041 											0, DE_LENGTH_OF_ARRAY(textureDataETC2), textureDataETC2);
1042 					GLU_EXPECT_NO_ERROR(gl.getError(), "glCompressedTexImage2D() failed");
1043 
1044 					context.bindTexture(GL_TEXTURE_2D, 0);
1045 				},
1046 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
1047 			},
1048 			{
1049 				// Re-attach rbo0 -> complete
1050 				[](TestContext& context)
__anond6e629773e02() 1051 				{
1052 					context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
1053 													context.rboIds[0]);
1054 				},
1055 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE)
1056 			},
1057 			{
1058 				// Rbo storage to non renderable format -> incomplete_attachment
1059 				[](TestContext& context)
__anond6e629773f02() 1060 				{
1061 					context.renderbufferStorage(context.rboIds[0], GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, TEXTURE_WIDTH,
1062 												TEXTURE_HEIGHT);
1063 				},
1064 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT)
1065 			},
1066 			{
1067 				// Delete rbo -> missing_attachment
1068 				[](TestContext& context)
__anond6e629774002() 1069 				{
1070 					context.gl.deleteRenderbuffers(1, &context.rboIds[0]);
1071 					GLU_EXPECT_NO_ERROR(context.gl.getError(), "glDeleteRenderbuffers() failed");
1072 					context.rboIds.erase(context.rboIds.begin());
1073 				},
1074 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
1075 			}
1076 		},
1077 		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
1078 	},
1079 	{
1080 		"mutable_texture_missing_attachment_level",												// string					name
1081 		"Attaching a mutable texture with undefined image for attachment level"
1082 		" should be invalid",																	// string					description
1083 		apiES30,																				// glu::ApiType				apiType
1084 		1,																						// size_t					numFboIds
1085 		1,																						// size_t					numTexIds
1086 		0,																						// size_t					numRboIds
1087 		{},																						// vector<TestStep>			initialSteps
1088 		[](vector<TestStep>& steps, TestContext&)												// StepsGeneratorFn			stepsGenerator
__anond6e629774102() 1089 		{
1090 			DE_ASSERT(TEXTURE_WIDTH >= 16 && TEXTURE_HEIGHT >= 16);
1091 			steps.push_back(
1092 				{
1093 					[](TestContext& context)
1094 					{
1095 						context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
1096 					},
1097 					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
1098 				});
1099 			steps.push_back(
1100 				{
1101 					[](TestContext& context)
1102 					{
1103 
1104 						context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1105 						context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
1106 										   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
1107 						context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 1, GL_RGBA8, TEXTURE_WIDTH >> 1, TEXTURE_HEIGHT >> 1, 0,
1108 										   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
1109 						context.texImage2D(context.texIds[0], GL_TEXTURE_2D, 3, GL_RGBA8, TEXTURE_WIDTH >> 3, TEXTURE_HEIGHT >> 3, 0,
1110 										   GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
1111 
1112 						context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1113 
1114 						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 2);
1115 					},
1116 					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
1117 				});
1118 		}
1119 	},
1120 	{
1121 		"immutable_texture_any_level_as_attachment",											// string					name
1122 		"Any level of immutable texture as attachment should be valid",							// string					description
1123 		apiES30,																				// glu::ApiType				apiType
1124 		1,																						// size_t					numFboIds
1125 		1,																						// size_t					numTexIds
1126 		0,																						// size_t					numRboIds
1127 		{},																						// vector<TestStep>			initialSteps
1128 		[](vector<TestStep>& steps, TestContext&)												// StepsGeneratorFn			stepsGenerator
__anond6e629774402() 1129 		{
1130 			DE_ASSERT(TEXTURE_WIDTH >= 8 && TEXTURE_HEIGHT >= 8);
1131 			steps.push_back(
1132 				{
1133 					[](TestContext& context)
1134 					{
1135 						context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
1136 					},
1137 					expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT)
1138 				});
1139 			steps.push_back(
1140 				{
1141 					[](TestContext& context)
1142 					{
1143 						context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1144 						context.bindTexture(GL_TEXTURE_2D, context.texIds[0]);
1145 						const auto&	gl	= context.gl;
1146 						gl.texStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT);
1147 						GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() failed");
1148 						context.bindTexture(GL_TEXTURE_2D, 0);
1149 
1150 						context.texParameteri(context.texIds[0], GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1151 
1152 						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 2);
1153 					},
1154 					expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE),
1155 				});
1156 			steps.push_back(
1157 				{
1158 					[](TestContext& context)
1159 					{
1160 						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 1);
1161 					},
1162 					expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE),
1163 				});
1164 			steps.push_back(
1165 				{
1166 					[](TestContext& context)
1167 					{
1168 						context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, context.texIds[0], 0);
1169 					},
1170 					expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE),
1171 				});
1172 		}
1173 	},
1174 	{
1175 		"cube_map_layered_attachment_valid_size_and_format",									// string					name
1176 		"Cube map attachment with images of same size, same format and square should be valid",	// string					description
1177 		apiES32,																				// glu::ApiType				apiType
1178 		1,																						// size_t					numFboIds
1179 		1,																						// size_t					numTexIds
1180 		0,																						// size_t					numRboIds
1181 		{																						// vector<TestStep>			initialSteps
1182 			{
1183 				[](TestContext& context)
__anond6e629774902() 1184 				{
1185 					context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
1186 					for(const auto target : cubemapTextureTargets)
1187 						context.texImage2D(target, 0, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1188 					context.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
1189 
1190 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
1191 					context.gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, context.texIds[0], 0);
1192 					GLU_EXPECT_NO_ERROR(context.gl.getError(), "glFramebufferTexture() failed");
1193 				},
1194 				expectedStatusConstant(GL_FRAMEBUFFER_COMPLETE),
1195 			}
1196 		},
1197 		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
1198 	},
1199 	{
1200 		"cube_map_layered_attachment_different_formats",										// string					name
1201 		"Cube map attachment with images of the same size, square but different formats"
1202 		" should be incomplete",																// string					description
1203 		apiES32,																				// glu::ApiType				apiType
1204 		1,																						// size_t					numFboIds
1205 		1,																						// size_t					numTexIds
1206 		0,																						// size_t					numRboIds
1207 		{																						// vector<TestStep>			initialSteps
1208 			{
1209 				[](TestContext& context)
__anond6e629774a02() 1210 				{
1211 					context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
1212 					for(size_t i = 0; i < DE_LENGTH_OF_ARRAY(cubemapTextureTargets); ++i)
1213 						context.texImage2D(cubemapTextureTargets[i], 0, (i % 2) ? GL_RGBA8 : GL_RGB8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, (i % 2) ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, 0);
1214 					context.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
1215 
1216 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
1217 					context.gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, context.texIds[0], 0);
1218 					GLU_EXPECT_NO_ERROR(context.gl.getError(), "glFramebufferTexture() failed");
1219 				},
1220 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
1221 			},
1222 			{
1223 				[](TestContext& context)
__anond6e629774b02() 1224 				{
1225 					context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
1226 					for(size_t i = 0; i < DE_LENGTH_OF_ARRAY(cubemapTextureTargets); ++i)
1227 						context.texImage2D(cubemapTextureTargets[i], 0, (i % 2) ? GL_RGBA8 : GL_SRGB8_ALPHA8, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1228 					context.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
1229 
1230 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
1231 					context.gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, context.texIds[0], 0);
1232 					GLU_EXPECT_NO_ERROR(context.gl.getError(), "glFramebufferTexture() failed");
1233 				},
1234 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
1235 			}
1236 		},
1237 		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
1238 	},
1239 	{
1240 		"cube_map_layered_attachment_different_sizes",											// string					name
1241 		"Cube map with images of different sizes, same format and all square should"
1242 		" be incomplete",																		// string					description
1243 		apiES32,																				// glu::ApiType				apiType
1244 		1,																						// size_t					numFboIds
1245 		1,																						// size_t					numTexIds
1246 		0,																						// size_t					numRboIds
1247 		{																						// vector<TestStep>			initialSteps
1248 			{
1249 				[](TestContext& context)
__anond6e629774c02() 1250 				{
1251 					context.bindTexture(GL_TEXTURE_CUBE_MAP, context.texIds[0]);
1252 					for(size_t i = 0; i < DE_LENGTH_OF_ARRAY(cubemapTextureTargets); ++i)
1253 						context.texImage2D(cubemapTextureTargets[i], 0, GL_RGBA8, (i % 2) ? TEXTURE_WIDTH : TEXTURE_WIDTH / 2, (i % 2) ? TEXTURE_HEIGHT : TEXTURE_HEIGHT / 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1254 					context.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
1255 
1256 					context.bindFramebuffer(GL_FRAMEBUFFER, context.fboIds[0]);
1257 					context.gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, context.texIds[0], 0);
1258 					GLU_EXPECT_NO_ERROR(context.gl.getError(), "glFramebufferTexture() failed");
1259 				},
1260 				expectedStatusConstant(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
1261 			},
1262 		},
1263 		DE_NULL,																				// StepsGeneratorFn			stepsGenerator
1264 	}
1265 };
1266 
1267 class FramebufferCompletenessTestCase : public deqp::TestCase
1268 {
1269 public:
1270 	FramebufferCompletenessTestCase				(deqp::Context& context, const TestParams& params);
1271 	virtual ~FramebufferCompletenessTestCase	();
1272 
1273 	virtual void			init				(void);
1274 	virtual void			deinit				(void);
1275 	TestNode::IterateResult iterate				(void);
1276 
1277 private:
1278 	bool verifyFramebufferStatus				(const glw::Functions& gl, const ExpectedStatusFn expectedStatusFn, const size_t stepIndex);
1279 
1280 	const TestParams		m_params;
1281 	vector<GLuint>			m_fboIds;
1282 	vector<GLuint>			m_texIds;
1283 	vector<GLuint>			m_rboIds;
1284 };
1285 
FramebufferCompletenessTestCase(deqp::Context & context,const TestParams & params)1286 FramebufferCompletenessTestCase::FramebufferCompletenessTestCase(deqp::Context& context, const TestParams& params)
1287 	: deqp::TestCase(context, params.name.c_str(), params.description.c_str()), m_params(params)
1288 {
1289 }
1290 
~FramebufferCompletenessTestCase()1291 FramebufferCompletenessTestCase::~FramebufferCompletenessTestCase()
1292 {
1293 }
1294 
init(void)1295 void FramebufferCompletenessTestCase::init(void)
1296 {
1297 	const auto& renderContext	= m_context.getRenderContext();
1298 	const auto& gl				= renderContext.getFunctions();
1299 
1300 	if (m_params.numFboIds > 0)
1301 	{
1302 		m_fboIds.resize(m_params.numFboIds);
1303 		gl.genFramebuffers(m_params.numFboIds, m_fboIds.data());
1304 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() failed");
1305 	}
1306 	if (m_params.numTexIds > 0)
1307 	{
1308 		m_texIds.resize(m_params.numTexIds);
1309 		gl.genTextures(m_params.numTexIds, m_texIds.data());
1310 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
1311 	}
1312 	if (m_params.numRboIds > 0)
1313 	{
1314 		m_rboIds.resize(m_params.numRboIds);
1315 		gl.genRenderbuffers(m_params.numRboIds, m_rboIds.data());
1316 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers() failed");
1317 	}
1318 }
1319 
deinit(void)1320 void FramebufferCompletenessTestCase::deinit(void)
1321 {
1322 	const auto& renderContext	= m_context.getRenderContext();
1323 	const auto& gl				= renderContext.getFunctions();
1324 
1325 	if (!m_rboIds.empty())
1326 	{
1327 		gl.deleteRenderbuffers(m_params.numRboIds, m_rboIds.data());
1328 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteRenderbuffers() failed");
1329 		m_rboIds.clear();
1330 	}
1331 	if (!m_texIds.empty())
1332 	{
1333 		gl.deleteTextures(m_params.numTexIds, m_texIds.data());
1334 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() failed");
1335 		m_texIds.clear();
1336 	}
1337 	if (!m_fboIds.empty())
1338 	{
1339 		gl.deleteFramebuffers(m_params.numFboIds, m_fboIds.data());
1340 		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebufers() failed");
1341 		m_fboIds.clear();
1342 	}
1343 }
1344 
iterate(void)1345 tcu::TestNode::IterateResult FramebufferCompletenessTestCase::iterate(void)
1346 {
1347 	const auto& renderContext	= m_context.getRenderContext();
1348 	const auto& gl				= renderContext.getFunctions();
1349 	TestContext context			=
1350 	{
1351 		renderContext,	// const glu::RenderContext&	renderContext
1352 		gl,				// const glw::Functions&		gl
1353 		m_fboIds,		// vector<GLuint>&				fboIds
1354 		m_texIds,		// vector<GLuint>&				texIds
1355 		m_rboIds		// vector<GLuint>&				rboIds
1356 	};
1357 	auto steps = vector<TestStep>(m_params.initialSteps);
1358 	if (m_params.stepsGenerator != DE_NULL)
1359 		m_params.stepsGenerator(steps, context);
1360 
1361 	if (steps.empty())
1362 	{
1363 		m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1364 		return STOP;
1365 	}
1366 
1367 	size_t stepIndex = 0;
1368 	for (const auto& step : steps)
1369 	{
1370 		step.testFn(context);
1371 
1372 		if (!verifyFramebufferStatus(gl, step.expectedFbStatus, stepIndex++))
1373 			return STOP;
1374 	}
1375 	return STOP;
1376 }
1377 
verifyFramebufferStatus(const glw::Functions & gl,const ExpectedStatusFn expectedStatusFn,const size_t stepIndex)1378 bool FramebufferCompletenessTestCase::verifyFramebufferStatus(const glw::Functions& gl, const ExpectedStatusFn expectedStatusFn,
1379 												  const size_t stepIndex)
1380 {
1381 	static const map<GLenum, string>	statusNames	=
1382 	{
1383 		{ GL_FRAMEBUFFER_COMPLETE						, "GL_FRAMEBUFFER_COMPLETE" },
1384 		{ GL_FRAMEBUFFER_UNDEFINED						, "GL_FRAMEBUFFER_UNDEFINED" },
1385 		{ GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT			, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT" },
1386 		{ GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT	, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" },
1387 		{ GL_FRAMEBUFFER_UNSUPPORTED					, "GL_FRAMEBUFFER_UNSUPPORTED" },
1388 		{ GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE			, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" },
1389 		{ GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS			, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS" }
1390 	};
1391 	const auto expectedStatus	= expectedStatusFn(m_context.getContextInfo());
1392 	const auto fboStatus		= gl.checkFramebufferStatus(GL_FRAMEBUFFER);
1393 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCheckFramebufferStatus() failed");
1394 	if (fboStatus != expectedStatus)
1395 	{
1396 		ostringstream					msg;
1397 		const auto&						fboStatusName		= statusNames.find(fboStatus);
1398 		const auto&						expectedStatusName	= statusNames.find(expectedStatus);
1399 		msg << "Frame buffer status ("
1400 			<< ((fboStatusName != statusNames.end()) ? fboStatusName->second : std::to_string(fboStatus))
1401 			<< ") does not match the expected status ("
1402 			<< ((expectedStatusName != statusNames.end()) ? expectedStatusName->second : std::to_string(expectedStatus))
1403 			<< ") after step " << stepIndex;
1404 		TCU_FAIL(msg.str().c_str());
1405 		return false;
1406 	}
1407 	m_context.getTestContext().setTestResult(QP_TEST_RESULT_PASS, "Pass");
1408 	return true;
1409 }
1410 
1411 } // namespace
1412 
FramebufferCompletenessTests(deqp::Context & context)1413 FramebufferCompletenessTests::FramebufferCompletenessTests(deqp::Context& context)
1414 	: deqp::TestCaseGroup(context, "framebuffer_completeness", "Tests for frame buffer completeness")
1415 {
1416 }
1417 
init(void)1418 void FramebufferCompletenessTests::init(void)
1419 {
1420 	const auto& renderContext	= m_context.getRenderContext();
1421 	for (const auto& test : tests)
1422 	{
1423 		if (!glu::contextSupports(renderContext.getType(), test.apiType))
1424 			continue;
1425 
1426 		addChild(new FramebufferCompletenessTestCase(m_context, test));
1427 	}
1428 }
1429 
1430 } // namespace es3cts
1431