void * GLAPIENTRY _mesa_MapBufferARB(GLenum target, GLenum access) { GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object * bufObj; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL); switch (access) { case GL_READ_ONLY_ARB: case GL_WRITE_ONLY_ARB: case GL_READ_WRITE_ARB: /* OK */ break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferARB(access)"); return NULL; } bufObj = get_buffer(ctx, target); if (!bufObj) { _mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferARB(target)" ); return NULL; } if (bufObj->Name == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB" ); return NULL; } if (bufObj->Pointer) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(already mapped)"); return NULL; } ASSERT(ctx->Driver.MapBuffer); bufObj->Pointer = ctx->Driver.MapBuffer( ctx, target, access, bufObj ); if (!bufObj->Pointer) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(access)"); } bufObj->Access = access; return bufObj->Pointer; }
GLboolean _mesa_validate_DrawArraysInstanced(struct gl_context *ctx, GLenum mode, GLint first, GLsizei count, GLsizei numInstances) { ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); if (count <= 0) { if (count < 0) _mesa_error(ctx, GL_INVALID_VALUE, "glDrawArraysInstanced(count=%d)", count); return GL_FALSE; } if (mode > GL_TRIANGLE_STRIP_ADJACENCY_ARB) { _mesa_error(ctx, GL_INVALID_ENUM, "glDrawArraysInstanced(mode=0x%x)", mode); return GL_FALSE; } if (numInstances <= 0) { if (numInstances < 0) _mesa_error(ctx, GL_INVALID_VALUE, "glDrawArraysInstanced(numInstances=%d)", numInstances); return GL_FALSE; } if (!check_valid_to_render(ctx, "glDrawArraysInstanced(invalid to render)")) return GL_FALSE; if (ctx->CompileFlag) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawArraysInstanced(display list"); return GL_FALSE; } if (ctx->Const.CheckArrayBounds) { if (first + count > (GLint) ctx->Array.ArrayObj->_MaxElement) return GL_FALSE; } return GL_TRUE; }
GLboolean GLAPIENTRY _mesa_IsQuery(GLuint id) { struct gl_query_object *q; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glIsQuery(%u)\n", id); if (id == 0) return GL_FALSE; q = _mesa_lookup_query_object(ctx, id); if (q == NULL) return GL_FALSE; return q->EverBound; }
/** * Determine if a set of programs is resident in hardware. * \note Not compiled into display lists. * \note Called from the GL API dispatcher. */ GLboolean GLAPIENTRY _mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids, GLboolean *residences) { GLint i, j; GLboolean allResident = GL_TRUE; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); if (n < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV(n)"); return GL_FALSE; } for (i = 0; i < n; i++) { const struct gl_program *prog; if (ids[i] == 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV"); return GL_FALSE; } prog = _mesa_lookup_program(ctx, ids[i]); if (!prog) { _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV"); return GL_FALSE; } if (prog->Resident) { if (!allResident) residences[i] = GL_TRUE; } else { if (allResident) { allResident = GL_FALSE; for (j = 0; j < i; j++) residences[j] = GL_TRUE; } residences[i] = GL_FALSE; } } return allResident; }
/** * GL3 */ const GLubyte * glGetStringi(GLenum name, GLuint index) { GET_CURRENT_CONTEXT(ctx); if (!ctx) return NULL; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL); switch (name) { // case GL_EXTENSIONS: // if (index >= _mesa_get_extension_count(ctx)) { // _mesa_error(ctx, GL_INVALID_VALUE, "glGetStringi(index=%u)", index); // return (const GLubyte *) 0; // } // return _mesa_get_enabled_extension(ctx, index); default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetStringi"); return (const GLubyte *) 0; } }
GLenum GLAPIENTRY _mesa_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { GET_CURRENT_CONTEXT(ctx); struct gl_sync_object *syncObj; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_WAIT_FAILED); if ((flags & ~GL_SYNC_FLUSH_COMMANDS_BIT) != 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glClientWaitSync(flags=0x%x)", flags); return GL_WAIT_FAILED; } syncObj = _mesa_get_and_ref_sync(ctx, sync, true); if (!syncObj) { _mesa_error(ctx, GL_INVALID_VALUE, "glClientWaitSync (not a valid sync object)"); return GL_WAIT_FAILED; } return client_wait_sync(ctx, syncObj, flags, timeout); }
GLenum GLAPIENTRY _mesa_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { GET_CURRENT_CONTEXT(ctx); struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync; GLenum ret; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_WAIT_FAILED); if (!_mesa_validate_sync(syncObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glClientWaitSync"); return GL_WAIT_FAILED; } if ((flags & ~GL_SYNC_FLUSH_COMMANDS_BIT) != 0) { _mesa_error(ctx, GL_INVALID_ENUM, "glClientWaitSync(flags=0x%x)", flags); return GL_WAIT_FAILED; } _mesa_ref_sync_object(ctx, syncObj); /* From the GL_ARB_sync spec: * * ClientWaitSync returns one of four status values. A return value of * ALREADY_SIGNALED indicates that <sync> was signaled at the time * ClientWaitSync was called. ALREADY_SIGNALED will always be returned * if <sync> was signaled, even if the value of <timeout> is zero. */ ctx->Driver.CheckSync(ctx, syncObj); if (syncObj->StatusFlag) { ret = GL_ALREADY_SIGNALED; } else { ctx->Driver.ClientWaitSync(ctx, syncObj, flags, timeout); ret = syncObj->StatusFlag ? GL_CONDITION_SATISFIED : GL_TIMEOUT_EXPIRED; } _mesa_unref_sync_object(ctx, syncObj); return ret; }
/** * See if textures are loaded in texture memory. * * \param n number of textures to query. * \param texName array with the texture names. * \param residences array which will hold the residence status. * * \return GL_TRUE if all textures are resident and \p residences is left unchanged, * * Note: we assume all textures are always resident */ GLboolean GLAPIENTRY _mesa_AreTexturesResident(GLsizei n, const GLuint *texName, GLboolean *residences) { GET_CURRENT_CONTEXT(ctx); GLboolean allResident = GL_TRUE; GLint i; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) _mesa_debug(ctx, "glAreTexturesResident %d\n", n); if (n < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)"); return GL_FALSE; } if (!texName || !residences) return GL_FALSE; /* We only do error checking on the texture names */ for (i = 0; i < n; i++) { struct gl_texture_object *t; if (texName[i] == 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident"); return GL_FALSE; } t = _mesa_lookup_texture(ctx, texName[i]); if (!t) { _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident"); return GL_FALSE; } } return allResident; }
/** * See GL_ARB_map_buffer_range spec */ void * GLAPIENTRY _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) { GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL); if (!ctx->Extensions.ARB_map_buffer_range) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferRange(extension not supported)"); return NULL; } if (offset < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glMapBufferRange(offset = %ld)", offset); return NULL; } if (length < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glMapBufferRange(length = %ld)", length); return NULL; } if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferRange(access indicates neither read or write)"); return NULL; } if (access & GL_MAP_READ_BIT) { if ((access & GL_MAP_INVALIDATE_RANGE_BIT) || (access & GL_MAP_INVALIDATE_BUFFER_BIT) || (access & GL_MAP_UNSYNCHRONIZED_BIT)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferRange(invalid access flags)"); return NULL; } } if ((access & GL_MAP_FLUSH_EXPLICIT_BIT) && ((access & GL_MAP_WRITE_BIT) == 0)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferRange(invalid access flags)"); return NULL; } bufObj = get_buffer(ctx, target); if (!bufObj || bufObj->Name == 0) { _mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferRange(target = 0x%x)", target); return NULL; } if (offset + length > bufObj->Size) { _mesa_error(ctx, GL_INVALID_VALUE, "glMapBufferRange(offset + length > size)"); return NULL; } if (bufObj->Pointer) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferRange(buffer already mapped)"); return NULL; } ASSERT(ctx->Driver.MapBufferRange); bufObj->Pointer = ctx->Driver.MapBufferRange(ctx, target, offset, length, access, bufObj); bufObj->Offset = offset; bufObj->Length = length; bufObj->AccessFlags = access; return bufObj->Pointer; }
GLboolean GLAPIENTRY _mesa_UnmapBufferARB(GLenum target) { GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj; GLboolean status = GL_TRUE; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); bufObj = get_buffer(ctx, target); if (!bufObj) { _mesa_error(ctx, GL_INVALID_ENUM, "glUnmapBufferARB(target)" ); return GL_FALSE; } if (bufObj->Name == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB" ); return GL_FALSE; } if (!bufObj->Pointer) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB"); return GL_FALSE; } #ifdef BOUNDS_CHECK if (bufObj->Access != GL_READ_ONLY_ARB) { GLubyte *buf = (GLubyte *) bufObj->Pointer; GLuint i; /* check that last 100 bytes are still = magic value */ for (i = 0; i < 100; i++) { GLuint pos = bufObj->Size - i - 1; if (buf[pos] != 123) { _mesa_warning(ctx, "Out of bounds buffer object write detected" " at position %d (value = %u)\n", pos, buf[pos]); } } } #endif #ifdef VBO_DEBUG if (bufObj->AccessFlags & GL_MAP_WRITE_BIT) { GLuint i, unchanged = 0; GLubyte *b = (GLubyte *) bufObj->Pointer; GLint pos = -1; /* check which bytes changed */ for (i = 0; i < bufObj->Size - 1; i++) { if (b[i] == (i & 0xff) && b[i+1] == ((i+1) & 0xff)) { unchanged++; if (pos == -1) pos = i; } } if (unchanged) { _mesa_printf("glUnmapBufferARB(%u): %u of %ld unchanged, starting at %d\n", bufObj->Name, unchanged, bufObj->Size, pos); } } #endif status = ctx->Driver.UnmapBuffer( ctx, target, bufObj ); bufObj->AccessFlags = DEFAULT_ACCESS; bufObj->Pointer = NULL; bufObj->Offset = 0; bufObj->Length = 0; return status; }
void * GLAPIENTRY _mesa_MapBufferARB(GLenum target, GLenum access) { GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object * bufObj; GLbitfield accessFlags; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL); switch (access) { case GL_READ_ONLY_ARB: accessFlags = GL_MAP_READ_BIT; break; case GL_WRITE_ONLY_ARB: accessFlags = GL_MAP_WRITE_BIT; break; case GL_READ_WRITE_ARB: accessFlags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferARB(access)"); return NULL; } bufObj = get_buffer(ctx, target); if (!bufObj) { _mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferARB(target)" ); return NULL; } if (bufObj->Name == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(buffer 0)" ); return NULL; } if (bufObj->Pointer) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(already mapped)"); return NULL; } ASSERT(ctx->Driver.MapBuffer); bufObj->Pointer = ctx->Driver.MapBuffer( ctx, target, access, bufObj ); if (!bufObj->Pointer) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(access)"); } bufObj->AccessFlags = accessFlags; bufObj->Offset = 0; bufObj->Length = bufObj->Size; if (access == GL_WRITE_ONLY_ARB || access == GL_READ_WRITE_ARB) bufObj->Written = GL_TRUE; #ifdef VBO_DEBUG _mesa_printf("glMapBufferARB(%u, sz %ld, access 0x%x)\n", bufObj->Name, bufObj->Size, access); if (access == GL_WRITE_ONLY_ARB) { GLuint i; GLubyte *b = (GLubyte *) bufObj->Pointer; for (i = 0; i < bufObj->Size; i++) b[i] = i & 0xff; } #endif #ifdef BOUNDS_CHECK { GLubyte *buf = (GLubyte *) bufObj->Pointer; GLuint i; /* buffer is 100 bytes larger than requested, fill with magic value */ for (i = 0; i < 100; i++) { buf[bufObj->Size - i - 1] = 123; } } #endif return bufObj->Pointer; }
void * GLAPIENTRY _mesa_MapBufferARB(GLenum target, GLenum access) { GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object * bufObj; GLbitfield accessFlags; void *map; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL); switch (access) { case GL_READ_ONLY_ARB: accessFlags = GL_MAP_READ_BIT; break; case GL_WRITE_ONLY_ARB: accessFlags = GL_MAP_WRITE_BIT; break; case GL_READ_WRITE_ARB: accessFlags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferARB(access)"); return NULL; } bufObj = get_buffer(ctx, "glMapBufferARB", target); if (!bufObj) return NULL; if (_mesa_bufferobj_mapped(bufObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(already mapped)"); return NULL; } if (!bufObj->Size) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBuffer(buffer size = 0)"); return NULL; } ASSERT(ctx->Driver.MapBufferRange); map = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size, accessFlags, bufObj); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(map failed)"); return NULL; } else { /* The driver callback should have set these fields. * This is important because other modules (like VBO) might call * the driver function directly. */ ASSERT(bufObj->Pointer == map); ASSERT(bufObj->Length == bufObj->Size); ASSERT(bufObj->Offset == 0); bufObj->AccessFlags = accessFlags; } if (access == GL_WRITE_ONLY_ARB || access == GL_READ_WRITE_ARB) bufObj->Written = GL_TRUE; #ifdef VBO_DEBUG printf("glMapBufferARB(%u, sz %ld, access 0x%x)\n", bufObj->Name, bufObj->Size, access); if (access == GL_WRITE_ONLY_ARB) { GLuint i; GLubyte *b = (GLubyte *) bufObj->Pointer; for (i = 0; i < bufObj->Size; i++) b[i] = i & 0xff; } #endif #ifdef BOUNDS_CHECK { GLubyte *buf = (GLubyte *) bufObj->Pointer; GLuint i; /* buffer is 100 bytes larger than requested, fill with magic value */ for (i = 0; i < 100; i++) { buf[bufObj->Size - i - 1] = 123; } } #endif return bufObj->Pointer; }
/** * Error checking for glDrawRangeElements(). Includes parameter checking * and VBO bounds checking. * \return GL_TRUE if OK to render, GL_FALSE if error found */ GLboolean _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) { ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); if (count <= 0) { if (count < 0) _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(count)" ); return GL_FALSE; } if (mode > GL_POLYGON) { _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(mode)" ); return GL_FALSE; } if (end < start) { _mesa_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements(end<start)"); return GL_FALSE; } if (type != GL_UNSIGNED_INT && type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT) { _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(type)" ); return GL_FALSE; } if (ctx->NewState) _mesa_update_state(ctx); if (!check_valid_to_render(ctx, "RangeElements")) return GL_FALSE; /* Vertex buffer object tests */ if (ctx->Array.ElementArrayBufferObj->Name) { /* use indices in the buffer object */ /* make sure count doesn't go outside buffer bounds */ if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) { _mesa_warning(ctx, "glDrawRangeElements index out of buffer bounds"); return GL_FALSE; } } else { /* not using a VBO */ if (!indices) return GL_FALSE; } if (ctx->Const.CheckArrayBounds) { GLuint max = max_buffer_index(ctx, count, type, indices, ctx->Array.ElementArrayBufferObj); if (max >= ctx->Array.ArrayObj->_MaxElement) { /* the max element is out of bounds of one or more enabled arrays */ return GL_FALSE; } } return GL_TRUE; }
/** * Return simple enable/disable state. * * \param cap state variable to query. * * Returns the state of the specified capability from the current GL context. * For the capabilities associated with extensions verifies that those * extensions are effectively present before reporting. */ GLboolean GLAPIENTRY _mesa_IsEnabled( GLenum cap ) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); switch (cap) { case GL_ALPHA_TEST: return ctx->Color.AlphaEnabled; case GL_AUTO_NORMAL: return ctx->Eval.AutoNormal; case GL_BLEND: return ctx->Color.BlendEnabled & 1; /* return state for buffer[0] */ case GL_CLIP_DISTANCE0: case GL_CLIP_DISTANCE1: case GL_CLIP_DISTANCE2: case GL_CLIP_DISTANCE3: case GL_CLIP_DISTANCE4: case GL_CLIP_DISTANCE5: case GL_CLIP_DISTANCE6: case GL_CLIP_DISTANCE7: { const GLuint p = cap - GL_CLIP_DISTANCE0; if (p >= ctx->Const.MaxClipPlanes) goto invalid_enum_error; return (ctx->Transform.ClipPlanesEnabled >> p) & 1; } case GL_COLOR_MATERIAL: return ctx->Light.ColorMaterialEnabled; case GL_CULL_FACE: return ctx->Polygon.CullFlag; case GL_DEPTH_TEST: return ctx->Depth.Test; case GL_DITHER: return ctx->Color.DitherFlag; case GL_FOG: return ctx->Fog.Enabled; case GL_LIGHTING: return ctx->Light.Enabled; case GL_LIGHT0: case GL_LIGHT1: case GL_LIGHT2: case GL_LIGHT3: case GL_LIGHT4: case GL_LIGHT5: case GL_LIGHT6: case GL_LIGHT7: return ctx->Light.Light[cap-GL_LIGHT0].Enabled; case GL_LINE_SMOOTH: return ctx->Line.SmoothFlag; case GL_LINE_STIPPLE: return ctx->Line.StippleFlag; case GL_INDEX_LOGIC_OP: return ctx->Color.IndexLogicOpEnabled; case GL_COLOR_LOGIC_OP: return ctx->Color.ColorLogicOpEnabled; case GL_MAP1_COLOR_4: return ctx->Eval.Map1Color4; case GL_MAP1_INDEX: return ctx->Eval.Map1Index; case GL_MAP1_NORMAL: return ctx->Eval.Map1Normal; case GL_MAP1_TEXTURE_COORD_1: return ctx->Eval.Map1TextureCoord1; case GL_MAP1_TEXTURE_COORD_2: return ctx->Eval.Map1TextureCoord2; case GL_MAP1_TEXTURE_COORD_3: return ctx->Eval.Map1TextureCoord3; case GL_MAP1_TEXTURE_COORD_4: return ctx->Eval.Map1TextureCoord4; case GL_MAP1_VERTEX_3: return ctx->Eval.Map1Vertex3; case GL_MAP1_VERTEX_4: return ctx->Eval.Map1Vertex4; case GL_MAP2_COLOR_4: return ctx->Eval.Map2Color4; case GL_MAP2_INDEX: return ctx->Eval.Map2Index; case GL_MAP2_NORMAL: return ctx->Eval.Map2Normal; case GL_MAP2_TEXTURE_COORD_1: return ctx->Eval.Map2TextureCoord1; case GL_MAP2_TEXTURE_COORD_2: return ctx->Eval.Map2TextureCoord2; case GL_MAP2_TEXTURE_COORD_3: return ctx->Eval.Map2TextureCoord3; case GL_MAP2_TEXTURE_COORD_4: return ctx->Eval.Map2TextureCoord4; case GL_MAP2_VERTEX_3: return ctx->Eval.Map2Vertex3; case GL_MAP2_VERTEX_4: return ctx->Eval.Map2Vertex4; case GL_NORMALIZE: return ctx->Transform.Normalize; case GL_POINT_SMOOTH: return ctx->Point.SmoothFlag; case GL_POLYGON_SMOOTH: return ctx->Polygon.SmoothFlag; case GL_POLYGON_STIPPLE: return ctx->Polygon.StippleFlag; case GL_POLYGON_OFFSET_POINT: return ctx->Polygon.OffsetPoint; case GL_POLYGON_OFFSET_LINE: return ctx->Polygon.OffsetLine; case GL_POLYGON_OFFSET_FILL: return ctx->Polygon.OffsetFill; case GL_RESCALE_NORMAL_EXT: return ctx->Transform.RescaleNormals; case GL_SCISSOR_TEST: return ctx->Scissor.Enabled; case GL_STENCIL_TEST: return ctx->Stencil.Enabled; case GL_TEXTURE_1D: return is_texture_enabled(ctx, TEXTURE_1D_BIT); case GL_TEXTURE_2D: return is_texture_enabled(ctx, TEXTURE_2D_BIT); case GL_TEXTURE_GEN_S: case GL_TEXTURE_GEN_T: case GL_TEXTURE_GEN_R: case GL_TEXTURE_GEN_Q: { const struct gl_texture_unit *texUnit = get_texcoord_unit(ctx); if (texUnit) { GLbitfield coordBit = S_BIT << (cap - GL_TEXTURE_GEN_S); return (texUnit->TexGenEnabled & coordBit) ? GL_TRUE : GL_FALSE; } } return GL_FALSE; #if FEATURE_ES1 case GL_TEXTURE_GEN_STR_OES: { const struct gl_texture_unit *texUnit = get_texcoord_unit(ctx); if (texUnit) { return (texUnit->TexGenEnabled & STR_BITS) == STR_BITS ? GL_TRUE : GL_FALSE; } } #endif /* client-side state */ case GL_VERTEX_ARRAY: return (ctx->Array.VertexAttrib[VERT_ATTRIB_POS].Enabled != 0); case GL_NORMAL_ARRAY: return (ctx->Array.VertexAttrib[VERT_ATTRIB_NORMAL].Enabled != 0); case GL_COLOR_ARRAY: return (ctx->Array.VertexAttrib[VERT_ATTRIB_COLOR].Enabled != 0); case GL_INDEX_ARRAY: return (ctx->Array.VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled != 0); case GL_TEXTURE_COORD_ARRAY: return (ctx->Array.VertexAttrib[VERT_ATTRIB_TEX] .Enabled != 0); case GL_EDGE_FLAG_ARRAY: return (ctx->Array.VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled != 0); case GL_FOG_COORDINATE_ARRAY_EXT: CHECK_EXTENSION(EXT_fog_coord); return (ctx->Array.VertexAttrib[VERT_ATTRIB_FOG].Enabled != 0); #if FEATURE_point_size_array case GL_POINT_SIZE_ARRAY_OES: return (ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Enabled != 0); #endif /* GL_ARB_texture_cube_map */ case GL_TEXTURE_CUBE_MAP_ARB: CHECK_EXTENSION(ARB_texture_cube_map); return is_texture_enabled(ctx, TEXTURE_CUBE_BIT); /* GL_ARB_multisample */ case GL_MULTISAMPLE_ARB: return ctx->Multisample.Enabled; case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB: return ctx->Multisample.SampleAlphaToCoverage; case GL_SAMPLE_ALPHA_TO_ONE_ARB: return ctx->Multisample.SampleAlphaToOne; case GL_SAMPLE_COVERAGE_ARB: return ctx->Multisample.SampleCoverage; case GL_SAMPLE_COVERAGE_INVERT_ARB: return ctx->Multisample.SampleCoverageInvert; /* GL_IBM_rasterpos_clip */ case GL_RASTER_POSITION_UNCLIPPED_IBM: CHECK_EXTENSION(IBM_rasterpos_clip); return ctx->Transform.RasterPositionUnclipped; /* GL_NV_point_sprite */ case GL_POINT_SPRITE_NV: CHECK_EXTENSION2(NV_point_sprite, ARB_point_sprite) return ctx->Point.PointSprite; /* GL_EXT_depth_bounds_test */ case GL_DEPTH_BOUNDS_TEST_EXT: CHECK_EXTENSION(EXT_depth_bounds_test); return ctx->Depth.BoundsTest; default: goto invalid_enum_error; } return GL_FALSE; invalid_enum_error: _mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(0x%x)", (int) cap); return GL_FALSE; }
/** * Set rasterization mode. * * \param mode rasterization mode. * * \note this function can't be put in a display list. * * \sa glRenderMode(). * * Flushes the vertices and do the necessary cleanup according to the previous * rasterization mode, such as writing the hit record or resent the select * buffer index when exiting the select mode. Updates * __struct gl_contextRec::RenderMode and notifies the driver via the * dd_function_table::RenderMode callback. */ GLint GLAPIENTRY _mesa_RenderMode( GLenum mode ) { GET_CURRENT_CONTEXT(ctx); GLint result; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glRenderMode %s\n", _mesa_lookup_enum_by_nr(mode)); FLUSH_VERTICES(ctx, _NEW_RENDERMODE); switch (ctx->RenderMode) { case GL_RENDER: result = 0; break; case GL_SELECT: if (ctx->Select.HitFlag) { write_hit_record( ctx ); } if (ctx->Select.BufferCount > ctx->Select.BufferSize) { /* overflow */ #ifdef DEBUG _mesa_warning(ctx, "Feedback buffer overflow"); #endif result = -1; } else { result = ctx->Select.Hits; } ctx->Select.BufferCount = 0; ctx->Select.Hits = 0; ctx->Select.NameStackDepth = 0; break; case GL_FEEDBACK: if (ctx->Feedback.Count > ctx->Feedback.BufferSize) { /* overflow */ result = -1; } else { result = ctx->Feedback.Count; } ctx->Feedback.Count = 0; break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glRenderMode" ); return 0; } switch (mode) { case GL_RENDER: break; case GL_SELECT: if (ctx->Select.BufferSize==0) { /* haven't called glSelectBuffer yet */ _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" ); } break; case GL_FEEDBACK: if (ctx->Feedback.BufferSize==0) { /* haven't called glFeedbackBuffer yet */ _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" ); } break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glRenderMode" ); return 0; } ctx->RenderMode = mode; if (ctx->Driver.RenderMode) ctx->Driver.RenderMode( ctx, mode ); return result; }
/** * See GL_ARB_map_buffer_range spec */ void * GLAPIENTRY _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) { GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj; void *map; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL); if (!ctx->Extensions.ARB_map_buffer_range) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferRange(extension not supported)"); return NULL; } if (offset < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glMapBufferRange(offset = %ld)", (long)offset); return NULL; } if (length < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glMapBufferRange(length = %ld)", (long)length); return NULL; } if (access & ~(GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT)) { /* generate an error if any undefind bit is set */ _mesa_error(ctx, GL_INVALID_VALUE, "glMapBufferRange(access)"); return NULL; } if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferRange(access indicates neither read or write)"); return NULL; } if ((access & GL_MAP_READ_BIT) && (access & (GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT))) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferRange(invalid access flags)"); return NULL; } if ((access & GL_MAP_FLUSH_EXPLICIT_BIT) && ((access & GL_MAP_WRITE_BIT) == 0)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferRange(invalid access flags)"); return NULL; } bufObj = get_buffer(ctx, "glMapBufferRange", target); if (!bufObj) return NULL; if (offset + length > bufObj->Size) { _mesa_error(ctx, GL_INVALID_VALUE, "glMapBufferRange(offset + length > size)"); return NULL; } if (_mesa_bufferobj_mapped(bufObj)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferRange(buffer already mapped)"); return NULL; } if (!bufObj->Size) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferRange(buffer size = 0)"); return NULL; } /* Mapping zero bytes should return a non-null pointer. */ if (!length) { static long dummy = 0; bufObj->Pointer = &dummy; bufObj->Length = length; bufObj->Offset = offset; bufObj->AccessFlags = access; return bufObj->Pointer; } ASSERT(ctx->Driver.MapBufferRange); map = ctx->Driver.MapBufferRange(ctx, offset, length, access, bufObj); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(map failed)"); } else { /* The driver callback should have set all these fields. * This is important because other modules (like VBO) might call * the driver function directly. */ ASSERT(bufObj->Pointer == map); ASSERT(bufObj->Length == length); ASSERT(bufObj->Offset == offset); ASSERT(bufObj->AccessFlags == access); } return map; }
/** * Query string-valued state. The return value should _not_ be freed by * the caller. * * \param name the state variable to query. * * \sa glGetString(). * * Tries to get the string from dd_function_table::GetString, otherwise returns * the hardcoded strings. */ const GLubyte * GLAPIENTRY _mesa_GetString( GLenum name ) { GET_CURRENT_CONTEXT(ctx); static const char *vendor = "Brian Paul"; static const char *renderer = "Mesa"; static const char *version_1_2 = "1.2 Mesa " MESA_VERSION_STRING; static const char *version_1_3 = "1.3 Mesa " MESA_VERSION_STRING; static const char *version_1_4 = "1.4 Mesa " MESA_VERSION_STRING; static const char *version_1_5 = "1.5 Mesa " MESA_VERSION_STRING; static const char *version_2_0 = "2.0 Mesa " MESA_VERSION_STRING; static const char *version_2_1 = "2.1 Mesa " MESA_VERSION_STRING; #if FEATURE_ARB_shading_language_100 static const char *sl_version_110 = "1.10 Mesa " MESA_VERSION_STRING; #endif if (!ctx) return NULL; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL); /* this is a required driver function */ assert(ctx->Driver.GetString); { /* Give the driver the chance to handle this query */ const GLubyte *str = (*ctx->Driver.GetString)(ctx, name); if (str) return str; } switch (name) { case GL_VENDOR: return (const GLubyte *) vendor; case GL_RENDERER: return (const GLubyte *) renderer; case GL_VERSION: if (ctx->Extensions.ARB_multisample && ctx->Extensions.ARB_multitexture && ctx->Extensions.ARB_texture_border_clamp && ctx->Extensions.ARB_texture_compression && ctx->Extensions.ARB_texture_cube_map && ctx->Extensions.EXT_texture_env_add && ctx->Extensions.ARB_texture_env_combine && ctx->Extensions.ARB_texture_env_dot3) { if (ctx->Extensions.ARB_depth_texture && ctx->Extensions.ARB_shadow && ctx->Extensions.ARB_texture_env_crossbar && ctx->Extensions.ARB_texture_mirrored_repeat && ctx->Extensions.ARB_window_pos && ctx->Extensions.EXT_blend_color && ctx->Extensions.EXT_blend_func_separate && ctx->Extensions.EXT_blend_logic_op && ctx->Extensions.EXT_blend_minmax && ctx->Extensions.EXT_blend_subtract && ctx->Extensions.EXT_fog_coord && ctx->Extensions.EXT_multi_draw_arrays && ctx->Extensions.EXT_point_parameters && /*aka ARB*/ ctx->Extensions.EXT_secondary_color && ctx->Extensions.EXT_stencil_wrap && ctx->Extensions.EXT_texture_lod_bias && ctx->Extensions.SGIS_generate_mipmap) { if (ctx->Extensions.ARB_occlusion_query && ctx->Extensions.ARB_vertex_buffer_object && ctx->Extensions.EXT_shadow_funcs) { if (ctx->Extensions.ARB_draw_buffers && ctx->Extensions.ARB_point_sprite && ctx->Extensions.ARB_shader_objects && ctx->Extensions.ARB_vertex_shader && ctx->Extensions.ARB_fragment_shader && ctx->Extensions.ARB_texture_non_power_of_two && ctx->Extensions.EXT_blend_equation_separate) { if (ctx->Extensions.ARB_shading_language_120 && ctx->Extensions.EXT_pixel_buffer_object && ctx->Extensions.EXT_texture_sRGB) { return (const GLubyte *) version_2_1; } else { return (const GLubyte *) version_2_0; } } else { return (const GLubyte *) version_1_5; } } else { return (const GLubyte *) version_1_4; } } else { return (const GLubyte *) version_1_3; } } else { return (const GLubyte *) version_1_2; } case GL_EXTENSIONS: if (!ctx->Extensions.String) ctx->Extensions.String = _mesa_make_extension_string(ctx); return (const GLubyte *) ctx->Extensions.String; #if FEATURE_ARB_shading_language_100 case GL_SHADING_LANGUAGE_VERSION_ARB: if (ctx->Extensions.ARB_shading_language_100) return (const GLubyte *) sl_version_110; goto error; #endif #if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program || \ FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program case GL_PROGRAM_ERROR_STRING_NV: if (ctx->Extensions.NV_fragment_program || ctx->Extensions.ARB_fragment_program || ctx->Extensions.NV_vertex_program || ctx->Extensions.ARB_vertex_program) { return (const GLubyte *) ctx->Program.ErrorString; } /* FALL-THROUGH */ #endif #if FEATURE_ARB_shading_language_100 error: #endif default: _mesa_error( ctx, GL_INVALID_ENUM, "glGetString" ); return (const GLubyte *) 0; } }