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		int numTexUnits = 0;
128		gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numTexUnits);
129
130		for (int ndx = 0; ndx < numTexUnits; ndx++)
131		{
132			gl.activeTexture(GL_TEXTURE0 + ndx);
133
134			// Reset 2D texture.
135			gl.bindTexture(GL_TEXTURE_2D, 0);
136			gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
137			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,		GL_LINEAR_MIPMAP_NEAREST);
138			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
139			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
140			gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,			GL_REPEAT);
141
142			if (contextSupports(type, ApiType::es(3,0)))
143			{
144				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
145				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
146				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
147				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
148				gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD,			-1000.0f);
149				gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD,			1000.0f);
150				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL,		0);
151				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL,		1000);
152				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
153				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
154			}
155
156			if (contextSupports(type, ApiType::es(3,1)))
157				gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
158
159			// Reset cube map texture.
160			gl.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
161			gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
162			gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
163			gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
164			gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
165			gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
166			gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
167			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_LINEAR_MIPMAP_NEAREST);
168			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
169			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
170			gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);
171
172			if (contextSupports(type, ApiType::es(3,0)))
173			{
174				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_R,		GL_RED);
175				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
176				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
177				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
178				gl.texParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_LOD,		-1000.0f);
179				gl.texParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LOD,		1000.0f);
180				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL,	0);
181				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL,		1000);
182				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
183				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
184			}
185
186			if (contextSupports(type, ApiType::es(3,1)))
187				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
188
189			if (contextSupports(type, ApiType::es(3,0)))
190			{
191				// Reset 2D array texture.
192				gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
193				gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
194				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER,	GL_LINEAR_MIPMAP_NEAREST);
195				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
196				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S,		GL_REPEAT);
197				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T,		GL_REPEAT);
198				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_R,		GL_RED);
199				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
200				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
201				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
202				gl.texParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_LOD,		-1000.0f);
203				gl.texParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LOD,		1000.0f);
204				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL,	0);
205				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL,		1000);
206				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
207				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
208				if (contextSupports(type, ApiType::es(3,1)))
209					gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
210			};
211
212			if (contextSupports(type, ApiType::es(3,0)))
213			{
214				// Reset 3D texture.
215				gl.bindTexture(GL_TEXTURE_3D, 0);
216				gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
217				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,		GL_LINEAR_MIPMAP_NEAREST);
218				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
219				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
220				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,			GL_REPEAT);
221				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,			GL_REPEAT);
222				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
223				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
224				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
225				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
226				gl.texParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_LOD,			-1000.0f);
227				gl.texParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAX_LOD,			1000.0f);
228				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL,		0);
229				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL,		1000);
230				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
231				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
232				if (contextSupports(type, ApiType::es(3,1)))
233					gl.texParameteri(GL_TEXTURE_3D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
234			}
235
236			if (contextSupports(type, ApiType::es(3,1)))
237			{
238				// Reset multisample textures.
239				gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
240
241				if (ctxInfo->isExtensionSupported("GL_OES_texture_storage_multisample_2d_array"))
242					gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);
243			}
244		}
245
246		gl.activeTexture(GL_TEXTURE0);
247
248		if (contextSupports(type, ApiType::es(3,0)))
249		{
250			for (int ndx = 0; ndx < numTexUnits; ndx++)
251				gl.bindSampler(ndx, 0);
252		}
253
254		GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state reset failed");
255	}
256
257	// Pixel operations.
258	{
259		const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget();
260
261		gl.disable		(GL_SCISSOR_TEST);
262		gl.scissor		(0, 0, renderTarget.getWidth(), renderTarget.getHeight());
263
264		gl.disable		(GL_STENCIL_TEST);
265		gl.stencilFunc	(GL_ALWAYS, 0, ~0u);
266		gl.stencilOp	(GL_KEEP, GL_KEEP, GL_KEEP);
267
268		gl.disable		(GL_DEPTH_TEST);
269		gl.depthFunc	(GL_LESS);
270
271		gl.disable		(GL_BLEND);
272		gl.blendFunc	(GL_ONE, GL_ZERO);
273		gl.blendEquation(GL_FUNC_ADD);
274		gl.blendColor	(0.0f, 0.0f, 0.0f, 0.0f);
275
276		gl.enable		(GL_DITHER);
277
278		GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel operation state reset failed");
279	}
280
281	// Framebuffer control.
282	{
283		gl.colorMask		(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
284		gl.depthMask		(GL_TRUE);
285		gl.stencilMask		(~0u);
286
287		gl.clearColor		(0.0f, 0.0f, 0.0f, 0.0f);
288		gl.clearDepthf		(1.0f);
289		gl.clearStencil		(0);
290
291		GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer control state reset failed");
292	}
293
294	// Framebuffer state.
295	{
296		// \note Actually spec explictly says 0 but on some platforms (iOS) no default framebuffer exists.
297		const deUint32		defaultFbo		= renderCtx.getDefaultFramebuffer();
298		const deUint32		drawBuffer		= defaultFbo != 0 ? GL_COLOR_ATTACHMENT0 : GL_BACK;
299		const deUint32		readBuffer		= defaultFbo != 0 ? GL_COLOR_ATTACHMENT0 : GL_BACK;
300
301		gl.bindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
302
303		if (contextSupports(type, ApiType::es(3,0)))
304		{
305			gl.drawBuffers	(1, &drawBuffer);
306			gl.readBuffer	(readBuffer);
307		}
308
309		GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer state reset failed");
310	}
311
312	// Renderbuffer state.
313	{
314		gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
315		GLU_EXPECT_NO_ERROR(gl.getError(), "Renderbuffer state reset failed");
316	}
317
318	// Pixel transfer state.
319	{
320		gl.pixelStorei(GL_UNPACK_ALIGNMENT,		4);
321		gl.pixelStorei(GL_PACK_ALIGNMENT,		4);
322
323		if (contextSupports(type, ApiType::es(3,0)))
324		{
325			gl.pixelStorei(GL_UNPACK_IMAGE_HEIGHT,	0);
326			gl.pixelStorei(GL_UNPACK_SKIP_IMAGES,	0);
327			gl.pixelStorei(GL_UNPACK_ROW_LENGTH,	0);
328			gl.pixelStorei(GL_UNPACK_SKIP_ROWS,		0);
329			gl.pixelStorei(GL_UNPACK_SKIP_PIXELS,	0);
330
331			gl.pixelStorei(GL_PACK_ROW_LENGTH,		0);
332			gl.pixelStorei(GL_PACK_SKIP_ROWS,		0);
333			gl.pixelStorei(GL_PACK_SKIP_PIXELS,		0);
334
335			gl.bindBuffer(GL_PIXEL_PACK_BUFFER,		0);
336			gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER,	0);
337		}
338
339		GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel transfer state reset failed");
340	}
341
342	// Program object state.
343	{
344		gl.useProgram(0);
345
346		if (contextSupports(type, ApiType::es(3,0)))
347		{
348			int maxUniformBufferBindings = 0;
349			gl.getIntegerv	(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings);
350			gl.bindBuffer	(GL_UNIFORM_BUFFER,	0);
351
352			for (int ndx = 0; ndx < maxUniformBufferBindings; ndx++)
353				gl.bindBufferBase(GL_UNIFORM_BUFFER, ndx, 0);
354		}
355
356		if (contextSupports(type, ApiType::es(3,1)))
357		{
358			gl.bindProgramPipeline(0);
359
360			{
361				int maxAtomicCounterBufferBindings = 0;
362				gl.getIntegerv	(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &maxAtomicCounterBufferBindings);
363				gl.bindBuffer	(GL_ATOMIC_COUNTER_BUFFER, 0);
364
365				for (int ndx = 0; ndx < maxAtomicCounterBufferBindings; ndx++)
366					gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, ndx, 0);
367			}
368
369			{
370				int maxShaderStorageBufferBindings = 0;
371				gl.getIntegerv	(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxShaderStorageBufferBindings);
372				gl.bindBuffer	(GL_SHADER_STORAGE_BUFFER, 0);
373
374				for (int ndx = 0; ndx < maxShaderStorageBufferBindings; ndx++)
375					gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, ndx, 0);
376			}
377		}
378
379		GLU_EXPECT_NO_ERROR(gl.getError(), "Program object state reset failed");
380	}
381
382	// Vertex shader state.
383	{
384		int numVertexAttribArrays = 0;
385		gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribArrays);
386
387		for (int ndx = 0; ndx < numVertexAttribArrays; ndx++)
388			gl.vertexAttrib4f(ndx, 0.0f, 0.0f, 0.0f, 1.0f);
389
390		GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex shader state reset failed");
391	}
392
393	// Transform feedback state.
394	if (contextSupports(type, ApiType::es(3,0)))
395	{
396		int				numTransformFeedbackSeparateAttribs	= 0;
397		glw::GLboolean	transformFeedbackActive				= 0;
398		gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,	&numTransformFeedbackSeparateAttribs);
399		gl.getBooleanv(GL_TRANSFORM_FEEDBACK_ACTIVE,				&transformFeedbackActive);
400
401		if (transformFeedbackActive)
402			gl.endTransformFeedback();
403
404		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
405
406		for (int ndx = 0; ndx < numTransformFeedbackSeparateAttribs; ndx++)
407			gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, ndx, 0);
408
409		GLU_EXPECT_NO_ERROR(gl.getError(), "Transform feedback state reset failed");
410	}
411
412	// Asynchronous query state.
413	if (contextSupports(type, ApiType::es(3,0)))
414	{
415		static const deUint32 targets[] = { GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN };
416
417		for (int i = 0; i < DE_LENGTH_OF_ARRAY(targets); i++)
418		{
419			int queryActive = 0;
420			gl.getQueryiv(targets[i], GL_CURRENT_QUERY, &queryActive);
421
422			if (queryActive != 0)
423				gl.endQuery(targets[i]);
424		}
425
426		GLU_EXPECT_NO_ERROR(gl.getError(), "Asynchronous query state reset failed");
427	}
428
429	// Hints.
430	{
431		gl.hint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE);
432
433		if (contextSupports(type, ApiType::es(3,0)))
434			gl.hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_DONT_CARE);
435
436		GLU_EXPECT_NO_ERROR(gl.getError(), "Hints reset failed");
437	}
438
439	// Compute.
440	if (contextSupports(type, ApiType::es(3,1)))
441	{
442		gl.bindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0);
443		GLU_EXPECT_NO_ERROR(gl.getError(), "Compute dispatch state reset failed");
444	}
445
446	// Buffer copy state.
447	if (contextSupports(type, ApiType::es(3,0)))
448	{
449		gl.bindBuffer(GL_COPY_READ_BUFFER,	0);
450		gl.bindBuffer(GL_COPY_WRITE_BUFFER,	0);
451
452		GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer copy state reset failed");
453	}
454
455	// Sample shading state.
456	if (contextSupports(type, ApiType::es(3,1)) && ctxInfo->isExtensionSupported("GL_OES_sample_shading"))
457	{
458		gl.minSampleShading(0.0f);
459		gl.disable(GL_SAMPLE_SHADING);
460
461		GLU_EXPECT_NO_ERROR(gl.getError(), "Sample shading state reset failed");
462	}
463
464	// Debug state
465	if (ctxInfo->isExtensionSupported("GL_KHR_debug"))
466	{
467		const bool entrypointsPresent =	gl.debugMessageControl	!= DE_NULL	&&
468										gl.debugMessageCallback	!= DE_NULL;
469
470		// some drivers advertise GL_KHR_debug but give out null pointers. Silently ignore.
471		if (entrypointsPresent)
472		{
473			gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true);
474			gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, DE_NULL, false);
475			gl.debugMessageCallback(DE_NULL, DE_NULL);
476
477			if (type.getFlags() & glu::CONTEXT_DEBUG)
478				gl.enable(GL_DEBUG_OUTPUT);
479			else
480				gl.disable(GL_DEBUG_OUTPUT);
481		}
482	}
483}
484
485void resetStateGLCore (const RenderContext& renderCtx)
486{
487	const glw::Functions&					gl		= renderCtx.getFunctions();
488	const ContextType						type	= renderCtx.getType();
489	const de::UniquePtr<glu::ContextInfo>	ctxInfo	(glu::ContextInfo::create(renderCtx));
490
491	// Reset error state.
492	gl.getError();
493	GLU_EXPECT_NO_ERROR(gl.getError(), "Error state");
494
495	// Vertex attrib array state.
496	{
497		gl.bindVertexArray	(0);
498		gl.bindBuffer		(GL_ARRAY_BUFFER,			0);
499		gl.bindBuffer		(GL_ELEMENT_ARRAY_BUFFER,	0);
500
501		if (contextSupports(type, ApiType::core(3,1)))
502		{
503			gl.disable				(GL_PRIMITIVE_RESTART);
504			gl.primitiveRestartIndex(0);
505		}
506
507		GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex attrib array state reset failed");
508	}
509
510	// Transformation state.
511	{
512		const tcu::RenderTarget&	renderTarget		= renderCtx.getRenderTarget();
513		int							numUserClipPlanes	= 0;
514
515		gl.getIntegerv(GL_MAX_CLIP_DISTANCES, &numUserClipPlanes);
516
517		gl.viewport		(0, 0, renderTarget.getWidth(), renderTarget.getHeight());
518		gl.depthRange	(0.0, 1.0);
519
520		for (int ndx = 0; ndx < numUserClipPlanes; ndx++)
521			gl.disable(GL_CLIP_DISTANCE0+ndx);
522
523		if (contextSupports(type, ApiType::core(3,2)))
524			gl.disable(GL_DEPTH_CLAMP);
525
526		//gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
527
528		GLU_EXPECT_NO_ERROR(gl.getError(), "Transformation state reset failed");
529	}
530
531	// Coloring
532	{
533		gl.clampColor(GL_CLAMP_READ_COLOR, GL_FIXED_ONLY);
534
535		if (contextSupports(type, ApiType::core(3,2)))
536			gl.provokingVertex(GL_LAST_VERTEX_CONVENTION);
537
538		GLU_EXPECT_NO_ERROR(gl.getError(), "Coloring state reset failed");
539	}
540
541	// Rasterization state
542	{
543		gl.disable			(GL_RASTERIZER_DISCARD);
544		gl.pointSize		(1.0f);
545		gl.pointParameterf	(GL_POINT_FADE_THRESHOLD_SIZE,	1.0f);
546		gl.pointParameteri	(GL_POINT_SPRITE_COORD_ORIGIN,	GL_UPPER_LEFT);
547		gl.lineWidth		(1.0f);
548		gl.disable			(GL_LINE_SMOOTH);
549		gl.disable			(GL_CULL_FACE);
550		gl.cullFace			(GL_BACK);
551		gl.frontFace		(GL_CCW);
552		gl.disable			(GL_POLYGON_SMOOTH);
553		gl.polygonOffset	(0.0f, 0.0f);
554		gl.disable			(GL_POLYGON_OFFSET_POINT);
555		gl.disable			(GL_POLYGON_OFFSET_LINE);
556		gl.disable			(GL_POLYGON_OFFSET_FILL);
557
558		GLU_EXPECT_NO_ERROR(gl.getError(), "Rasterization state reset failed");
559	}
560
561	// Multisampling state
562	{
563		gl.enable			(GL_MULTISAMPLE);
564		gl.disable			(GL_SAMPLE_ALPHA_TO_COVERAGE);
565		gl.disable			(GL_SAMPLE_ALPHA_TO_ONE);
566		gl.disable			(GL_SAMPLE_COVERAGE);
567		gl.sampleCoverage	(1.0f, GL_FALSE);
568
569		if (contextSupports(type, ApiType::core(3,2)))
570		{
571			int numSampleMaskWords = 0;
572			gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &numSampleMaskWords);
573
574			gl.disable(GL_SAMPLE_MASK);
575
576			for (int ndx = 0; ndx < numSampleMaskWords; ndx++)
577				gl.sampleMaski(ndx, ~0u);
578		}
579
580		GLU_EXPECT_NO_ERROR(gl.getError(), "Multisampling state reset failed");
581	}
582
583	// Texture state.
584	// \todo [2013-04-08 pyry] Reset all levels?
585	{
586		const float	borderColor[]	= { 0.0f, 0.0f, 0.0f, 0.0f };
587		int			numTexUnits		= 0;
588		gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numTexUnits);
589
590		gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
591
592		for (int ndx = 0; ndx < numTexUnits; ndx++)
593		{
594			gl.activeTexture(GL_TEXTURE0 + ndx);
595
596			// Reset 1D texture.
597			gl.bindTexture		(GL_TEXTURE_1D, 0);
598			gl.texImage1D		(GL_TEXTURE_1D, 0, GL_RGBA, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
599			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER,		GL_LINEAR_MIPMAP_NEAREST);
600			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
601			gl.texParameterfv	(GL_TEXTURE_1D, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
602			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
603			gl.texParameterf	(GL_TEXTURE_1D, GL_TEXTURE_MIN_LOD,			-1000.0f);
604			gl.texParameterf	(GL_TEXTURE_1D, GL_TEXTURE_MAX_LOD,			1000.0f);
605			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_BASE_LEVEL,		0);
606			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_MAX_LEVEL,		1000);
607			gl.texParameterf	(GL_TEXTURE_1D, GL_TEXTURE_LOD_BIAS,		0.0f);
608			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
609			gl.texParameteri	(GL_TEXTURE_1D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
610
611			if (contextSupports(type, ApiType::core(3,3)))
612			{
613				gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
614				gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
615				gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
616				gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
617			}
618
619			// Reset 2D texture.
620			gl.bindTexture		(GL_TEXTURE_2D, 0);
621			gl.texImage2D		(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
622			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,		GL_LINEAR_MIPMAP_NEAREST);
623			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
624			gl.texParameterfv	(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
625			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
626			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,			GL_REPEAT);
627			gl.texParameterf	(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD,			-1000.0f);
628			gl.texParameterf	(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD,			1000.0f);
629			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL,		0);
630			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL,		1000);
631			gl.texParameterf	(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS,		0.0f);
632			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
633			gl.texParameteri	(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
634
635			if (contextSupports(type, ApiType::core(3,3)))
636			{
637				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
638				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
639				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
640				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
641			}
642
643			// Reset cube map texture.
644			gl.bindTexture		(GL_TEXTURE_CUBE_MAP, 0);
645			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
646			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
647			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
648			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
649			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
650			gl.texImage2D		(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
651			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_LINEAR_MIPMAP_NEAREST);
652			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
653			gl.texParameterfv	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
654			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
655			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);
656			gl.texParameterf	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_LOD,		-1000.0f);
657			gl.texParameterf	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LOD,		1000.0f);
658			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL,	0);
659			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL,		1000);
660			gl.texParameterf	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_LOD_BIAS,		0.0f);
661			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
662			gl.texParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
663
664			if (contextSupports(type, ApiType::core(3,3)))
665			{
666				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_R,		GL_RED);
667				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
668				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
669				gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
670			}
671
672			// Reset 1D array texture.
673			gl.bindTexture		(GL_TEXTURE_1D_ARRAY, 0);
674			gl.texImage2D		(GL_TEXTURE_1D_ARRAY, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
675			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_FILTER,	GL_LINEAR_MIPMAP_NEAREST);
676			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
677			gl.texParameterfv	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
678			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_WRAP_S,		GL_REPEAT);
679			gl.texParameterf	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_LOD,		-1000.0f);
680			gl.texParameterf	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAX_LOD,		1000.0f);
681			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_BASE_LEVEL,	0);
682			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAX_LEVEL,		1000);
683			gl.texParameterf	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_LOD_BIAS,		0.0f);
684			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
685			gl.texParameteri	(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
686
687			if (contextSupports(type, ApiType::core(3,3)))
688			{
689				gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_R,		GL_RED);
690				gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
691				gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
692				gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
693			}
694
695			// Reset 2D array texture.
696			gl.bindTexture		(GL_TEXTURE_2D_ARRAY, 0);
697			gl.texImage3D		(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
698			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER,	GL_LINEAR_MIPMAP_NEAREST);
699			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
700			gl.texParameterfv	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
701			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S,		GL_REPEAT);
702			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T,		GL_REPEAT);
703			gl.texParameterf	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_LOD,		-1000.0f);
704			gl.texParameterf	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LOD,		1000.0f);
705			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL,	0);
706			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL,		1000);
707			gl.texParameterf	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_LOD_BIAS,		0.0f);
708			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
709			gl.texParameteri	(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
710
711			if (contextSupports(type, ApiType::core(3,3)))
712			{
713				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_R,		GL_RED);
714				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
715				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
716				gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
717			}
718
719			// Reset 3D texture.
720			gl.bindTexture		(GL_TEXTURE_3D, 0);
721			gl.texImage3D		(GL_TEXTURE_3D, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
722			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,		GL_LINEAR_MIPMAP_NEAREST);
723			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,		GL_LINEAR);
724			gl.texParameterfv	(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
725			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,			GL_REPEAT);
726			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,			GL_REPEAT);
727			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,			GL_REPEAT);
728			gl.texParameterf	(GL_TEXTURE_3D, GL_TEXTURE_MIN_LOD,			-1000.0f);
729			gl.texParameterf	(GL_TEXTURE_3D, GL_TEXTURE_MAX_LOD,			1000.0f);
730			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL,		0);
731			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL,		1000);
732			gl.texParameterf	(GL_TEXTURE_3D, GL_TEXTURE_LOD_BIAS,		0.0f);
733			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
734			gl.texParameteri	(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
735
736			if (contextSupports(type, ApiType::core(3,3)))
737			{
738				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R,		GL_RED);
739				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_G,		GL_GREEN);
740				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_B,		GL_BLUE);
741				gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A,		GL_ALPHA);
742			}
743
744			if (contextSupports(type, ApiType::core(3,1)))
745			{
746				// Reset rectangle texture.
747				gl.bindTexture		(GL_TEXTURE_RECTANGLE, 0);
748				gl.texImage2D		(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
749				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER,	GL_LINEAR);
750				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER,	GL_LINEAR);
751				gl.texParameterfv	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_BORDER_COLOR,	&borderColor[0]);
752				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
753				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
754				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_BASE_LEVEL,	0);
755				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAX_LEVEL,	1000);
756				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_COMPARE_MODE,	GL_NONE);
757				gl.texParameteri	(GL_TEXTURE_RECTANGLE, GL_TEXTURE_COMPARE_FUNC,	GL_LEQUAL);
758				// \todo [2013-06-17 pyry] Drivers don't accept GL_MIN_LOD, GL_MAX_LOD for rectangle textures. Is that okay?
759
760				if (contextSupports(type, ApiType::core(3,3)))
761				{
762					gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_R,	GL_RED);
763					gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_G,	GL_GREEN);
764					gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_B,	GL_BLUE);
765					gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_A,	GL_ALPHA);
766				}
767
768				// Reset buffer texture.
769				gl.bindTexture	(GL_TEXTURE_BUFFER, 0);
770				gl.texBuffer	(GL_TEXTURE_BUFFER, GL_R8, 0);
771				// \todo [2013-05-04 pyry] Which parameters apply to buffer textures?
772			}
773
774			if (contextSupports(type, ApiType::core(3,2)))
775			{
776				// Reset 2D multisample texture.
777				gl.bindTexture				(GL_TEXTURE_2D_MULTISAMPLE, 0);
778				gl.texImage2DMultisample	(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 0, 0, GL_TRUE);
779
780				// Reset 2D multisample array texture.
781				gl.bindTexture				(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);
782				gl.texImage3DMultisample	(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, GL_RGBA8, 0, 0, 0, GL_TRUE);
783			}
784		}
785
786		gl.activeTexture(GL_TEXTURE0);
787
788		if (contextSupports(type, ApiType::core(3,3)))
789		{
790			for (int ndx = 0; ndx < numTexUnits; ndx++)
791				gl.bindSampler(ndx, 0);
792
793			gl.disable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
794		}
795
796		GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state reset failed");
797	}
798
799	// Pixel operations.
800	{
801		const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget();
802
803		gl.disable		(GL_SCISSOR_TEST);
804		gl.scissor		(0, 0, renderTarget.getWidth(), renderTarget.getHeight());
805
806		gl.disable		(GL_STENCIL_TEST);
807		gl.stencilFunc	(GL_ALWAYS, 0, ~0u);
808		gl.stencilOp	(GL_KEEP, GL_KEEP, GL_KEEP);
809
810		gl.disable		(GL_DEPTH_TEST);
811		gl.depthFunc	(GL_LESS);
812
813		gl.disable		(GL_BLEND);
814		gl.blendFunc	(GL_ONE, GL_ZERO);
815		gl.blendEquation(GL_FUNC_ADD);
816		gl.blendColor	(0.0f, 0.0f, 0.0f, 0.0f);
817
818		gl.disable		(GL_FRAMEBUFFER_SRGB);
819		gl.enable		(GL_DITHER);
820
821		gl.disable		(GL_COLOR_LOGIC_OP);
822		gl.logicOp		(GL_COPY);
823
824		GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel operation state reset failed");
825	}
826
827	// Framebuffer control.
828	{
829		gl.colorMask		(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
830		gl.depthMask		(GL_TRUE);
831		gl.stencilMask		(~0u);
832
833		gl.clearColor		(0.0f, 0.0f, 0.0f, 0.0f);
834		gl.clearDepth		(1.0);
835		gl.clearStencil		(0);
836
837		GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer control state reset failed");
838	}
839
840	// Framebuffer state.
841	{
842		// \todo [2013-04-05 pyry] Single-buffered rendering: use GL_FRONT
843		deUint32	framebuffer		= renderCtx.getDefaultFramebuffer();
844		deUint32	drawReadBuffer	= framebuffer == 0 ? GL_BACK : GL_COLOR_ATTACHMENT0;
845
846		gl.bindFramebuffer	(GL_FRAMEBUFFER, renderCtx.getDefaultFramebuffer());
847		gl.drawBuffer		(drawReadBuffer);
848		gl.readBuffer		(drawReadBuffer);
849
850		GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer state reset failed");
851	}
852
853	// Renderbuffer state.
854	{
855		gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
856		GLU_EXPECT_NO_ERROR(gl.getError(), "Renderbuffer state reset failed");
857	}
858
859	// Pixel transfer state.
860	{
861		gl.pixelStorei	(GL_UNPACK_SWAP_BYTES,		GL_FALSE);
862		gl.pixelStorei	(GL_UNPACK_LSB_FIRST,		GL_FALSE);
863		gl.pixelStorei	(GL_UNPACK_IMAGE_HEIGHT,	0);
864		gl.pixelStorei	(GL_UNPACK_SKIP_IMAGES,		0);
865		gl.pixelStorei	(GL_UNPACK_ROW_LENGTH,		0);
866		gl.pixelStorei	(GL_UNPACK_SKIP_ROWS,		0);
867		gl.pixelStorei	(GL_UNPACK_SKIP_PIXELS,		0);
868		gl.pixelStorei	(GL_UNPACK_ALIGNMENT,		4);
869
870		gl.pixelStorei	(GL_PACK_SWAP_BYTES,		GL_FALSE);
871		gl.pixelStorei	(GL_PACK_LSB_FIRST,			GL_FALSE);
872		gl.pixelStorei	(GL_PACK_IMAGE_HEIGHT,		0);
873		gl.pixelStorei	(GL_PACK_SKIP_IMAGES,		0);
874		gl.pixelStorei	(GL_PACK_ROW_LENGTH,		0);
875		gl.pixelStorei	(GL_PACK_SKIP_ROWS,			0);
876		gl.pixelStorei	(GL_PACK_SKIP_PIXELS,		0);
877		gl.pixelStorei	(GL_PACK_ALIGNMENT,			4);
878
879		gl.bindBuffer	(GL_PIXEL_PACK_BUFFER,		0);
880		gl.bindBuffer	(GL_PIXEL_UNPACK_BUFFER,	0);
881
882		GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel transfer state reset failed");
883	}
884
885	// Program object state.
886	{
887		gl.useProgram(0);
888
889		if (contextSupports(type, ApiType::core(3,1)))
890		{
891			int maxUniformBufferBindings = 0;
892			gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings);
893
894			gl.bindBuffer(GL_UNIFORM_BUFFER, 0);
895
896			for (int ndx = 0; ndx < maxUniformBufferBindings; ndx++)
897				gl.bindBufferBase(GL_UNIFORM_BUFFER, ndx, 0);
898		}
899
900		GLU_EXPECT_NO_ERROR(gl.getError(), "Program object state reset failed");
901	}
902
903	// Vertex shader state.
904	{
905		int numVertexAttribArrays = 0;
906		gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribArrays);
907
908		for (int ndx = 0; ndx < numVertexAttribArrays; ndx++)
909			gl.vertexAttrib4f(ndx, 0.0f, 0.0f, 0.0f, 1.0f);
910
911		gl.disable(GL_VERTEX_PROGRAM_POINT_SIZE);
912
913		GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex shader state reset failed");
914	}
915
916	// Transform feedback state.
917	{
918		int numTransformFeedbackSeparateAttribs = 0;
919		gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &numTransformFeedbackSeparateAttribs);
920
921		if (contextSupports(type, ApiType::core(4,0)))
922		{
923			glw::GLboolean transformFeedbackActive = 0;
924			gl.getBooleanv(GL_TRANSFORM_FEEDBACK_ACTIVE, &transformFeedbackActive);
925
926			if (transformFeedbackActive)
927				gl.endTransformFeedback();
928		}
929
930		gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
931
932		for (int ndx = 0; ndx < numTransformFeedbackSeparateAttribs; ndx++)
933			gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, ndx, 0);
934
935		GLU_EXPECT_NO_ERROR(gl.getError(), "Transform feedback state reset failed");
936	}
937
938	// Asynchronous query state.
939	{
940		deUint32	queryTargets[8];
941		int			numTargets		= 0;
942
943		queryTargets[numTargets++] = GL_PRIMITIVES_GENERATED;
944		queryTargets[numTargets++] = GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
945		queryTargets[numTargets++] = GL_SAMPLES_PASSED;
946
947		DE_ASSERT(numTargets <= DE_LENGTH_OF_ARRAY(queryTargets));
948
949		for (int i = 0; i < numTargets; i++)
950		{
951			int queryActive = 0;
952			gl.getQueryiv(queryTargets[i], GL_CURRENT_QUERY, &queryActive);
953
954			if (queryActive != 0)
955				gl.endQuery(queryTargets[i]);
956		}
957
958		GLU_EXPECT_NO_ERROR(gl.getError(), "Asynchronous query state reset failed");
959	}
960
961	// Hints.
962	{
963		gl.hint(GL_LINE_SMOOTH_HINT,				GL_DONT_CARE);
964		gl.hint(GL_POLYGON_SMOOTH_HINT,				GL_DONT_CARE);
965		gl.hint(GL_TEXTURE_COMPRESSION_HINT,		GL_DONT_CARE);
966		gl.hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT,	GL_DONT_CARE);
967
968		GLU_EXPECT_NO_ERROR(gl.getError(), "Hints reset failed");
969	}
970
971	// Buffer copy state.
972	if (contextSupports(type, ApiType::core(3,1)))
973	{
974		gl.bindBuffer(GL_COPY_READ_BUFFER,	0);
975		gl.bindBuffer(GL_COPY_WRITE_BUFFER,	0);
976
977		GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer copy state reset failed");
978	}
979
980	// Debug state
981	if (ctxInfo->isExtensionSupported("GL_KHR_debug"))
982	{
983		const bool entrypointsPresent =	gl.debugMessageControl	!= DE_NULL	&&
984										gl.debugMessageCallback	!= DE_NULL;
985
986		// some drivers advertise GL_KHR_debug but give out null pointers. Silently ignore.
987		if (entrypointsPresent)
988		{
989			gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true);
990			gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, DE_NULL, false);
991			gl.debugMessageCallback(DE_NULL, DE_NULL);
992
993			if (type.getFlags() & glu::CONTEXT_DEBUG)
994				gl.enable(GL_DEBUG_OUTPUT);
995			else
996				gl.disable(GL_DEBUG_OUTPUT);
997		}
998	}
999}
1000
1001void resetState (const RenderContext& renderCtx)
1002{
1003	if (isContextTypeES(renderCtx.getType()))
1004		resetStateES(renderCtx);
1005	else if (isContextTypeGLCore(renderCtx.getType()))
1006		resetStateGLCore(renderCtx);
1007	else
1008		throw tcu::InternalError("State reset requested for unsupported context type");
1009}
1010
1011} // glu
1012