| /*------------------------------------------------------------------------- |
| * drawElements Quality Program OpenGL ES Utilities |
| * ------------------------------------------------ |
| * |
| * Copyright 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief OpenGL State Reset. |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "gluStateReset.hpp" |
| #include "gluContextInfo.hpp" |
| #include "gluRenderContext.hpp" |
| #include "tcuRenderTarget.hpp" |
| #include "glwFunctions.hpp" |
| #include "glwEnums.hpp" |
| #include "deUniquePtr.hpp" |
| |
| namespace glu |
| { |
| namespace |
| { |
| enum |
| { |
| MAX_ERROR_COUNT = 10 |
| }; |
| |
| void resetErrors (const glw::Functions& gl) |
| { |
| size_t errorNdx = 0; |
| |
| for (errorNdx = 0; errorNdx < MAX_ERROR_COUNT; errorNdx++) |
| { |
| if (gl.getError() == GL_NONE) |
| break; |
| } |
| |
| if (errorNdx == MAX_ERROR_COUNT) |
| TCU_FAIL("Couldn't reset error state"); |
| } |
| |
| } |
| |
| void resetStateES (const RenderContext& renderCtx, const ContextInfo& ctxInfo) |
| { |
| const glw::Functions& gl = renderCtx.getFunctions(); |
| const ContextType type = renderCtx.getType(); |
| |
| // Reset error state |
| resetErrors(gl); |
| |
| DE_ASSERT(isContextTypeES(type)); |
| |
| // Vertex attrib array state. |
| { |
| int numVertexAttribArrays = 0; |
| gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribArrays); |
| |
| gl.bindBuffer (GL_ARRAY_BUFFER, 0); |
| gl.bindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0); |
| |
| if (contextSupports(type, ApiType::es(3,0))) |
| { |
| gl.bindVertexArray (0); |
| gl.disable (GL_PRIMITIVE_RESTART_FIXED_INDEX); |
| } |
| |
| if (contextSupports(type, ApiType::es(3,1))) |
| gl.bindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); |
| |
| for (int ndx = 0; ndx < numVertexAttribArrays; ndx++) |
| { |
| gl.disableVertexAttribArray (ndx); |
| gl.vertexAttribPointer (ndx, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL); |
| |
| if (contextSupports(type, ApiType::es(3,0))) |
| gl.vertexAttribDivisor(ndx, 0); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex attrib array state reset failed"); |
| } |
| |
| // Transformation state. |
| { |
| const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget(); |
| |
| gl.viewport (0, 0, renderTarget.getWidth(), renderTarget.getHeight()); |
| gl.depthRangef (0.0f, 1.0f); |
| |
| if (contextSupports(type, ApiType::es(3,0))) |
| gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Transformation state reset failed"); |
| } |
| |
| // Rasterization state |
| { |
| gl.lineWidth (1.0f); |
| gl.disable (GL_CULL_FACE); |
| gl.cullFace (GL_BACK); |
| gl.frontFace (GL_CCW); |
| gl.polygonOffset(0.0f, 0.0f); |
| gl.disable (GL_POLYGON_OFFSET_FILL); |
| |
| if (contextSupports(type, ApiType::es(3,0))) |
| gl.disable(GL_RASTERIZER_DISCARD); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Rasterization state reset failed"); |
| } |
| |
| // Multisampling state |
| { |
| gl.disable (GL_SAMPLE_ALPHA_TO_COVERAGE); |
| gl.disable (GL_SAMPLE_COVERAGE); |
| gl.sampleCoverage (1.0f, GL_FALSE); |
| |
| if (contextSupports(type, ApiType::es(3,1))) |
| { |
| int numSampleMaskWords = 0; |
| gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &numSampleMaskWords); |
| |
| gl.disable(GL_SAMPLE_MASK); |
| |
| for (int ndx = 0; ndx < numSampleMaskWords; ndx++) |
| gl.sampleMaski(ndx, ~0u); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Multisampling state reset failed"); |
| } |
| |
| // Texture state. |
| // \todo [2013-04-08 pyry] Reset all levels? |
| { |
| const float borderColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; |
| int numTexUnits = 0; |
| gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numTexUnits); |
| |
| for (int ndx = 0; ndx < numTexUnits; ndx++) |
| { |
| gl.activeTexture(GL_TEXTURE0 + ndx); |
| |
| // Reset 2D texture. |
| gl.bindTexture(GL_TEXTURE_2D, 0); |
| gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); |
| |
| if (contextSupports(type, ApiType::es(3,0))) |
| { |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); |
| gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, -1000.0f); |
| gl.texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 1000.0f); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1000); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); |
| } |
| |
| if (contextSupports(type, ApiType::es(3,1))) |
| gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT); |
| |
| if (ctxInfo.isExtensionSupported("GL_EXT_texture_border_clamp")) |
| gl.texParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &borderColor[0]); |
| |
| // Reset cube map texture. |
| gl.bindTexture(GL_TEXTURE_CUBE_MAP, 0); |
| gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT); |
| |
| if (contextSupports(type, ApiType::es(3,0))) |
| { |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_R, GL_RED); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_G, GL_GREEN); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_B, GL_BLUE); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); |
| gl.texParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_LOD, -1000.0f); |
| gl.texParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LOD, 1000.0f); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 1000); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_NONE); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); |
| } |
| |
| if (contextSupports(type, ApiType::es(3,1))) |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT); |
| |
| if (ctxInfo.isExtensionSupported("GL_EXT_texture_border_clamp")) |
| gl.texParameterfv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR, &borderColor[0]); |
| |
| if (contextSupports(type, ApiType::es(3,0))) |
| { |
| // Reset 2D array texture. |
| gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0); |
| gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_R, GL_RED); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_G, GL_GREEN); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_B, GL_BLUE); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); |
| gl.texParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_LOD, -1000.0f); |
| gl.texParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LOD, 1000.0f); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1000); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_NONE); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); |
| |
| if (ctxInfo.isExtensionSupported("GL_EXT_texture_border_clamp")) |
| gl.texParameterfv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, &borderColor[0]); |
| } |
| |
| if (contextSupports(type, ApiType::es(3,1))) |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT); |
| |
| if (contextSupports(type, ApiType::es(3,0))) |
| { |
| // Reset 3D texture. |
| gl.bindTexture(GL_TEXTURE_3D, 0); |
| gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R, GL_RED); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_G, GL_GREEN); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_B, GL_BLUE); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); |
| gl.texParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_LOD, -1000.0f); |
| gl.texParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAX_LOD, 1000.0f); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1000); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_MODE, GL_NONE); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); |
| |
| if (ctxInfo.isExtensionSupported("GL_EXT_texture_border_clamp")) |
| gl.texParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, &borderColor[0]); |
| } |
| |
| if (contextSupports(type, ApiType::es(3,1))) |
| gl.texParameteri(GL_TEXTURE_3D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT); |
| |
| if (contextSupports(type, ApiType::es(3,1))) |
| { |
| // Reset multisample textures. |
| gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0); |
| gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_SWIZZLE_R, GL_RED); |
| gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_SWIZZLE_G, GL_GREEN); |
| gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_SWIZZLE_B, GL_BLUE); |
| gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); |
| gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAX_LEVEL, 1000); |
| } |
| |
| if (ctxInfo.isExtensionSupported("GL_OES_texture_storage_multisample_2d_array")) |
| { |
| gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0); |
| gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_SWIZZLE_R, GL_RED); |
| gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_SWIZZLE_G, GL_GREEN); |
| gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_SWIZZLE_B, GL_BLUE); |
| gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); |
| gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_MAX_LEVEL, 1000); |
| } |
| |
| if (ctxInfo.isExtensionSupported("GL_EXT_texture_cube_map_array")) |
| { |
| // Reset cube array texture. |
| gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_SWIZZLE_R, GL_RED); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_SWIZZLE_G, GL_GREEN); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_SWIZZLE_B, GL_BLUE); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); |
| gl.texParameterf(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_LOD, -1000.0f); |
| gl.texParameterf(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LOD, 1000.0f); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL, 1000); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_NONE); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); |
| |
| if (ctxInfo.isExtensionSupported("GL_EXT_texture_border_clamp")) |
| gl.texParameterfv(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BORDER_COLOR, &borderColor[0]); |
| } |
| } |
| |
| gl.activeTexture(GL_TEXTURE0); |
| |
| if (contextSupports(type, ApiType::es(3,0))) |
| { |
| for (int ndx = 0; ndx < numTexUnits; ndx++) |
| gl.bindSampler(ndx, 0); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state reset failed"); |
| } |
| |
| // Resetting state using non-indexed variants should be enough, but some |
| // implementations have bugs so we need to make sure indexed state gets |
| // set back to initial values. |
| if (ctxInfo.isExtensionSupported("GL_EXT_draw_buffers_indexed")) |
| { |
| int numDrawBuffers = 0; |
| |
| gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &numDrawBuffers); |
| |
| for (int drawBufferNdx = 0; drawBufferNdx < numDrawBuffers; drawBufferNdx++) |
| { |
| gl.disablei (GL_BLEND, drawBufferNdx); |
| gl.blendFunci (drawBufferNdx, GL_ONE, GL_ZERO); |
| gl.blendEquationi (drawBufferNdx, GL_FUNC_ADD); |
| gl.colorMaski (drawBufferNdx, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to reset indexed draw buffer state"); |
| } |
| |
| // Pixel operations. |
| { |
| const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget(); |
| |
| gl.disable (GL_SCISSOR_TEST); |
| gl.scissor (0, 0, renderTarget.getWidth(), renderTarget.getHeight()); |
| |
| gl.disable (GL_STENCIL_TEST); |
| gl.stencilFunc (GL_ALWAYS, 0, ~0u); |
| gl.stencilOp (GL_KEEP, GL_KEEP, GL_KEEP); |
| |
| gl.disable (GL_DEPTH_TEST); |
| gl.depthFunc (GL_LESS); |
| |
| gl.disable (GL_BLEND); |
| gl.blendFunc (GL_ONE, GL_ZERO); |
| gl.blendEquation(GL_FUNC_ADD); |
| gl.blendColor (0.0f, 0.0f, 0.0f, 0.0f); |
| |
| gl.enable (GL_DITHER); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel operation state reset failed"); |
| } |
| |
| // Framebuffer control. |
| { |
| gl.colorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
| gl.depthMask (GL_TRUE); |
| gl.stencilMask (~0u); |
| |
| gl.clearColor (0.0f, 0.0f, 0.0f, 0.0f); |
| gl.clearDepthf (1.0f); |
| gl.clearStencil (0); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer control state reset failed"); |
| } |
| |
| // Framebuffer state. |
| { |
| // \note Actually spec explictly says 0 but on some platforms (iOS) no default framebuffer exists. |
| const deUint32 defaultFbo = renderCtx.getDefaultFramebuffer(); |
| const deUint32 drawBuffer = defaultFbo != 0 ? GL_COLOR_ATTACHMENT0 : GL_BACK; |
| const deUint32 readBuffer = defaultFbo != 0 ? GL_COLOR_ATTACHMENT0 : GL_BACK; |
| |
| gl.bindFramebuffer(GL_FRAMEBUFFER, defaultFbo); |
| |
| if (contextSupports(type, ApiType::es(3,0))) |
| { |
| gl.drawBuffers (1, &drawBuffer); |
| gl.readBuffer (readBuffer); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer state reset failed"); |
| } |
| |
| // Renderbuffer state. |
| { |
| gl.bindRenderbuffer(GL_RENDERBUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Renderbuffer state reset failed"); |
| } |
| |
| // Pixel transfer state. |
| { |
| gl.pixelStorei(GL_UNPACK_ALIGNMENT, 4); |
| gl.pixelStorei(GL_PACK_ALIGNMENT, 4); |
| |
| if (contextSupports(type, ApiType::es(3,0))) |
| { |
| gl.pixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); |
| gl.pixelStorei(GL_UNPACK_SKIP_IMAGES, 0); |
| gl.pixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
| gl.pixelStorei(GL_UNPACK_SKIP_ROWS, 0); |
| gl.pixelStorei(GL_UNPACK_SKIP_PIXELS, 0); |
| |
| gl.pixelStorei(GL_PACK_ROW_LENGTH, 0); |
| gl.pixelStorei(GL_PACK_SKIP_ROWS, 0); |
| gl.pixelStorei(GL_PACK_SKIP_PIXELS, 0); |
| |
| gl.bindBuffer(GL_PIXEL_PACK_BUFFER, 0); |
| gl.bindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel transfer state reset failed"); |
| } |
| |
| // Program object state. |
| { |
| gl.useProgram(0); |
| |
| if (contextSupports(type, ApiType::es(3,0))) |
| { |
| int maxUniformBufferBindings = 0; |
| gl.getIntegerv (GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings); |
| gl.bindBuffer (GL_UNIFORM_BUFFER, 0); |
| |
| for (int ndx = 0; ndx < maxUniformBufferBindings; ndx++) |
| gl.bindBufferBase(GL_UNIFORM_BUFFER, ndx, 0); |
| } |
| |
| if (contextSupports(type, ApiType::es(3,1))) |
| { |
| gl.bindProgramPipeline(0); |
| |
| { |
| int maxAtomicCounterBufferBindings = 0; |
| gl.getIntegerv (GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &maxAtomicCounterBufferBindings); |
| gl.bindBuffer (GL_ATOMIC_COUNTER_BUFFER, 0); |
| |
| for (int ndx = 0; ndx < maxAtomicCounterBufferBindings; ndx++) |
| gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, ndx, 0); |
| } |
| |
| { |
| int maxShaderStorageBufferBindings = 0; |
| gl.getIntegerv (GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxShaderStorageBufferBindings); |
| gl.bindBuffer (GL_SHADER_STORAGE_BUFFER, 0); |
| |
| for (int ndx = 0; ndx < maxShaderStorageBufferBindings; ndx++) |
| gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, ndx, 0); |
| } |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Program object state reset failed"); |
| } |
| |
| // Vertex shader state. |
| { |
| int numVertexAttribArrays = 0; |
| gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribArrays); |
| |
| for (int ndx = 0; ndx < numVertexAttribArrays; ndx++) |
| gl.vertexAttrib4f(ndx, 0.0f, 0.0f, 0.0f, 1.0f); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex shader state reset failed"); |
| } |
| |
| // Transform feedback state. |
| if (contextSupports(type, ApiType::es(3,0))) |
| { |
| int numTransformFeedbackSeparateAttribs = 0; |
| glw::GLboolean transformFeedbackActive = 0; |
| gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &numTransformFeedbackSeparateAttribs); |
| gl.getBooleanv(GL_TRANSFORM_FEEDBACK_ACTIVE, &transformFeedbackActive); |
| |
| if (transformFeedbackActive) |
| gl.endTransformFeedback(); |
| |
| gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); |
| |
| for (int ndx = 0; ndx < numTransformFeedbackSeparateAttribs; ndx++) |
| gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, ndx, 0); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Transform feedback state reset failed"); |
| } |
| |
| // Asynchronous query state. |
| if (contextSupports(type, ApiType::es(3,0))) |
| { |
| static const deUint32 targets[] = { GL_ANY_SAMPLES_PASSED, GL_ANY_SAMPLES_PASSED_CONSERVATIVE, GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN }; |
| |
| for (int i = 0; i < DE_LENGTH_OF_ARRAY(targets); i++) |
| { |
| int queryActive = 0; |
| gl.getQueryiv(targets[i], GL_CURRENT_QUERY, &queryActive); |
| |
| if (queryActive != 0) |
| gl.endQuery(targets[i]); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Asynchronous query state reset failed"); |
| } |
| |
| // Hints. |
| { |
| gl.hint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); |
| |
| if (contextSupports(type, ApiType::es(3,0))) |
| gl.hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_DONT_CARE); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Hints reset failed"); |
| } |
| |
| // Compute. |
| if (contextSupports(type, ApiType::es(3,1))) |
| { |
| gl.bindBuffer(GL_DISPATCH_INDIRECT_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Compute dispatch state reset failed"); |
| } |
| |
| // Buffer copy state. |
| if (contextSupports(type, ApiType::es(3,0))) |
| { |
| gl.bindBuffer(GL_COPY_READ_BUFFER, 0); |
| gl.bindBuffer(GL_COPY_WRITE_BUFFER, 0); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer copy state reset failed"); |
| } |
| |
| // Images. |
| if (contextSupports(type, ApiType::es(3,1))) |
| { |
| int numImageUnits = 0; |
| gl.getIntegerv(GL_MAX_IMAGE_UNITS, &numImageUnits); |
| |
| for (int ndx = 0; ndx < numImageUnits; ndx++) |
| gl.bindImageTexture(ndx, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32UI); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Image state reset failed"); |
| } |
| |
| // Sample shading state. |
| if (contextSupports(type, ApiType::es(3,1)) && ctxInfo.isExtensionSupported("GL_OES_sample_shading")) |
| { |
| gl.minSampleShading(0.0f); |
| gl.disable(GL_SAMPLE_SHADING); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Sample shading state reset failed"); |
| } |
| |
| // Debug state |
| if (ctxInfo.isExtensionSupported("GL_KHR_debug")) |
| { |
| const bool entrypointsPresent = gl.debugMessageControl != DE_NULL && |
| gl.debugMessageCallback != DE_NULL && |
| gl.popDebugGroup != DE_NULL; |
| |
| // some drivers advertise GL_KHR_debug but give out null pointers. Silently ignore. |
| if (entrypointsPresent) |
| { |
| int stackDepth = 0; |
| gl.getIntegerv(GL_DEBUG_GROUP_STACK_DEPTH, &stackDepth); |
| for (int ndx = 1; ndx < stackDepth; ++ndx) |
| gl.popDebugGroup(); |
| |
| gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true); |
| gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, DE_NULL, false); |
| gl.debugMessageCallback(DE_NULL, DE_NULL); |
| |
| if (type.getFlags() & glu::CONTEXT_DEBUG) |
| gl.enable(GL_DEBUG_OUTPUT); |
| else |
| gl.disable(GL_DEBUG_OUTPUT); |
| gl.disable(GL_DEBUG_OUTPUT_SYNCHRONOUS); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Debug state reset failed"); |
| } |
| } |
| |
| // Primitive bounding box state. |
| if (ctxInfo.isExtensionSupported("GL_EXT_primitive_bounding_box")) |
| { |
| gl.primitiveBoundingBox(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Primitive bounding box state reset failed"); |
| } |
| |
| // Tessellation state |
| if (ctxInfo.isExtensionSupported("GL_EXT_tessellation_shader")) |
| { |
| gl.patchParameteri(GL_PATCH_VERTICES, 3); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Tessellation patch vertices state reset failed"); |
| } |
| |
| // Advanced coherent blending |
| if (ctxInfo.isExtensionSupported("GL_KHR_blend_equation_advanced_coherent")) |
| { |
| gl.enable(GL_BLEND_ADVANCED_COHERENT_KHR); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Blend equation advanced coherent state reset failed"); |
| } |
| |
| // Texture buffer |
| if (ctxInfo.isExtensionSupported("GL_EXT_texture_buffer")) |
| { |
| gl.bindTexture(GL_TEXTURE_BUFFER, 0); |
| gl.bindBuffer(GL_TEXTURE_BUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Texture buffer state reset failed"); |
| } |
| } |
| |
| void resetStateGLCore (const RenderContext& renderCtx, const ContextInfo& ctxInfo) |
| { |
| const glw::Functions& gl = renderCtx.getFunctions(); |
| const ContextType type = renderCtx.getType(); |
| |
| // Reset error state |
| resetErrors(gl); |
| |
| // Vertex attrib array state. |
| { |
| gl.bindVertexArray (0); |
| gl.bindBuffer (GL_ARRAY_BUFFER, 0); |
| gl.bindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0); |
| |
| if (contextSupports(type, ApiType::core(3,1))) |
| { |
| gl.disable (GL_PRIMITIVE_RESTART); |
| gl.primitiveRestartIndex(0); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex attrib array state reset failed"); |
| } |
| |
| // Transformation state. |
| { |
| const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget(); |
| int numUserClipPlanes = 0; |
| |
| gl.getIntegerv(GL_MAX_CLIP_DISTANCES, &numUserClipPlanes); |
| |
| gl.viewport (0, 0, renderTarget.getWidth(), renderTarget.getHeight()); |
| gl.depthRange (0.0, 1.0); |
| |
| for (int ndx = 0; ndx < numUserClipPlanes; ndx++) |
| gl.disable(GL_CLIP_DISTANCE0+ndx); |
| |
| if (contextSupports(type, ApiType::core(3,2))) |
| gl.disable(GL_DEPTH_CLAMP); |
| |
| //gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Transformation state reset failed"); |
| } |
| |
| // Coloring |
| { |
| gl.clampColor(GL_CLAMP_READ_COLOR, GL_FIXED_ONLY); |
| |
| if (contextSupports(type, ApiType::core(3,2))) |
| gl.provokingVertex(GL_LAST_VERTEX_CONVENTION); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Coloring state reset failed"); |
| } |
| |
| // Rasterization state |
| { |
| gl.disable (GL_RASTERIZER_DISCARD); |
| gl.pointSize (1.0f); |
| gl.pointParameterf (GL_POINT_FADE_THRESHOLD_SIZE, 1.0f); |
| gl.pointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, GL_UPPER_LEFT); |
| gl.lineWidth (1.0f); |
| gl.disable (GL_LINE_SMOOTH); |
| gl.disable (GL_CULL_FACE); |
| gl.cullFace (GL_BACK); |
| gl.frontFace (GL_CCW); |
| gl.disable (GL_POLYGON_SMOOTH); |
| gl.polygonOffset (0.0f, 0.0f); |
| gl.disable (GL_POLYGON_OFFSET_POINT); |
| gl.disable (GL_POLYGON_OFFSET_LINE); |
| gl.disable (GL_POLYGON_OFFSET_FILL); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Rasterization state reset failed"); |
| } |
| |
| // Multisampling state |
| { |
| gl.enable (GL_MULTISAMPLE); |
| gl.disable (GL_SAMPLE_ALPHA_TO_COVERAGE); |
| gl.disable (GL_SAMPLE_ALPHA_TO_ONE); |
| gl.disable (GL_SAMPLE_COVERAGE); |
| gl.sampleCoverage (1.0f, GL_FALSE); |
| |
| if (contextSupports(type, ApiType::core(3,2))) |
| { |
| int numSampleMaskWords = 0; |
| gl.getIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &numSampleMaskWords); |
| |
| gl.disable(GL_SAMPLE_MASK); |
| |
| for (int ndx = 0; ndx < numSampleMaskWords; ndx++) |
| gl.sampleMaski(ndx, ~0u); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Multisampling state reset failed"); |
| } |
| |
| // Texture state. |
| // \todo [2013-04-08 pyry] Reset all levels? |
| { |
| const float borderColor[] = { 0.0f, 0.0f, 0.0f, 0.0f }; |
| int numTexUnits = 0; |
| gl.getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numTexUnits); |
| |
| gl.bindBuffer(GL_TEXTURE_BUFFER, 0); |
| |
| for (int ndx = 0; ndx < numTexUnits; ndx++) |
| { |
| gl.activeTexture(GL_TEXTURE0 + ndx); |
| |
| // Reset 1D texture. |
| gl.bindTexture (GL_TEXTURE_1D, 0); |
| gl.texImage1D (GL_TEXTURE_1D, 0, GL_RGBA, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); |
| gl.texParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| gl.texParameterfv (GL_TEXTURE_1D, GL_TEXTURE_BORDER_COLOR, &borderColor[0]); |
| gl.texParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); |
| gl.texParameterf (GL_TEXTURE_1D, GL_TEXTURE_MIN_LOD, -1000.0f); |
| gl.texParameterf (GL_TEXTURE_1D, GL_TEXTURE_MAX_LOD, 1000.0f); |
| gl.texParameteri (GL_TEXTURE_1D, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAX_LEVEL, 1000); |
| gl.texParameterf (GL_TEXTURE_1D, GL_TEXTURE_LOD_BIAS, 0.0f); |
| gl.texParameteri (GL_TEXTURE_1D, GL_TEXTURE_COMPARE_MODE, GL_NONE); |
| gl.texParameteri (GL_TEXTURE_1D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); |
| |
| if (contextSupports(type, ApiType::core(3,3))) |
| { |
| gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_R, GL_RED); |
| gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_G, GL_GREEN); |
| gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_B, GL_BLUE); |
| gl.texParameteri(GL_TEXTURE_1D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); |
| } |
| |
| // Reset 2D texture. |
| gl.bindTexture (GL_TEXTURE_2D, 0); |
| gl.texImage2D (GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); |
| gl.texParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| gl.texParameterfv (GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, &borderColor[0]); |
| gl.texParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); |
| gl.texParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); |
| gl.texParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, -1000.0f); |
| gl.texParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 1000.0f); |
| gl.texParameteri (GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1000); |
| gl.texParameterf (GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, 0.0f); |
| gl.texParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); |
| gl.texParameteri (GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); |
| |
| if (contextSupports(type, ApiType::core(3,3))) |
| { |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE); |
| gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); |
| } |
| |
| // Reset cube map texture. |
| gl.bindTexture (GL_TEXTURE_CUBE_MAP, 0); |
| gl.texImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texImage2D (GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texImage2D (GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texImage2D (GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); |
| gl.texParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| gl.texParameterfv (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BORDER_COLOR, &borderColor[0]); |
| gl.texParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT); |
| gl.texParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT); |
| gl.texParameterf (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_LOD, -1000.0f); |
| gl.texParameterf (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LOD, 1000.0f); |
| gl.texParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 1000); |
| gl.texParameterf (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_LOD_BIAS, 0.0f); |
| gl.texParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_NONE); |
| gl.texParameteri (GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); |
| |
| if (contextSupports(type, ApiType::core(3,3))) |
| { |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_R, GL_RED); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_G, GL_GREEN); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_B, GL_BLUE); |
| gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); |
| } |
| |
| // Reset 1D array texture. |
| gl.bindTexture (GL_TEXTURE_1D_ARRAY, 0); |
| gl.texImage2D (GL_TEXTURE_1D_ARRAY, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texParameteri (GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); |
| gl.texParameteri (GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| gl.texParameterfv (GL_TEXTURE_1D_ARRAY, GL_TEXTURE_BORDER_COLOR, &borderColor[0]); |
| gl.texParameteri (GL_TEXTURE_1D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT); |
| gl.texParameterf (GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MIN_LOD, -1000.0f); |
| gl.texParameterf (GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAX_LOD, 1000.0f); |
| gl.texParameteri (GL_TEXTURE_1D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri (GL_TEXTURE_1D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1000); |
| gl.texParameterf (GL_TEXTURE_1D_ARRAY, GL_TEXTURE_LOD_BIAS, 0.0f); |
| gl.texParameteri (GL_TEXTURE_1D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_NONE); |
| gl.texParameteri (GL_TEXTURE_1D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); |
| |
| if (contextSupports(type, ApiType::core(3,3))) |
| { |
| gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_R, GL_RED); |
| gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_G, GL_GREEN); |
| gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_B, GL_BLUE); |
| gl.texParameteri(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); |
| } |
| |
| // Reset 2D array texture. |
| gl.bindTexture (GL_TEXTURE_2D_ARRAY, 0); |
| gl.texImage3D (GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texParameteri (GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); |
| gl.texParameteri (GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| gl.texParameterfv (GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BORDER_COLOR, &borderColor[0]); |
| gl.texParameteri (GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT); |
| gl.texParameteri (GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT); |
| gl.texParameterf (GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_LOD, -1000.0f); |
| gl.texParameterf (GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LOD, 1000.0f); |
| gl.texParameteri (GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri (GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1000); |
| gl.texParameterf (GL_TEXTURE_2D_ARRAY, GL_TEXTURE_LOD_BIAS, 0.0f); |
| gl.texParameteri (GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_MODE, GL_NONE); |
| gl.texParameteri (GL_TEXTURE_2D_ARRAY, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); |
| |
| if (contextSupports(type, ApiType::core(3,3))) |
| { |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_R, GL_RED); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_G, GL_GREEN); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_B, GL_BLUE); |
| gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); |
| } |
| |
| // Reset 3D texture. |
| gl.bindTexture (GL_TEXTURE_3D, 0); |
| gl.texImage3D (GL_TEXTURE_3D, 0, GL_RGBA, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texParameteri (GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); |
| gl.texParameteri (GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| gl.texParameterfv (GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, &borderColor[0]); |
| gl.texParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT); |
| gl.texParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT); |
| gl.texParameteri (GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT); |
| gl.texParameterf (GL_TEXTURE_3D, GL_TEXTURE_MIN_LOD, -1000.0f); |
| gl.texParameterf (GL_TEXTURE_3D, GL_TEXTURE_MAX_LOD, 1000.0f); |
| gl.texParameteri (GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri (GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1000); |
| gl.texParameterf (GL_TEXTURE_3D, GL_TEXTURE_LOD_BIAS, 0.0f); |
| gl.texParameteri (GL_TEXTURE_3D, GL_TEXTURE_COMPARE_MODE, GL_NONE); |
| gl.texParameteri (GL_TEXTURE_3D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); |
| |
| if (contextSupports(type, ApiType::core(3,3))) |
| { |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_R, GL_RED); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_G, GL_GREEN); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_B, GL_BLUE); |
| gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); |
| } |
| |
| if (contextSupports(type, ApiType::core(3,1))) |
| { |
| // Reset rectangle texture. |
| gl.bindTexture (GL_TEXTURE_RECTANGLE, 0); |
| gl.texImage2D (GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| gl.texParameteri (GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| gl.texParameteri (GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| gl.texParameterfv (GL_TEXTURE_RECTANGLE, GL_TEXTURE_BORDER_COLOR, &borderColor[0]); |
| gl.texParameteri (GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| gl.texParameteri (GL_TEXTURE_RECTANGLE, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| gl.texParameteri (GL_TEXTURE_RECTANGLE, GL_TEXTURE_BASE_LEVEL, 0); |
| gl.texParameteri (GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAX_LEVEL, 1000); |
| gl.texParameteri (GL_TEXTURE_RECTANGLE, GL_TEXTURE_COMPARE_MODE, GL_NONE); |
| gl.texParameteri (GL_TEXTURE_RECTANGLE, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); |
| // \todo [2013-06-17 pyry] Drivers don't accept GL_MIN_LOD, GL_MAX_LOD for rectangle textures. Is that okay? |
| |
| if (contextSupports(type, ApiType::core(3,3))) |
| { |
| gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_R, GL_RED); |
| gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_G, GL_GREEN); |
| gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_B, GL_BLUE); |
| gl.texParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_SWIZZLE_A, GL_ALPHA); |
| } |
| |
| // Reset buffer texture. |
| gl.bindTexture (GL_TEXTURE_BUFFER, 0); |
| gl.texBuffer (GL_TEXTURE_BUFFER, GL_R8, 0); |
| // \todo [2013-05-04 pyry] Which parameters apply to buffer textures? |
| } |
| |
| if (contextSupports(type, ApiType::core(3,2))) |
| { |
| // Reset 2D multisample texture. |
| gl.bindTexture (GL_TEXTURE_2D_MULTISAMPLE, 0); |
| gl.texImage2DMultisample (GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 0, 0, GL_TRUE); |
| |
| // Reset 2D multisample array texture. |
| gl.bindTexture (GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0); |
| gl.texImage3DMultisample (GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 1, GL_RGBA8, 0, 0, 0, GL_TRUE); |
| } |
| } |
| |
| gl.activeTexture(GL_TEXTURE0); |
| |
| if (contextSupports(type, ApiType::core(3,3))) |
| { |
| for (int ndx = 0; ndx < numTexUnits; ndx++) |
| gl.bindSampler(ndx, 0); |
| |
| gl.disable(GL_TEXTURE_CUBE_MAP_SEAMLESS); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state reset failed"); |
| } |
| |
| // Pixel operations. |
| { |
| const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget(); |
| |
| gl.disable (GL_SCISSOR_TEST); |
| gl.scissor (0, 0, renderTarget.getWidth(), renderTarget.getHeight()); |
| |
| gl.disable (GL_STENCIL_TEST); |
| gl.stencilFunc (GL_ALWAYS, 0, ~0u); |
| gl.stencilOp (GL_KEEP, GL_KEEP, GL_KEEP); |
| |
| gl.disable (GL_DEPTH_TEST); |
| gl.depthFunc (GL_LESS); |
| |
| gl.disable (GL_BLEND); |
| gl.blendFunc (GL_ONE, GL_ZERO); |
| gl.blendEquation(GL_FUNC_ADD); |
| gl.blendColor (0.0f, 0.0f, 0.0f, 0.0f); |
| |
| gl.disable (GL_FRAMEBUFFER_SRGB); |
| gl.enable (GL_DITHER); |
| |
| gl.disable (GL_COLOR_LOGIC_OP); |
| gl.logicOp (GL_COPY); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel operation state reset failed"); |
| } |
| |
| // Framebuffer control. |
| { |
| gl.colorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
| gl.depthMask (GL_TRUE); |
| gl.stencilMask (~0u); |
| |
| gl.clearColor (0.0f, 0.0f, 0.0f, 0.0f); |
| gl.clearDepth (1.0); |
| gl.clearStencil (0); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer control state reset failed"); |
| } |
| |
| // Framebuffer state. |
| { |
| // \todo [2013-04-05 pyry] Single-buffered rendering: use GL_FRONT |
| deUint32 framebuffer = renderCtx.getDefaultFramebuffer(); |
| deUint32 drawReadBuffer = framebuffer == 0 ? GL_BACK : GL_COLOR_ATTACHMENT0; |
| |
| gl.bindFramebuffer (GL_FRAMEBUFFER, renderCtx.getDefaultFramebuffer()); |
| gl.drawBuffer (drawReadBuffer); |
| gl.readBuffer (drawReadBuffer); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Framebuffer state reset failed"); |
| } |
| |
| // Renderbuffer state. |
| { |
| gl.bindRenderbuffer(GL_RENDERBUFFER, 0); |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Renderbuffer state reset failed"); |
| } |
| |
| // Pixel transfer state. |
| { |
| gl.pixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE); |
| gl.pixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE); |
| gl.pixelStorei (GL_UNPACK_IMAGE_HEIGHT, 0); |
| gl.pixelStorei (GL_UNPACK_SKIP_IMAGES, 0); |
| gl.pixelStorei (GL_UNPACK_ROW_LENGTH, 0); |
| gl.pixelStorei (GL_UNPACK_SKIP_ROWS, 0); |
| gl.pixelStorei (GL_UNPACK_SKIP_PIXELS, 0); |
| gl.pixelStorei (GL_UNPACK_ALIGNMENT, 4); |
| |
| gl.pixelStorei (GL_PACK_SWAP_BYTES, GL_FALSE); |
| gl.pixelStorei (GL_PACK_LSB_FIRST, GL_FALSE); |
| gl.pixelStorei (GL_PACK_IMAGE_HEIGHT, 0); |
| gl.pixelStorei (GL_PACK_SKIP_IMAGES, 0); |
| gl.pixelStorei (GL_PACK_ROW_LENGTH, 0); |
| gl.pixelStorei (GL_PACK_SKIP_ROWS, 0); |
| gl.pixelStorei (GL_PACK_SKIP_PIXELS, 0); |
| gl.pixelStorei (GL_PACK_ALIGNMENT, 4); |
| |
| gl.bindBuffer (GL_PIXEL_PACK_BUFFER, 0); |
| gl.bindBuffer (GL_PIXEL_UNPACK_BUFFER, 0); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Pixel transfer state reset failed"); |
| } |
| |
| // Program object state. |
| { |
| gl.useProgram(0); |
| |
| if (contextSupports(type, ApiType::core(3,1))) |
| { |
| int maxUniformBufferBindings = 0; |
| gl.getIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings); |
| |
| gl.bindBuffer(GL_UNIFORM_BUFFER, 0); |
| |
| for (int ndx = 0; ndx < maxUniformBufferBindings; ndx++) |
| gl.bindBufferBase(GL_UNIFORM_BUFFER, ndx, 0); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Program object state reset failed"); |
| } |
| |
| // Vertex shader state. |
| { |
| int numVertexAttribArrays = 0; |
| gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribArrays); |
| |
| for (int ndx = 0; ndx < numVertexAttribArrays; ndx++) |
| gl.vertexAttrib4f(ndx, 0.0f, 0.0f, 0.0f, 1.0f); |
| |
| gl.disable(GL_VERTEX_PROGRAM_POINT_SIZE); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex shader state reset failed"); |
| } |
| |
| // Transform feedback state. |
| { |
| int numTransformFeedbackSeparateAttribs = 0; |
| gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &numTransformFeedbackSeparateAttribs); |
| |
| if (contextSupports(type, ApiType::core(4,0))) |
| { |
| glw::GLboolean transformFeedbackActive = 0; |
| gl.getBooleanv(GL_TRANSFORM_FEEDBACK_ACTIVE, &transformFeedbackActive); |
| |
| if (transformFeedbackActive) |
| gl.endTransformFeedback(); |
| } |
| |
| gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); |
| |
| for (int ndx = 0; ndx < numTransformFeedbackSeparateAttribs; ndx++) |
| gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, ndx, 0); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Transform feedback state reset failed"); |
| } |
| |
| // Asynchronous query state. |
| { |
| deUint32 queryTargets[8]; |
| int numTargets = 0; |
| |
| queryTargets[numTargets++] = GL_PRIMITIVES_GENERATED; |
| queryTargets[numTargets++] = GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN; |
| queryTargets[numTargets++] = GL_SAMPLES_PASSED; |
| |
| DE_ASSERT(numTargets <= DE_LENGTH_OF_ARRAY(queryTargets)); |
| |
| for (int i = 0; i < numTargets; i++) |
| { |
| int queryActive = 0; |
| gl.getQueryiv(queryTargets[i], GL_CURRENT_QUERY, &queryActive); |
| |
| if (queryActive != 0) |
| gl.endQuery(queryTargets[i]); |
| } |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Asynchronous query state reset failed"); |
| } |
| |
| // Hints. |
| { |
| gl.hint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); |
| gl.hint(GL_POLYGON_SMOOTH_HINT, GL_DONT_CARE); |
| gl.hint(GL_TEXTURE_COMPRESSION_HINT, GL_DONT_CARE); |
| gl.hint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, GL_DONT_CARE); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Hints reset failed"); |
| } |
| |
| // Buffer copy state. |
| if (contextSupports(type, ApiType::core(3,1))) |
| { |
| gl.bindBuffer(GL_COPY_READ_BUFFER, 0); |
| gl.bindBuffer(GL_COPY_WRITE_BUFFER, 0); |
| |
| GLU_EXPECT_NO_ERROR(gl.getError(), "Buffer copy state reset failed"); |
| } |
| |
| // Debug state |
| if (ctxInfo.isExtensionSupported("GL_KHR_debug")) |
| { |
| const bool entrypointsPresent = gl.debugMessageControl != DE_NULL && |
| gl.debugMessageCallback != DE_NULL; |
| |
| // some drivers advertise GL_KHR_debug but give out null pointers. Silently ignore. |
| if (entrypointsPresent) |
| { |
| gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, DE_NULL, true); |
| gl.debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, DE_NULL, false); |
| gl.debugMessageCallback(DE_NULL, DE_NULL); |
| |
| if (type.getFlags() & glu::CONTEXT_DEBUG) |
| gl.enable(GL_DEBUG_OUTPUT); |
| else |
| gl.disable(GL_DEBUG_OUTPUT); |
| } |
| } |
| } |
| |
| void resetState (const RenderContext& renderCtx, const ContextInfo& ctxInfo) |
| { |
| if (isContextTypeES(renderCtx.getType())) |
| resetStateES(renderCtx, ctxInfo); |
| else if (isContextTypeGLCore(renderCtx.getType())) |
| resetStateGLCore(renderCtx, ctxInfo); |
| else |
| throw tcu::InternalError("State reset requested for unsupported context type"); |
| } |
| |
| } // glu |