1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES Utilities
3 * ------------------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief OpenGL State Reset.
22 *//*--------------------------------------------------------------------*/
23
24#include "gluStateReset.hpp"
25#include "gluContextInfo.hpp"
26#include "gluRenderContext.hpp"
27#include "tcuRenderTarget.hpp"
28#include "glwFunctions.hpp"
29#include "glwEnums.hpp"
30#include "deUniquePtr.hpp"
31
32namespace glu
33{
34
35void resetStateES (const RenderContext& renderCtx)
36{
37	const glw::Functions&					gl		= renderCtx.getFunctions();
38	const ContextType						type	= renderCtx.getType();
39	const de::UniquePtr<glu::ContextInfo>	ctxInfo	(glu::ContextInfo::create(renderCtx));
40
41	DE_ASSERT(isContextTypeES(type));
42
43	// Reset error state.
44	gl.getError();
45	GLU_EXPECT_NO_ERROR(gl.getError(), "Error state");
46
47	// Vertex attrib array state.
48	{
49		int numVertexAttribArrays = 0;
50		gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribArrays);
51
52		gl.bindBuffer	(GL_ARRAY_BUFFER,			0);
53		gl.bindBuffer	(GL_ELEMENT_ARRAY_BUFFER,	0);
54
55		if (contextSupports(type, ApiType::es(3,0)))
56		{
57			gl.bindVertexArray	(0);
58			gl.disable			(GL_PRIMITIVE_RESTART_FIXED_INDEX);
59		}
60
61		if (contextSupports(type, ApiType::es(3,1)))
62			gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
63
64		for (int ndx = 0; ndx < numVertexAttribArrays; ndx++)
65		{
66			gl.disableVertexAttribArray	(ndx);
67			gl.vertexAttribPointer		(ndx, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
68
69			if (contextSupports(type, ApiType::es(3,0)))
70				gl.vertexAttribDivisor(ndx, 0);
71		}
72
73		GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex attrib array state reset failed");
74	}
75
76	// Transformation state.
77	{
78		const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget();
79
80		gl.viewport		(0, 0, renderTarget.getWidth(), renderTarget.getHeight());
81		gl.depthRangef	(0.0f, 1.0f);
82
83		if (contextSupports(type, ApiType::es(3,0)))
84			gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
85
86		GLU_EXPECT_NO_ERROR(gl.getError(), "Transformation state reset failed");
87	}
88
89	// Rasterization state
90	{
91		gl.lineWidth	(1.0f);
92		gl.disable		(GL_CULL_FACE);
93		gl.cullFace		(GL_BACK);
94		gl.frontFace	(GL_CCW);
95		gl.polygonOffset(0.0f, 0.0f);
96		gl.disable		(GL_POLYGON_OFFSET_FILL);
97
98		if (contextSupports(type, ApiType::es(3,0)))
99			gl.disable(GL_RASTERIZER_DISCARD);
100
101		GLU_EXPECT_NO_ERROR(gl.getError(), "Rasterization state reset failed");
102	}
103
104	// Multisampling state
105	{
106		gl.disable			(GL_SAMPLE_ALPHA_TO_COVERAGE);
107		gl.disable			(GL_SAMPLE_COVERAGE);
108		gl.sampleCoverage	(1.0f, GL_FALSE);
109
110		if (contextSupports(type, ApiType::es(3,1)))
111		{
112			int numSampleMaskWords = 0;
113			gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &numSampleMaskWords);
114
115			gl.disable(GL_SAMPLE_MASK);
116
117			for (int ndx = 0; ndx < numSampleMaskWords; ndx++)
118				gl.sampleMaski(ndx, ~0u);
119		}
120
121		GLU_EXPECT_NO_ERROR(gl.getError(), "Multisampling state reset failed");
122	}
123
124	// Texture state.
125	// \todo [2013-04-08 pyry] Reset all levels?
126	{
127		const float	borderColor[]	= { 0.0f, 0.0f, 0.0f, 0.0f };
128		int			numTexUnits		= 0;
129		gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numTexUnits);
130
131		for (int ndx = 0; ndx < numTexUnits; ndx++)
132		{
133			gl.activeTexture(GL_TEXTURE0 + ndx);
134
135			// Reset 2D texture.
136			gl.bindTexture(GL_TEXTURE_2D, 0);
137			gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
138			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,		GL_NEAREST_MIPMAP_LINEAR);
139			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
140			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
141			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,			GL_REPEAT);
142
143			if (contextSupports(type, ApiType::es(3,0)))
144			{
145				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
146				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
147				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
148				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
149				gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD,			-1000.0f);
150				gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD,			1000.0f);
151				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL,		0);
152				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL,		1000);
153				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
154				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
155			}
156
157			if (contextSupports(type, ApiType::es(3,1)))
158				gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
159
160			if (ctxInfo->isExtensionSupported("GL_EXT_texture_border_clamp"))
161				gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &borderColor[0]);
162
163			// Reset cube map texture.
164			gl.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
165			gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
166			gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
167			gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
168			gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
169			gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
170			gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
171			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_LINEAR);
172			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
173			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
174			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);
175
176			if (contextSupports(type, ApiType::es(3,0)))
177			{
178				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_R,		GL_RED);
179				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
180				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
181				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
182				gl.texParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_LOD,		-1000.0f);
183				gl.texParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LOD,		1000.0f);
184				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL,	0);
185				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL,		1000);
186				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
187				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
188			}
189
190			if (contextSupports(type, ApiType::es(3,1)))
191				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
192
193			if (ctxInfo->isExtensionSupported("GL_EXT_texture_border_clamp"))
194				gl.texParameterfv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR, &borderColor[0]);
195
196			if (contextSupports(type, ApiType::es(3,0)))
197			{
198				// Reset 2D array texture.
199				gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
200				gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
201				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_LINEAR);
202				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
203				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S,		GL_REPEAT);
204				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T,		GL_REPEAT);
205				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_R,		GL_RED);
206				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
207				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
208				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
209				gl.texParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_LOD,		-1000.0f);
210				gl.texParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LOD,		1000.0f);
211				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL,	0);
212				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL,		1000);
213				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
214				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
215
216				if (ctxInfo->isExtensionSupported("GL_EXT_texture_border_clamp"))
217					gl.texParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, &borderColor[0]);
218			}
219
220			if (contextSupports(type, ApiType::es(3,1)))
221				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
222
223			if (contextSupports(type, ApiType::es(3,0)))
224			{
225				// Reset 3D texture.
226				gl.bindTexture(GL_TEXTURE_3D, 0);
227				gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
228				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,		GL_NEAREST_MIPMAP_LINEAR);
229				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
230				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
231				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,			GL_REPEAT);
232				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,			GL_REPEAT);
233				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
234				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
235				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
236				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
237				gl.texParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_LOD,			-1000.0f);
238				gl.texParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAX_LOD,			1000.0f);
239				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL,		0);
240				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL,		1000);
241				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
242				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
243
244				if (ctxInfo->isExtensionSupported("GL_EXT_texture_border_clamp"))
245					gl.texParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, &borderColor[0]);
246			}
247
248			if (contextSupports(type, ApiType::es(3,1)))
249				gl.texParameteri(GL_TEXTURE_3D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
250
251			if (contextSupports(type, ApiType::es(3,1)))
252			{
253				// Reset multisample textures.
254				gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
255				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_SWIZZLE_R,	GL_RED);
256				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_SWIZZLE_G,	GL_GREEN);
257				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_SWIZZLE_B,	GL_BLUE);
258				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_SWIZZLE_A,	GL_ALPHA);
259				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BASE_LEVEL,	0);
260				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAX_LEVEL,	1000);
261			}
262
263			if (ctxInfo->isExtensionSupported("GL_OES_texture_storage_multisample_2d_array"))
264			{
265				gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);
266				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_SWIZZLE_R,		GL_RED);
267				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
268				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
269				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
270				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BASE_LEVEL,	0);
271				gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_MAX_LEVEL,		1000);
272			}
273
274			if (ctxInfo->isExtensionSupported("GL_EXT_texture_cube_map_array"))
275			{
276				// Reset cube array texture.
277				gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
278				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER,		GL_NEAREST_MIPMAP_LINEAR);
279				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
280				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S,			GL_REPEAT);
281				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T,			GL_REPEAT);
282				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_SWIZZLE_R,		GL_RED);
283				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
284				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
285				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
286				gl.texParameterf(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_LOD,			-1000.0f);
287				gl.texParameterf(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LOD,			1000.0f);
288				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BASE_LEVEL,		0);
289				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL,		1000);
290				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
291				gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
292
293				if (ctxInfo->isExtensionSupported("GL_EXT_texture_border_clamp"))
294					gl.texParameterfv(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BORDER_COLOR, &borderColor[0]);
295			}
296		}
297
298		gl.activeTexture(GL_TEXTURE0);
299
300		if (contextSupports(type, ApiType::es(3,0)))
301		{
302			for (int ndx = 0; ndx < numTexUnits; ndx++)
303				gl.bindSampler(ndx, 0);
304		}
305
306		GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state reset failed");
307	}
308
309	// Resetting state using non-indexed variants should be enough, but some
310	// implementations have bugs so we need to make sure indexed state gets
311	// set back to initial values.
312	if (ctxInfo->isExtensionSupported("GL_EXT_draw_buffers_indexed"))
313	{
314		int numDrawBuffers = 0;
315
316		gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &numDrawBuffers);
317
318		for (int drawBufferNdx = 0; drawBufferNdx < numDrawBuffers; drawBufferNdx++)
319		{
320			gl.disablei			(GL_BLEND, drawBufferNdx);
321			gl.blendFunci		(drawBufferNdx, GL_ONE, GL_ZERO);
322			gl.blendEquationi	(drawBufferNdx, GL_FUNC_ADD);
323			gl.colorMaski		(drawBufferNdx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
324		}
325
326		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to reset indexed draw buffer state");
327	}
328
329	// Pixel operations.
330	{
331		const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget();
332
333		gl.disable		(GL_SCISSOR_TEST);
334		gl.scissor		(0, 0, renderTarget.getWidth(), renderTarget.getHeight());
335
336		gl.disable		(GL_STENCIL_TEST);
337		gl.stencilFunc	(GL_ALWAYS, 0, ~0u);
338		gl.stencilOp	(GL_KEEP, GL_KEEP, GL_KEEP);
339
340		gl.disable		(GL_DEPTH_TEST);
341		gl.depthFunc	(GL_LESS);
342
343		gl.disable		(GL_BLEND);
344		gl.blendFunc	(GL_ONE, GL_ZERO);
345		gl.blendEquation(GL_FUNC_ADD);
346		gl.blendColor	(0.0f, 0.0f, 0.0f, 0.0f);
347
348		gl.enable		(GL_DITHER);
349
350		GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel operation state reset failed");
351	}
352
353	// Framebuffer control.
354	{
355		gl.colorMask		(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
356		gl.depthMask		(GL_TRUE);
357		gl.stencilMask		(~0u);
358
359		gl.clearColor		(0.0f, 0.0f, 0.0f, 0.0f);
360		gl.clearDepthf		(1.0f);
361		gl.clearStencil		(0);
362
363		GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer control state reset failed");
364	}
365
366	// Framebuffer state.
367	{
368		// \note Actually spec explictly says 0 but on some platforms (iOS) no default framebuffer exists.
369		const deUint32		defaultFbo		= renderCtx.getDefaultFramebuffer();
370		const deUint32		drawBuffer		= defaultFbo != 0 ? GL_COLOR_ATTACHMENT0 : GL_BACK;
371		const deUint32		readBuffer		= defaultFbo != 0 ? GL_COLOR_ATTACHMENT0 : GL_BACK;
372
373		gl.bindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
374
375		if (contextSupports(type, ApiType::es(3,0)))
376		{
377			gl.drawBuffers	(1, &drawBuffer);
378			gl.readBuffer	(readBuffer);
379		}
380
381		GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer state reset failed");
382	}
383
384	// Renderbuffer state.
385	{
386		gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
387		GLU_EXPECT_NO_ERROR(gl.getError(), "Renderbuffer state reset failed");
388	}
389
390	// Pixel transfer state.
391	{
392		gl.pixelStorei(GL_UNPACK_ALIGNMENT,		4);
393		gl.pixelStorei(GL_PACK_ALIGNMENT,		4);
394
395		if (contextSupports(type, ApiType::es(3,0)))
396		{
397			gl.pixelStorei(GL_UNPACK_IMAGE_HEIGHT,	0);
398			gl.pixelStorei(GL_UNPACK_SKIP_IMAGES,	0);
399			gl.pixelStorei(GL_UNPACK_ROW_LENGTH,	0);
400			gl.pixelStorei(GL_UNPACK_SKIP_ROWS,		0);
401			gl.pixelStorei(GL_UNPACK_SKIP_PIXELS,	0);
402
403			gl.pixelStorei(GL_PACK_ROW_LENGTH,		0);
404			gl.pixelStorei(GL_PACK_SKIP_ROWS,		0);
405			gl.pixelStorei(GL_PACK_SKIP_PIXELS,		0);
406
407			gl.bindBuffer(GL_PIXEL_PACK_BUFFER,		0);
408			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER,	0);
409		}
410
411		GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel transfer state reset failed");
412	}
413
414	// Program object state.
415	{
416		gl.useProgram(0);
417
418		if (contextSupports(type, ApiType::es(3,0)))
419		{
420			int maxUniformBufferBindings = 0;
421			gl.getIntegerv	(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings);
422			gl.bindBuffer	(GL_UNIFORM_BUFFER,	0);
423
424			for (int ndx = 0; ndx < maxUniformBufferBindings; ndx++)
425				gl.bindBufferBase(GL_UNIFORM_BUFFER, ndx, 0);
426		}
427
428		if (contextSupports(type, ApiType::es(3,1)))
429		{
430			gl.bindProgramPipeline(0);
431
432			{
433				int maxAtomicCounterBufferBindings = 0;
434				gl.getIntegerv	(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &maxAtomicCounterBufferBindings);
435				gl.bindBuffer	(GL_ATOMIC_COUNTER_BUFFER, 0);
436
437				for (int ndx = 0; ndx < maxAtomicCounterBufferBindings; ndx++)
438					gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, ndx, 0);
439			}
440
441			{
442				int maxShaderStorageBufferBindings = 0;
443				gl.getIntegerv	(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxShaderStorageBufferBindings);
444				gl.bindBuffer	(GL_SHADER_STORAGE_BUFFER, 0);
445
446				for (int ndx = 0; ndx < maxShaderStorageBufferBindings; ndx++)
447					gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, ndx, 0);
448			}
449		}
450
451		GLU_EXPECT_NO_ERROR(gl.getError(), "Program object state reset failed");
452	}
453
454	// Vertex shader state.
455	{
456		int numVertexAttribArrays = 0;
457		gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribArrays);
458
459		for (int ndx = 0; ndx < numVertexAttribArrays; ndx++)
460			gl.vertexAttrib4f(ndx, 0.0f, 0.0f, 0.0f, 1.0f);
461
462		GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex shader state reset failed");
463	}
464
465	// Transform feedback state.
466	if (contextSupports(type, ApiType::es(3,0)))
467	{
468		int				numTransformFeedbackSeparateAttribs	= 0;
469		glw::GLboolean	transformFeedbackActive				= 0;
470		gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,	&numTransformFeedbackSeparateAttribs);
471		gl.getBooleanv(GL_TRANSFORM_FEEDBACK_ACTIVE,				&transformFeedbackActive);
472
473		if (transformFeedbackActive)
474			gl.endTransformFeedback();
475
476		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
477
478		for (int ndx = 0; ndx < numTransformFeedbackSeparateAttribs; ndx++)
479			gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, ndx, 0);
480
481		GLU_EXPECT_NO_ERROR(gl.getError(), "Transform feedback state reset failed");
482	}
483
484	// Asynchronous query state.
485	if (contextSupports(type, ApiType::es(3,0)))
486	{
487		static const deUint32 targets[] = { GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN };
488
489		for (int i = 0; i < DE_LENGTH_OF_ARRAY(targets); i++)
490		{
491			int queryActive = 0;
492			gl.getQueryiv(targets[i], GL_CURRENT_QUERY, &queryActive);
493
494			if (queryActive != 0)
495				gl.endQuery(targets[i]);
496		}
497
498		GLU_EXPECT_NO_ERROR(gl.getError(), "Asynchronous query state reset failed");
499	}
500
501	// Hints.
502	{
503		gl.hint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE);
504
505		if (contextSupports(type, ApiType::es(3,0)))
506			gl.hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_DONT_CARE);
507
508		GLU_EXPECT_NO_ERROR(gl.getError(), "Hints reset failed");
509	}
510
511	// Compute.
512	if (contextSupports(type, ApiType::es(3,1)))
513	{
514		gl.bindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0);
515		GLU_EXPECT_NO_ERROR(gl.getError(), "Compute dispatch state reset failed");
516	}
517
518	// Buffer copy state.
519	if (contextSupports(type, ApiType::es(3,0)))
520	{
521		gl.bindBuffer(GL_COPY_READ_BUFFER,	0);
522		gl.bindBuffer(GL_COPY_WRITE_BUFFER,	0);
523
524		GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer copy state reset failed");
525	}
526
527	// Images.
528	if (contextSupports(type, ApiType::es(3,1)))
529	{
530		int numImageUnits = 0;
531		gl.getIntegerv(GL_MAX_IMAGE_UNITS, &numImageUnits);
532
533		for (int ndx = 0; ndx < numImageUnits; ndx++)
534			gl.bindImageTexture(ndx, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI);
535
536		GLU_EXPECT_NO_ERROR(gl.getError(), "Image state reset failed");
537	}
538
539	// Sample shading state.
540	if (contextSupports(type, ApiType::es(3,1)) && ctxInfo->isExtensionSupported("GL_OES_sample_shading"))
541	{
542		gl.minSampleShading(0.0f);
543		gl.disable(GL_SAMPLE_SHADING);
544
545		GLU_EXPECT_NO_ERROR(gl.getError(), "Sample shading state reset failed");
546	}
547
548	// Debug state
549	if (ctxInfo->isExtensionSupported("GL_KHR_debug"))
550	{
551		const bool entrypointsPresent =	gl.debugMessageControl	!= DE_NULL	&&
552										gl.debugMessageCallback	!= DE_NULL	&&
553										gl.popDebugGroup		!= DE_NULL;
554
555		// some drivers advertise GL_KHR_debug but give out null pointers. Silently ignore.
556		if (entrypointsPresent)
557		{
558			int stackDepth = 0;
559			gl.getIntegerv(GL_DEBUG_GROUP_STACK_DEPTH, &stackDepth);
560			for (int ndx = 1; ndx < stackDepth; ++ndx)
561				gl.popDebugGroup();
562
563			gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true);
564			gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, DE_NULL, false);
565			gl.debugMessageCallback(DE_NULL, DE_NULL);
566
567			if (type.getFlags() & glu::CONTEXT_DEBUG)
568				gl.enable(GL_DEBUG_OUTPUT);
569			else
570				gl.disable(GL_DEBUG_OUTPUT);
571			gl.disable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
572
573			GLU_EXPECT_NO_ERROR(gl.getError(), "Debug state reset failed");
574		}
575	}
576
577	// Primitive bounding box state.
578	if (ctxInfo->isExtensionSupported("GL_EXT_primitive_bounding_box"))
579	{
580		gl.primitiveBoundingBoxEXT(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
581		GLU_EXPECT_NO_ERROR(gl.getError(), "Primitive bounding box state reset failed");
582	}
583
584	// Tessellation state
585	if (ctxInfo->isExtensionSupported("GL_EXT_tessellation_shader"))
586	{
587		gl.patchParameteri(GL_PATCH_VERTICES, 3);
588		GLU_EXPECT_NO_ERROR(gl.getError(), "Tessellation patch vertices state reset failed");
589	}
590
591	// Advanced coherent blending
592	if (ctxInfo->isExtensionSupported("GL_KHR_blend_equation_advanced_coherent"))
593	{
594		gl.enable(GL_BLEND_ADVANCED_COHERENT_KHR);
595		GLU_EXPECT_NO_ERROR(gl.getError(), "Blend equation advanced coherent state reset failed");
596	}
597
598	// Texture buffer
599	if (ctxInfo->isExtensionSupported("GL_EXT_texture_buffer"))
600	{
601		gl.bindTexture(GL_TEXTURE_BUFFER, 0);
602		gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
603		GLU_EXPECT_NO_ERROR(gl.getError(), "Texture buffer state reset failed");
604	}
605}
606
607void resetStateGLCore (const RenderContext& renderCtx)
608{
609	const glw::Functions&					gl		= renderCtx.getFunctions();
610	const ContextType						type	= renderCtx.getType();
611	const de::UniquePtr<glu::ContextInfo>	ctxInfo	(glu::ContextInfo::create(renderCtx));
612
613	// Reset error state.
614	gl.getError();
615	GLU_EXPECT_NO_ERROR(gl.getError(), "Error state");
616
617	// Vertex attrib array state.
618	{
619		gl.bindVertexArray	(0);
620		gl.bindBuffer		(GL_ARRAY_BUFFER,			0);
621		gl.bindBuffer		(GL_ELEMENT_ARRAY_BUFFER,	0);
622
623		if (contextSupports(type, ApiType::core(3,1)))
624		{
625			gl.disable				(GL_PRIMITIVE_RESTART);
626			gl.primitiveRestartIndex(0);
627		}
628
629		GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex attrib array state reset failed");
630	}
631
632	// Transformation state.
633	{
634		const tcu::RenderTarget&	renderTarget		= renderCtx.getRenderTarget();
635		int							numUserClipPlanes	= 0;
636
637		gl.getIntegerv(GL_MAX_CLIP_DISTANCES, &numUserClipPlanes);
638
639		gl.viewport		(0, 0, renderTarget.getWidth(), renderTarget.getHeight());
640		gl.depthRange	(0.0, 1.0);
641
642		for (int ndx = 0; ndx < numUserClipPlanes; ndx++)
643			gl.disable(GL_CLIP_DISTANCE0+ndx);
644
645		if (contextSupports(type, ApiType::core(3,2)))
646			gl.disable(GL_DEPTH_CLAMP);
647
648		//gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
649
650		GLU_EXPECT_NO_ERROR(gl.getError(), "Transformation state reset failed");
651	}
652
653	// Coloring
654	{
655		gl.clampColor(GL_CLAMP_READ_COLOR, GL_FIXED_ONLY);
656
657		if (contextSupports(type, ApiType::core(3,2)))
658			gl.provokingVertex(GL_LAST_VERTEX_CONVENTION);
659
660		GLU_EXPECT_NO_ERROR(gl.getError(), "Coloring state reset failed");
661	}
662
663	// Rasterization state
664	{
665		gl.disable			(GL_RASTERIZER_DISCARD);
666		gl.pointSize		(1.0f);
667		gl.pointParameterf	(GL_POINT_FADE_THRESHOLD_SIZE,	1.0f);
668		gl.pointParameteri	(GL_POINT_SPRITE_COORD_ORIGIN,	GL_UPPER_LEFT);
669		gl.lineWidth		(1.0f);
670		gl.disable			(GL_LINE_SMOOTH);
671		gl.disable			(GL_CULL_FACE);
672		gl.cullFace			(GL_BACK);
673		gl.frontFace		(GL_CCW);
674		gl.disable			(GL_POLYGON_SMOOTH);
675		gl.polygonOffset	(0.0f, 0.0f);
676		gl.disable			(GL_POLYGON_OFFSET_POINT);
677		gl.disable			(GL_POLYGON_OFFSET_LINE);
678		gl.disable			(GL_POLYGON_OFFSET_FILL);
679
680		GLU_EXPECT_NO_ERROR(gl.getError(), "Rasterization state reset failed");
681	}
682
683	// Multisampling state
684	{
685		gl.enable			(GL_MULTISAMPLE);
686		gl.disable			(GL_SAMPLE_ALPHA_TO_COVERAGE);
687		gl.disable			(GL_SAMPLE_ALPHA_TO_ONE);
688		gl.disable			(GL_SAMPLE_COVERAGE);
689		gl.sampleCoverage	(1.0f, GL_FALSE);
690
691		if (contextSupports(type, ApiType::core(3,2)))
692		{
693			int numSampleMaskWords = 0;
694			gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &numSampleMaskWords);
695
696			gl.disable(GL_SAMPLE_MASK);
697
698			for (int ndx = 0; ndx < numSampleMaskWords; ndx++)
699				gl.sampleMaski(ndx, ~0u);
700		}
701
702		GLU_EXPECT_NO_ERROR(gl.getError(), "Multisampling state reset failed");
703	}
704
705	// Texture state.
706	// \todo [2013-04-08 pyry] Reset all levels?
707	{
708		const float	borderColor[]	= { 0.0f, 0.0f, 0.0f, 0.0f };
709		int			numTexUnits		= 0;
710		gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numTexUnits);
711
712		gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
713
714		for (int ndx = 0; ndx < numTexUnits; ndx++)
715		{
716			gl.activeTexture(GL_TEXTURE0 + ndx);
717
718			// Reset 1D texture.
719			gl.bindTexture		(GL_TEXTURE_1D, 0);
720			gl.texImage1D		(GL_TEXTURE_1D, 0, GL_RGBA, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
721			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER,		GL_LINEAR_MIPMAP_NEAREST);
722			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
723			gl.texParameterfv	(GL_TEXTURE_1D, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
724			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
725			gl.texParameterf	(GL_TEXTURE_1D, GL_TEXTURE_MIN_LOD,			-1000.0f);
726			gl.texParameterf	(GL_TEXTURE_1D, GL_TEXTURE_MAX_LOD,			1000.0f);
727			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_BASE_LEVEL,		0);
728			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_MAX_LEVEL,		1000);
729			gl.texParameterf	(GL_TEXTURE_1D, GL_TEXTURE_LOD_BIAS,		0.0f);
730			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
731			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
732
733			if (contextSupports(type, ApiType::core(3,3)))
734			{
735				gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
736				gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
737				gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
738				gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
739			}
740
741			// Reset 2D texture.
742			gl.bindTexture		(GL_TEXTURE_2D, 0);
743			gl.texImage2D		(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
744			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,		GL_LINEAR_MIPMAP_NEAREST);
745			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
746			gl.texParameterfv	(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
747			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
748			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,			GL_REPEAT);
749			gl.texParameterf	(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD,			-1000.0f);
750			gl.texParameterf	(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD,			1000.0f);
751			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL,		0);
752			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL,		1000);
753			gl.texParameterf	(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS,		0.0f);
754			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
755			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
756
757			if (contextSupports(type, ApiType::core(3,3)))
758			{
759				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
760				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
761				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
762				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
763			}
764
765			// Reset cube map texture.
766			gl.bindTexture		(GL_TEXTURE_CUBE_MAP, 0);
767			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
768			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
769			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
770			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
771			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
772			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
773			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_LINEAR_MIPMAP_NEAREST);
774			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
775			gl.texParameterfv	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
776			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
777			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);
778			gl.texParameterf	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_LOD,		-1000.0f);
779			gl.texParameterf	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LOD,		1000.0f);
780			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL,	0);
781			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL,		1000);
782			gl.texParameterf	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_LOD_BIAS,		0.0f);
783			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
784			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
785
786			if (contextSupports(type, ApiType::core(3,3)))
787			{
788				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_R,		GL_RED);
789				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
790				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
791				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
792			}
793
794			// Reset 1D array texture.
795			gl.bindTexture		(GL_TEXTURE_1D_ARRAY, 0);
796			gl.texImage2D		(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
797			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_FILTER,	GL_LINEAR_MIPMAP_NEAREST);
798			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
799			gl.texParameterfv	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
800			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_WRAP_S,		GL_REPEAT);
801			gl.texParameterf	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_LOD,		-1000.0f);
802			gl.texParameterf	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAX_LOD,		1000.0f);
803			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_BASE_LEVEL,	0);
804			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAX_LEVEL,		1000);
805			gl.texParameterf	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_LOD_BIAS,		0.0f);
806			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
807			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
808
809			if (contextSupports(type, ApiType::core(3,3)))
810			{
811				gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_R,		GL_RED);
812				gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
813				gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
814				gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
815			}
816
817			// Reset 2D array texture.
818			gl.bindTexture		(GL_TEXTURE_2D_ARRAY, 0);
819			gl.texImage3D		(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
820			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER,	GL_LINEAR_MIPMAP_NEAREST);
821			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
822			gl.texParameterfv	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
823			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S,		GL_REPEAT);
824			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T,		GL_REPEAT);
825			gl.texParameterf	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_LOD,		-1000.0f);
826			gl.texParameterf	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LOD,		1000.0f);
827			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL,	0);
828			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL,		1000);
829			gl.texParameterf	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_LOD_BIAS,		0.0f);
830			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
831			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
832
833			if (contextSupports(type, ApiType::core(3,3)))
834			{
835				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_R,		GL_RED);
836				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
837				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
838				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
839			}
840
841			// Reset 3D texture.
842			gl.bindTexture		(GL_TEXTURE_3D, 0);
843			gl.texImage3D		(GL_TEXTURE_3D, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
844			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,		GL_LINEAR_MIPMAP_NEAREST);
845			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
846			gl.texParameterfv	(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
847			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
848			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,			GL_REPEAT);
849			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,			GL_REPEAT);
850			gl.texParameterf	(GL_TEXTURE_3D, GL_TEXTURE_MIN_LOD,			-1000.0f);
851			gl.texParameterf	(GL_TEXTURE_3D, GL_TEXTURE_MAX_LOD,			1000.0f);
852			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL,		0);
853			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL,		1000);
854			gl.texParameterf	(GL_TEXTURE_3D, GL_TEXTURE_LOD_BIAS,		0.0f);
855			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
856			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
857
858			if (contextSupports(type, ApiType::core(3,3)))
859			{
860				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
861				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
862				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
863				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
864			}
865
866			if (contextSupports(type, ApiType::core(3,1)))
867			{
868				// Reset rectangle texture.
869				gl.bindTexture		(GL_TEXTURE_RECTANGLE, 0);
870				gl.texImage2D		(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
871				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER,	GL_LINEAR);
872				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
873				gl.texParameterfv	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
874				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
875				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
876				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_BASE_LEVEL,	0);
877				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAX_LEVEL,	1000);
878				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
879				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
880				// \todo [2013-06-17 pyry] Drivers don't accept GL_MIN_LOD, GL_MAX_LOD for rectangle textures. Is that okay?
881
882				if (contextSupports(type, ApiType::core(3,3)))
883				{
884					gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_R,	GL_RED);
885					gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_G,	GL_GREEN);
886					gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_B,	GL_BLUE);
887					gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_A,	GL_ALPHA);
888				}
889
890				// Reset buffer texture.
891				gl.bindTexture	(GL_TEXTURE_BUFFER, 0);
892				gl.texBuffer	(GL_TEXTURE_BUFFER, GL_R8, 0);
893				// \todo [2013-05-04 pyry] Which parameters apply to buffer textures?
894			}
895
896			if (contextSupports(type, ApiType::core(3,2)))
897			{
898				// Reset 2D multisample texture.
899				gl.bindTexture				(GL_TEXTURE_2D_MULTISAMPLE, 0);
900				gl.texImage2DMultisample	(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 0, 0, GL_TRUE);
901
902				// Reset 2D multisample array texture.
903				gl.bindTexture				(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);
904				gl.texImage3DMultisample	(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, GL_RGBA8, 0, 0, 0, GL_TRUE);
905			}
906		}
907
908		gl.activeTexture(GL_TEXTURE0);
909
910		if (contextSupports(type, ApiType::core(3,3)))
911		{
912			for (int ndx = 0; ndx < numTexUnits; ndx++)
913				gl.bindSampler(ndx, 0);
914
915			gl.disable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
916		}
917
918		GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state reset failed");
919	}
920
921	// Pixel operations.
922	{
923		const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget();
924
925		gl.disable		(GL_SCISSOR_TEST);
926		gl.scissor		(0, 0, renderTarget.getWidth(), renderTarget.getHeight());
927
928		gl.disable		(GL_STENCIL_TEST);
929		gl.stencilFunc	(GL_ALWAYS, 0, ~0u);
930		gl.stencilOp	(GL_KEEP, GL_KEEP, GL_KEEP);
931
932		gl.disable		(GL_DEPTH_TEST);
933		gl.depthFunc	(GL_LESS);
934
935		gl.disable		(GL_BLEND);
936		gl.blendFunc	(GL_ONE, GL_ZERO);
937		gl.blendEquation(GL_FUNC_ADD);
938		gl.blendColor	(0.0f, 0.0f, 0.0f, 0.0f);
939
940		gl.disable		(GL_FRAMEBUFFER_SRGB);
941		gl.enable		(GL_DITHER);
942
943		gl.disable		(GL_COLOR_LOGIC_OP);
944		gl.logicOp		(GL_COPY);
945
946		GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel operation state reset failed");
947	}
948
949	// Framebuffer control.
950	{
951		gl.colorMask		(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
952		gl.depthMask		(GL_TRUE);
953		gl.stencilMask		(~0u);
954
955		gl.clearColor		(0.0f, 0.0f, 0.0f, 0.0f);
956		gl.clearDepth		(1.0);
957		gl.clearStencil		(0);
958
959		GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer control state reset failed");
960	}
961
962	// Framebuffer state.
963	{
964		// \todo [2013-04-05 pyry] Single-buffered rendering: use GL_FRONT
965		deUint32	framebuffer		= renderCtx.getDefaultFramebuffer();
966		deUint32	drawReadBuffer	= framebuffer == 0 ? GL_BACK : GL_COLOR_ATTACHMENT0;
967
968		gl.bindFramebuffer	(GL_FRAMEBUFFER, renderCtx.getDefaultFramebuffer());
969		gl.drawBuffer		(drawReadBuffer);
970		gl.readBuffer		(drawReadBuffer);
971
972		GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer state reset failed");
973	}
974
975	// Renderbuffer state.
976	{
977		gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
978		GLU_EXPECT_NO_ERROR(gl.getError(), "Renderbuffer state reset failed");
979	}
980
981	// Pixel transfer state.
982	{
983		gl.pixelStorei	(GL_UNPACK_SWAP_BYTES,		GL_FALSE);
984		gl.pixelStorei	(GL_UNPACK_LSB_FIRST,		GL_FALSE);
985		gl.pixelStorei	(GL_UNPACK_IMAGE_HEIGHT,	0);
986		gl.pixelStorei	(GL_UNPACK_SKIP_IMAGES,		0);
987		gl.pixelStorei	(GL_UNPACK_ROW_LENGTH,		0);
988		gl.pixelStorei	(GL_UNPACK_SKIP_ROWS,		0);
989		gl.pixelStorei	(GL_UNPACK_SKIP_PIXELS,		0);
990		gl.pixelStorei	(GL_UNPACK_ALIGNMENT,		4);
991
992		gl.pixelStorei	(GL_PACK_SWAP_BYTES,		GL_FALSE);
993		gl.pixelStorei	(GL_PACK_LSB_FIRST,			GL_FALSE);
994		gl.pixelStorei	(GL_PACK_IMAGE_HEIGHT,		0);
995		gl.pixelStorei	(GL_PACK_SKIP_IMAGES,		0);
996		gl.pixelStorei	(GL_PACK_ROW_LENGTH,		0);
997		gl.pixelStorei	(GL_PACK_SKIP_ROWS,			0);
998		gl.pixelStorei	(GL_PACK_SKIP_PIXELS,		0);
999		gl.pixelStorei	(GL_PACK_ALIGNMENT,			4);
1000
1001		gl.bindBuffer	(GL_PIXEL_PACK_BUFFER,		0);
1002		gl.bindBuffer	(GL_PIXEL_UNPACK_BUFFER,	0);
1003
1004		GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel transfer state reset failed");
1005	}
1006
1007	// Program object state.
1008	{
1009		gl.useProgram(0);
1010
1011		if (contextSupports(type, ApiType::core(3,1)))
1012		{
1013			int maxUniformBufferBindings = 0;
1014			gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings);
1015
1016			gl.bindBuffer(GL_UNIFORM_BUFFER, 0);
1017
1018			for (int ndx = 0; ndx < maxUniformBufferBindings; ndx++)
1019				gl.bindBufferBase(GL_UNIFORM_BUFFER, ndx, 0);
1020		}
1021
1022		GLU_EXPECT_NO_ERROR(gl.getError(), "Program object state reset failed");
1023	}
1024
1025	// Vertex shader state.
1026	{
1027		int numVertexAttribArrays = 0;
1028		gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribArrays);
1029
1030		for (int ndx = 0; ndx < numVertexAttribArrays; ndx++)
1031			gl.vertexAttrib4f(ndx, 0.0f, 0.0f, 0.0f, 1.0f);
1032
1033		gl.disable(GL_VERTEX_PROGRAM_POINT_SIZE);
1034
1035		GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex shader state reset failed");
1036	}
1037
1038	// Transform feedback state.
1039	{
1040		int numTransformFeedbackSeparateAttribs = 0;
1041		gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &numTransformFeedbackSeparateAttribs);
1042
1043		if (contextSupports(type, ApiType::core(4,0)))
1044		{
1045			glw::GLboolean transformFeedbackActive = 0;
1046			gl.getBooleanv(GL_TRANSFORM_FEEDBACK_ACTIVE, &transformFeedbackActive);
1047
1048			if (transformFeedbackActive)
1049				gl.endTransformFeedback();
1050		}
1051
1052		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
1053
1054		for (int ndx = 0; ndx < numTransformFeedbackSeparateAttribs; ndx++)
1055			gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, ndx, 0);
1056
1057		GLU_EXPECT_NO_ERROR(gl.getError(), "Transform feedback state reset failed");
1058	}
1059
1060	// Asynchronous query state.
1061	{
1062		deUint32	queryTargets[8];
1063		int			numTargets		= 0;
1064
1065		queryTargets[numTargets++] = GL_PRIMITIVES_GENERATED;
1066		queryTargets[numTargets++] = GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
1067		queryTargets[numTargets++] = GL_SAMPLES_PASSED;
1068
1069		DE_ASSERT(numTargets <= DE_LENGTH_OF_ARRAY(queryTargets));
1070
1071		for (int i = 0; i < numTargets; i++)
1072		{
1073			int queryActive = 0;
1074			gl.getQueryiv(queryTargets[i], GL_CURRENT_QUERY, &queryActive);
1075
1076			if (queryActive != 0)
1077				gl.endQuery(queryTargets[i]);
1078		}
1079
1080		GLU_EXPECT_NO_ERROR(gl.getError(), "Asynchronous query state reset failed");
1081	}
1082
1083	// Hints.
1084	{
1085		gl.hint(GL_LINE_SMOOTH_HINT,				GL_DONT_CARE);
1086		gl.hint(GL_POLYGON_SMOOTH_HINT,				GL_DONT_CARE);
1087		gl.hint(GL_TEXTURE_COMPRESSION_HINT,		GL_DONT_CARE);
1088		gl.hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT,	GL_DONT_CARE);
1089
1090		GLU_EXPECT_NO_ERROR(gl.getError(), "Hints reset failed");
1091	}
1092
1093	// Buffer copy state.
1094	if (contextSupports(type, ApiType::core(3,1)))
1095	{
1096		gl.bindBuffer(GL_COPY_READ_BUFFER,	0);
1097		gl.bindBuffer(GL_COPY_WRITE_BUFFER,	0);
1098
1099		GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer copy state reset failed");
1100	}
1101
1102	// Debug state
1103	if (ctxInfo->isExtensionSupported("GL_KHR_debug"))
1104	{
1105		const bool entrypointsPresent =	gl.debugMessageControl	!= DE_NULL	&&
1106										gl.debugMessageCallback	!= DE_NULL;
1107
1108		// some drivers advertise GL_KHR_debug but give out null pointers. Silently ignore.
1109		if (entrypointsPresent)
1110		{
1111			gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true);
1112			gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, DE_NULL, false);
1113			gl.debugMessageCallback(DE_NULL, DE_NULL);
1114
1115			if (type.getFlags() & glu::CONTEXT_DEBUG)
1116				gl.enable(GL_DEBUG_OUTPUT);
1117			else
1118				gl.disable(GL_DEBUG_OUTPUT);
1119		}
1120	}
1121}
1122
1123void resetState (const RenderContext& renderCtx)
1124{
1125	if (isContextTypeES(renderCtx.getType()))
1126		resetStateES(renderCtx);
1127	else if (isContextTypeGLCore(renderCtx.getType()))
1128		resetStateGLCore(renderCtx);
1129	else
1130		throw tcu::InternalError("State reset requested for unsupported context type");
1131}
1132
1133} // glu
1134