static void set_viewport_no_notify(struct gl_context *ctx, unsigned idx, GLfloat x, GLfloat y, GLfloat width, GLfloat height) { /* clamp width and height to the implementation dependent range */ width = MIN2(width, (GLfloat) ctx->Const.MaxViewportWidth); height = MIN2(height, (GLfloat) ctx->Const.MaxViewportHeight); /* The GL_ARB_viewport_array spec says: * * "The location of the viewport's bottom-left corner, given by (x,y), * are clamped to be within the implementation-dependent viewport * bounds range. The viewport bounds range [min, max] tuple may be * determined by calling GetFloatv with the symbolic constant * VIEWPORT_BOUNDS_RANGE (see section 6.1)." */ if (ctx->Extensions.ARB_viewport_array || (ctx->Extensions.OES_viewport_array && _mesa_is_gles31(ctx))) { x = CLAMP(x, ctx->Const.ViewportBounds.Min, ctx->Const.ViewportBounds.Max); y = CLAMP(y, ctx->Const.ViewportBounds.Min, ctx->Const.ViewportBounds.Max); } if (ctx->ViewportArray[idx].X == x && ctx->ViewportArray[idx].Width == width && ctx->ViewportArray[idx].Y == y && ctx->ViewportArray[idx].Height == height) return; FLUSH_VERTICES(ctx, ctx->DriverFlags.NewViewport ? 0 : _NEW_VIEWPORT); ctx->NewDriverState |= ctx->DriverFlags.NewViewport; ctx->ViewportArray[idx].X = x; ctx->ViewportArray[idx].Width = width; ctx->ViewportArray[idx].Y = y; ctx->ViewportArray[idx].Height = height; }
static GLboolean valid_draw_indirect(struct gl_context *ctx, GLenum mode, const GLvoid *indirect, GLsizei size, const char *name) { const uint64_t end = (uint64_t) (uintptr_t) indirect + size; /* OpenGL ES 3.1 spec. section 10.5: * * "DrawArraysIndirect requires that all data sourced for the * command, including the DrawArraysIndirectCommand * structure, be in buffer objects, and may not be called when * the default vertex array object is bound." */ if (ctx->Array.VAO == ctx->Array.DefaultVAO) { _mesa_error(ctx, GL_INVALID_OPERATION, "(no VAO bound)"); return GL_FALSE; } /* From OpenGL ES 3.1 spec. section 10.5: * "An INVALID_OPERATION error is generated if zero is bound to * VERTEX_ARRAY_BINDING, DRAW_INDIRECT_BUFFER or to any enabled * vertex array." * * Here we check that for each enabled vertex array we have a vertex * buffer bound. */ if (_mesa_is_gles31(ctx) && ctx->Array.VAO->_Enabled != ctx->Array.VAO->VertexAttribBufferMask) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(No VBO bound)", name); return GL_FALSE; } if (!_mesa_valid_prim_mode(ctx, mode, name)) return GL_FALSE; /* OpenGL ES 3.1 specification, section 10.5: * * "An INVALID_OPERATION error is generated if * transform feedback is active and not paused." */ if (_mesa_is_gles31(ctx) && !ctx->Extensions.OES_geometry_shader && _mesa_is_xfb_active_and_unpaused(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(TransformFeedback is active and not paused)", name); } /* From OpenGL version 4.4. section 10.5 * and OpenGL ES 3.1, section 10.6: * * "An INVALID_VALUE error is generated if indirect is not a * multiple of the size, in basic machine units, of uint." */ if ((GLsizeiptr)indirect & (sizeof(GLuint) - 1)) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(indirect is not aligned)", name); return GL_FALSE; } if (!_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s: no buffer bound to DRAW_INDIRECT_BUFFER", name); return GL_FALSE; } if (_mesa_check_disallowed_mapping(ctx->DrawIndirectBuffer)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(DRAW_INDIRECT_BUFFER is mapped)", name); return GL_FALSE; } /* From the ARB_draw_indirect specification: * "An INVALID_OPERATION error is generated if the commands source data * beyond the end of the buffer object [...]" */ if (ctx->DrawIndirectBuffer->Size < end) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(DRAW_INDIRECT_BUFFER too small)", name); return GL_FALSE; } if (!check_valid_to_render(ctx, name)) return GL_FALSE; return GL_TRUE; }
/* Handles the cases where either ARB_internalformat_query or * ARB_internalformat_query2 have to return an error. */ static bool _legal_parameters(struct gl_context *ctx, GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params) { bool query2 = _mesa_has_ARB_internalformat_query2(ctx); /* The ARB_internalformat_query2 spec says: * * "The INVALID_ENUM error is generated if the <target> parameter to * GetInternalformati*v is not one of the targets listed in Table 6.xx. */ switch(target){ case GL_TEXTURE_1D: case GL_TEXTURE_1D_ARRAY: case GL_TEXTURE_2D: case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_3D: case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP_ARRAY: case GL_TEXTURE_RECTANGLE: case GL_TEXTURE_BUFFER: if (!query2) { /* The ARB_internalformat_query spec says: * * "If the <target> parameter to GetInternalformativ is not one of * TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY * or RENDERBUFFER then an INVALID_ENUM error is generated. */ _mesa_error(ctx, GL_INVALID_ENUM, "glGetInternalformativ(target=%s)", _mesa_enum_to_string(target)); return false; } break; case GL_RENDERBUFFER: break; case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: /* The non-existence of ARB_texture_multisample is treated in * ARB_internalformat_query implementation like an error. */ if (!query2 && !(_mesa_has_ARB_texture_multisample(ctx) || _mesa_is_gles31(ctx))) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetInternalformativ(target=%s)", _mesa_enum_to_string(target)); return false; } break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetInternalformativ(target=%s)", _mesa_enum_to_string(target)); return false; } /* The ARB_internalformat_query2 spec says: * * "The INVALID_ENUM error is generated if the <pname> parameter is * not one of the listed possibilities. */ switch(pname){ case GL_SAMPLES: case GL_NUM_SAMPLE_COUNTS: break; case GL_SRGB_DECODE_ARB: /* The ARB_internalformat_query2 spec says: * * "If ARB_texture_sRGB_decode or EXT_texture_sRGB_decode or * equivalent functionality is not supported, queries for the * SRGB_DECODE_ARB <pname> set the INVALID_ENUM error. */ if (!_mesa_has_EXT_texture_sRGB_decode(ctx)) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetInternalformativ(pname=%s)", _mesa_enum_to_string(pname)); return false; } /* fallthrough */ case GL_INTERNALFORMAT_SUPPORTED: case GL_INTERNALFORMAT_PREFERRED: case GL_INTERNALFORMAT_RED_SIZE: case GL_INTERNALFORMAT_GREEN_SIZE: case GL_INTERNALFORMAT_BLUE_SIZE: case GL_INTERNALFORMAT_ALPHA_SIZE: case GL_INTERNALFORMAT_DEPTH_SIZE: case GL_INTERNALFORMAT_STENCIL_SIZE: case GL_INTERNALFORMAT_SHARED_SIZE: case GL_INTERNALFORMAT_RED_TYPE: case GL_INTERNALFORMAT_GREEN_TYPE: case GL_INTERNALFORMAT_BLUE_TYPE: case GL_INTERNALFORMAT_ALPHA_TYPE: case GL_INTERNALFORMAT_DEPTH_TYPE: case GL_INTERNALFORMAT_STENCIL_TYPE: case GL_MAX_WIDTH: case GL_MAX_HEIGHT: case GL_MAX_DEPTH: case GL_MAX_LAYERS: case GL_MAX_COMBINED_DIMENSIONS: case GL_COLOR_COMPONENTS: case GL_DEPTH_COMPONENTS: case GL_STENCIL_COMPONENTS: case GL_COLOR_RENDERABLE: case GL_DEPTH_RENDERABLE: case GL_STENCIL_RENDERABLE: case GL_FRAMEBUFFER_RENDERABLE: case GL_FRAMEBUFFER_RENDERABLE_LAYERED: case GL_FRAMEBUFFER_BLEND: case GL_READ_PIXELS: case GL_READ_PIXELS_FORMAT: case GL_READ_PIXELS_TYPE: case GL_TEXTURE_IMAGE_FORMAT: case GL_TEXTURE_IMAGE_TYPE: case GL_GET_TEXTURE_IMAGE_FORMAT: case GL_GET_TEXTURE_IMAGE_TYPE: case GL_MIPMAP: case GL_MANUAL_GENERATE_MIPMAP: case GL_AUTO_GENERATE_MIPMAP: case GL_COLOR_ENCODING: case GL_SRGB_READ: case GL_SRGB_WRITE: case GL_FILTER: case GL_VERTEX_TEXTURE: case GL_TESS_CONTROL_TEXTURE: case GL_TESS_EVALUATION_TEXTURE: case GL_GEOMETRY_TEXTURE: case GL_FRAGMENT_TEXTURE: case GL_COMPUTE_TEXTURE: case GL_TEXTURE_SHADOW: case GL_TEXTURE_GATHER: case GL_TEXTURE_GATHER_SHADOW: case GL_SHADER_IMAGE_LOAD: case GL_SHADER_IMAGE_STORE: case GL_SHADER_IMAGE_ATOMIC: case GL_IMAGE_TEXEL_SIZE: case GL_IMAGE_COMPATIBILITY_CLASS: case GL_IMAGE_PIXEL_FORMAT: case GL_IMAGE_PIXEL_TYPE: case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST: case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST: case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE: case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE: case GL_TEXTURE_COMPRESSED: case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH: case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT: case GL_TEXTURE_COMPRESSED_BLOCK_SIZE: case GL_CLEAR_BUFFER: case GL_TEXTURE_VIEW: case GL_VIEW_COMPATIBILITY_CLASS: /* The ARB_internalformat_query spec says: * * "If the <pname> parameter to GetInternalformativ is not SAMPLES * or NUM_SAMPLE_COUNTS, then an INVALID_ENUM error is generated." */ if (!query2) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetInternalformativ(pname=%s)", _mesa_enum_to_string(pname)); return false; } break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetInternalformativ(pname=%s)", _mesa_enum_to_string(pname)); return false; } /* The ARB_internalformat_query spec says: * * "If the <bufSize> parameter to GetInternalformativ is negative, then * an INVALID_VALUE error is generated." * * Nothing is said in ARB_internalformat_query2 but we assume the same. */ if (bufSize < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetInternalformativ(target=%s)", _mesa_enum_to_string(target)); return false; } /* The ARB_internalformat_query spec says: * * "If the <internalformat> parameter to GetInternalformativ is not * color-, depth- or stencil-renderable, then an INVALID_ENUM error is * generated." */ if (!query2 && !_is_renderable(ctx, internalformat)) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetInternalformativ(internalformat=%s)", _mesa_enum_to_string(internalformat)); return false; } return true; }
static bool _is_target_supported(struct gl_context *ctx, GLenum target) { /* The ARB_internalformat_query2 spec says: * * "if a particular type of <target> is not supported by the * implementation the "unsupported" answer should be given. * This is not an error." * * For OpenGL ES, queries can only be used with GL_RENDERBUFFER or MS. */ switch(target){ case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_3D: if (!_mesa_is_desktop_gl(ctx)) return false; break; case GL_TEXTURE_1D_ARRAY: if (!_mesa_has_EXT_texture_array(ctx)) return false; break; case GL_TEXTURE_2D_ARRAY: if (!_mesa_has_EXT_texture_array(ctx)) return false; break; case GL_TEXTURE_CUBE_MAP: if (ctx->API != API_OPENGL_CORE && !_mesa_has_ARB_texture_cube_map(ctx)) return false; break; case GL_TEXTURE_CUBE_MAP_ARRAY: if (!_mesa_has_ARB_texture_cube_map_array(ctx)) return false; break; case GL_TEXTURE_RECTANGLE: if (!_mesa_has_ARB_texture_rectangle(ctx)) return false; break; case GL_TEXTURE_BUFFER: if (!_mesa_has_ARB_texture_buffer_object(ctx)) return false; break; case GL_RENDERBUFFER: if (!(_mesa_has_ARB_framebuffer_object(ctx) || _mesa_is_gles3(ctx))) return false; break; case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: if (!(_mesa_has_ARB_texture_multisample(ctx) || _mesa_is_gles31(ctx))) return false; break; default: unreachable("invalid target"); } return true; }