/** * Returns the current GL error code, or GL_NO_ERROR. * \return current error code * * Returns __struct gl_contextRec::ErrorValue. */ GLenum GLAPIENTRY _mesa_GetError( void ) { GET_CURRENT_CONTEXT(ctx); GLenum e = ctx->ErrorValue; ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glGetError <-- %s\n", _mesa_lookup_enum_by_nr(e)); ctx->ErrorValue = (GLenum) GL_NO_ERROR; ctx->ErrorDebugCount = 0; return e; }
static void GLAPIENTRY vbo_exec_DrawTransformFeedbackInstanced(GLenum mode, GLuint name, GLsizei primcount) { GET_CURRENT_CONTEXT(ctx); struct gl_transform_feedback_object *obj = _mesa_lookup_transform_feedback_object(ctx, name); if (MESA_VERBOSE & VERBOSE_DRAW) _mesa_debug(ctx, "glDrawTransformFeedbackInstanced(%s, %d)\n", _mesa_lookup_enum_by_nr(mode), name); vbo_draw_transform_feedback(ctx, mode, obj, 0, primcount); }
static void gen6_set_prim(struct brw_context *brw, const struct _mesa_prim *prim) { uint32_t hw_prim; DBG("PRIM: %s\n", _mesa_lookup_enum_by_nr(prim->mode)); hw_prim = prim_to_hw_prim[prim->mode]; if (hw_prim != brw->primitive) { brw->primitive = hw_prim; brw->state.dirty.brw |= BRW_NEW_PRIMITIVE; } }
/** * Given vertex array type/size/format/normalized info, return * the appopriate hardware surface type. * Format will be GL_RGBA or possibly GL_BGRA for GLubyte[4] color arrays. */ static GLuint get_surface_type( GLenum type, GLuint size, GLenum format, GLboolean normalized ) { if (unlikely(INTEL_DEBUG & DEBUG_VERTS)) printf("type %s size %d normalized %d\n", _mesa_lookup_enum_by_nr(type), size, normalized); if (normalized) { switch (type) { case GL_DOUBLE: return double_types[size]; case GL_FLOAT: return float_types[size]; case GL_HALF_FLOAT: return half_float_types[size]; case GL_INT: return int_types_norm[size]; case GL_SHORT: return short_types_norm[size]; case GL_BYTE: return byte_types_norm[size]; case GL_UNSIGNED_INT: return uint_types_norm[size]; case GL_UNSIGNED_SHORT: return ushort_types_norm[size]; case GL_UNSIGNED_BYTE: if (format == GL_BGRA) { /* See GL_EXT_vertex_array_bgra */ assert(size == 4); return BRW_SURFACEFORMAT_B8G8R8A8_UNORM; } else { return ubyte_types_norm[size]; } default: assert(0); return 0; } } else { assert(format == GL_RGBA); /* sanity check */ switch (type) { case GL_DOUBLE: return double_types[size]; case GL_FLOAT: return float_types[size]; case GL_HALF_FLOAT: return half_float_types[size]; case GL_INT: return int_types_scale[size]; case GL_SHORT: return short_types_scale[size]; case GL_BYTE: return byte_types_scale[size]; case GL_UNSIGNED_INT: return uint_types_scale[size]; case GL_UNSIGNED_SHORT: return ushort_types_scale[size]; case GL_UNSIGNED_BYTE: return ubyte_types_scale[size]; /* This produces GL_FIXED inputs as values between INT32_MIN and * INT32_MAX, which will be scaled down by 1/65536 by the VS. */ case GL_FIXED: return int_types_scale[size]; default: assert(0); return 0; } } }
static void r300TexParameter(GLcontext * ctx, GLenum target, struct gl_texture_object *texObj, GLenum pname, const GLfloat * params) { r300TexObjPtr t = (r300TexObjPtr) texObj->DriverData; if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { fprintf(stderr, "%s( %s )\n", __FUNCTION__, _mesa_lookup_enum_by_nr(pname)); } switch (pname) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: case GL_TEXTURE_MAX_ANISOTROPY_EXT: r300SetTexMaxAnisotropy(t, texObj->MaxAnisotropy); r300SetTexFilter(t, texObj->MinFilter, texObj->MagFilter); break; case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: case GL_TEXTURE_WRAP_R: r300SetTexWrap(t, texObj->WrapS, texObj->WrapT, texObj->WrapR); break; case GL_TEXTURE_BORDER_COLOR: r300SetTexBorderColor(t, texObj->_BorderChan); break; case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_MAX_LEVEL: case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: /* This isn't the most efficient solution but there doesn't appear to * be a nice alternative. Since there's no LOD clamping, * we just have to rely on loading the right subset of mipmap levels * to simulate a clamped LOD. */ driSwapOutTextureObject((driTextureObject *) t); break; default: return; } /* Mark this texobj as dirty (one bit per tex unit) */ t->dirty_state = TEX_ALL; }
static void GLAPIENTRY _mesa_GetQueryObjectuivARB(GLuint id, GLenum pname, GLuint *params) { struct gl_query_object *q = NULL; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glGetQueryObjectuiv(%u, %s)\n", id, _mesa_lookup_enum_by_nr(pname)); if (id) q = _mesa_lookup_query_object(ctx, id); if (!q || q->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetQueryObjectuivARB(id=%d is invalid or active)", id); return; } switch (pname) { case GL_QUERY_RESULT_ARB: if (!q->Ready) ctx->Driver.WaitQuery(ctx, q); /* if result is too large for returned type, clamp to max value */ if (q->Target == GL_ANY_SAMPLES_PASSED) { if (q->Result) *params = GL_TRUE; else *params = GL_FALSE; } else { if (q->Result > 0xffffffff) { *params = 0xffffffff; } else { *params = (GLuint)q->Result; } } break; case GL_QUERY_RESULT_AVAILABLE_ARB: if (!q->Ready) ctx->Driver.CheckQuery( ctx, q ); *params = q->Ready; break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetQueryObjectuivARB(pname)"); return; } }
/** * Verify that the element type is valid. * * Generates \c GL_INVALID_ENUM and returns \c false if it is not. */ static bool valid_elements_type(struct gl_context *ctx, GLenum type, const char *name) { switch (type) { case GL_UNSIGNED_BYTE: case GL_UNSIGNED_SHORT: case GL_UNSIGNED_INT: return true; default: _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)", name, _mesa_lookup_enum_by_nr(type)); return false; } }
/* GL_ARB_multitexture */ void GLAPIENTRY _mesa_ActiveTextureARB(GLenum texture) { const GLuint texUnit = texture - GL_TEXTURE0; GLuint k; GET_CURRENT_CONTEXT(ctx); /* See OpenGL spec for glActiveTexture: */ k = MAX2(ctx->Const.MaxCombinedTextureImageUnits, ctx->Const.MaxTextureCoordUnits); ASSERT(k <= Elements(ctx->Texture.Unit)); ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) _mesa_debug(ctx, "glActiveTexture %s\n", _mesa_lookup_enum_by_nr(texture)); if (texUnit >= k) { _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture=%s)", _mesa_lookup_enum_by_nr(texture)); return; } if (ctx->Texture.CurrentUnit == texUnit) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); ctx->Texture.CurrentUnit = texUnit; if (ctx->Transform.MatrixMode == GL_TEXTURE) { /* update current stack pointer */ ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit]; } }
/* System to flush dma and emit state changes based on the rasterized * primitive. */ static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim ) { intelContextPtr intel = INTEL_CONTEXT(ctx); if (0) fprintf(stderr, "%s %s %x\n", __FUNCTION__, _mesa_lookup_enum_by_nr(rprim), hwprim); intel->vtbl.reduced_primitive_state( intel, rprim ); /* Start a new primitive. Arrange to have it flushed later on. */ if (hwprim != intel->prim.primitive) intelStartInlinePrimitive( intel, hwprim ); }
/** * Do error checking and update state for glVertex/Color/TexCoord/...Pointer * functions. * * \param func name of calling function used for error reporting * \param attrib the attribute array index to update * \param legalTypes bitmask of *_BIT above indicating legal datatypes * \param sizeMin min allowable size value * \param sizeMax max allowable size value * \param size components per element (1, 2, 3 or 4) * \param type datatype of each component (GL_FLOAT, GL_INT, etc) * \param stride stride between elements, in elements * \param normalized are integer types converted to floats in [-1, 1]? * \param integer integer-valued values (will not be normalized to [-1,1]) * \param ptr the address (or offset inside VBO) of the array data */ static void update_array(struct gl_context *ctx, const char *func, GLuint attrib, GLbitfield legalTypesMask, GLint sizeMin, GLint sizeMax, GLint size, GLenum type, GLsizei stride, GLboolean normalized, GLboolean integer, const GLvoid *ptr) { struct gl_client_array *array; GLbitfield typeBit; GLsizei elementSize; typeBit = type_to_bit(ctx, type); if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) { _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)", func, _mesa_lookup_enum_by_nr(type)); return; } /* Do size parameter checking. */ if (size < sizeMin || size > sizeMax || size > 4) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size); return; } ASSERT(size <= 4); if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride ); return; } elementSize = _mesa_sizeof_type(type) * size; array = &ctx->Array.VertexAttrib[attrib]; array->Size = size; array->Type = type; array->Stride = stride; array->StrideB = stride ? stride : elementSize; array->Normalized = normalized; array->Integer = integer; array->Ptr = (const GLubyte *) ptr; array->_ElementSize = elementSize; ctx->NewState |= _NEW_ARRAY; ctx->Array.NewState |= VERT_BIT(attrib); }
static void radeon_bind_framebuffer(struct gl_context * ctx, GLenum target, struct gl_framebuffer *fb, struct gl_framebuffer *fbread) { radeon_print(RADEON_TEXTURE, RADEON_TRACE, "%s(%p, fb %p, target %s) \n", __func__, ctx, fb, _mesa_lookup_enum_by_nr(target)); if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { radeon_draw_buffer(ctx, fb); } else { /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ } }
static void r300TexEnv(GLcontext * ctx, GLenum target, GLenum pname, const GLfloat * param) { if (RADEON_DEBUG & DEBUG_STATE) { fprintf(stderr, "%s( %s )\n", __FUNCTION__, _mesa_lookup_enum_by_nr(pname)); } /* This is incorrect: Need to maintain this data for each of * GL_TEXTURE_{123}D, GL_TEXTURE_RECTANGLE_NV, etc, and switch * between them according to _ReallyEnabled. */ switch (pname) { case GL_TEXTURE_LOD_BIAS_EXT:{ #if 0 /* Needs to be relocated in order to make sure we got the right tmu */ GLfloat bias, min; GLuint b; /* The R300's LOD bias is a signed 2's complement value with a * range of -16.0 <= bias < 16.0. * * NOTE: Add a small bias to the bias for conform mipsel.c test. */ bias = *param + .01; min = driQueryOptionb(&rmesa->radeon.optionCache, "no_neg_lod_bias") ? 0.0 : -16.0; bias = CLAMP(bias, min, 16.0); /* 0.0 - 16.0 == 0x0 - 0x1000 */ /* 0.0 - -16.0 == 0x1001 - 0x1fff */ b = 0x1000 / 16.0 * bias; b &= R300_LOD_BIAS_MASK; if(b != (rmesa->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+unit] & R300_LOD_BIAS_MASK)){ R300_STATECHANGE(rmesa, tex.unknown1); rmesa->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+unit] &= ~R300_LOD_BIAS_MASK; rmesa->hw.tex.unknown1.cmd[R300_TEX_VALUE_0+unit] |= b; } #endif break; } default: return; } }
void GLAPIENTRY _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) { GLint elementSize; GET_CURRENT_CONTEXT(ctx); const GLuint unit = ctx->Array.ActiveTexture; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (size < 1 || size > 4) { _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" ); return; } if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" ); return; } if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) _mesa_debug(ctx, "glTexCoordPointer(unit %u sz %d type %s stride %d)\n", unit, size, _mesa_lookup_enum_by_nr( type ), stride); /* always need to check that <type> is legal */ switch (type) { case GL_SHORT: elementSize = size * sizeof(GLshort); break; case GL_INT: elementSize = size * sizeof(GLint); break; case GL_FLOAT: elementSize = size * sizeof(GLfloat); break; case GL_DOUBLE: elementSize = size * sizeof(GLdouble); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" ); return; } update_array(ctx, &ctx->Array.TexCoord[unit], _NEW_ARRAY_TEXCOORD(unit), elementSize, size, type, stride, GL_FALSE, ptr); if (ctx->Driver.TexCoordPointer) ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr ); }
/** * New in GL 3.2 * This is pretty much a duplicate of GetBufferParameteriv() but the * GL_BUFFER_SIZE_ARB attribute will be 64-bits on a 64-bit system. */ void GLAPIENTRY _mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params) { GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj; ASSERT_OUTSIDE_BEGIN_END(ctx); bufObj = get_buffer(ctx, "glGetBufferParameteri64v", target); if (!bufObj) return; switch (pname) { case GL_BUFFER_SIZE_ARB: *params = bufObj->Size; return; case GL_BUFFER_USAGE_ARB: *params = bufObj->Usage; return; case GL_BUFFER_ACCESS_ARB: *params = simplified_access_mode(bufObj->AccessFlags); return; case GL_BUFFER_ACCESS_FLAGS: if (!ctx->Extensions.ARB_map_buffer_range) goto invalid_pname; *params = bufObj->AccessFlags; return; case GL_BUFFER_MAPPED_ARB: *params = _mesa_bufferobj_mapped(bufObj); return; case GL_BUFFER_MAP_OFFSET: if (!ctx->Extensions.ARB_map_buffer_range) goto invalid_pname; *params = bufObj->Offset; return; case GL_BUFFER_MAP_LENGTH: if (!ctx->Extensions.ARB_map_buffer_range) goto invalid_pname; *params = bufObj->Length; return; default: ; /* fall-through */ } invalid_pname: _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferParameteri64v(pname=%s)", _mesa_lookup_enum_by_nr(pname)); }
void brw_draw_prims( struct gl_context *ctx, const struct _mesa_prim *prim, GLuint nr_prims, const struct _mesa_index_buffer *ib, GLboolean index_bounds_valid, GLuint min_index, GLuint max_index, struct gl_transform_feedback_object *tfb_vertcount ) { struct intel_context *intel = intel_context(ctx); const struct gl_client_array **arrays = ctx->Array._DrawArrays; if (!_mesa_check_conditional_render(ctx)) return; /* Handle primitive restart if needed */ if (brw_handle_primitive_restart(ctx, prim, nr_prims, ib)) { /* The draw was handled, so we can exit now */ return; } /* If we're going to have to upload any of the user's vertex arrays, then * get the minimum and maximum of their index buffer so we know what range * to upload. */ if (!vbo_all_varyings_in_vbos(arrays) && !index_bounds_valid) vbo_get_minmax_indices(ctx, prim, ib, &min_index, &max_index, nr_prims); /* Do GL_SELECT and GL_FEEDBACK rendering using swrast, even though it * won't support all the extensions we support. */ if (ctx->RenderMode != GL_RENDER) { perf_debug("%s render mode not supported in hardware\n", _mesa_lookup_enum_by_nr(ctx->RenderMode)); _swsetup_Wakeup(ctx); _tnl_wakeup(ctx); _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); return; } /* Try drawing with the hardware, but don't do anything else if we can't * manage it. swrast doesn't support our featureset, so we can't fall back * to it. */ brw_try_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index); }
void GLAPIENTRY _mesa_BeginConditionalRender(GLuint queryId, GLenum mode) { struct gl_query_object *q; GET_CURRENT_CONTEXT(ctx); if (!ctx->Extensions.NV_conditional_render || ctx->Query.CondRenderQuery || queryId == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()"); return; } ASSERT(ctx->Query.CondRenderMode == GL_NONE); switch (mode) { case GL_QUERY_WAIT: case GL_QUERY_NO_WAIT: case GL_QUERY_BY_REGION_WAIT: case GL_QUERY_BY_REGION_NO_WAIT: /* OK */ break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glBeginConditionalRender(mode=%s)", _mesa_lookup_enum_by_nr(mode)); return; } q = _mesa_lookup_query_object(ctx, queryId); if (!q) { _mesa_error(ctx, GL_INVALID_VALUE, "glBeginConditionalRender(bad queryId=%u)", queryId); return; } ASSERT(q->Id == queryId); if (q->Target != GL_SAMPLES_PASSED || q->Active) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()"); return; } ctx->Query.CondRenderQuery = q; ctx->Query.CondRenderMode = mode; if (ctx->Driver.BeginConditionalRender) ctx->Driver.BeginConditionalRender(ctx, q, mode); }
/** * Called by glDrawBuffer(). * Specify which renderbuffer(s) to draw into for the first color output. * <buffer> can name zero, one, two or four renderbuffers! * \sa _mesa_DrawBuffers * * \param buffer buffer token such as GL_LEFT or GL_FRONT_AND_BACK, etc. * * Note that the behaviour of this function depends on whether the * current ctx->DrawBuffer is a window-system framebuffer or a user-created * framebuffer object. * In the former case, we update the per-context ctx->Color.DrawBuffer * state var _and_ the FB's ColorDrawBuffer state. * In the later case, we update the FB's ColorDrawBuffer state only. * * Furthermore, upon a MakeCurrent() or BindFramebuffer() call, if the * new FB is a window system FB, we need to re-update the FB's * ColorDrawBuffer state to match the context. This is handled in * _mesa_update_framebuffer(). * * See the GL_EXT_framebuffer_object spec for more info. */ void GLAPIENTRY _mesa_DrawBuffer(GLenum buffer) { GLbitfield destMask; GET_CURRENT_CONTEXT(ctx); FLUSH_VERTICES(ctx, 0); if (MESA_VERBOSE & VERBOSE_API) { _mesa_debug(ctx, "glDrawBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); } if (buffer == GL_NONE) { destMask = 0x0; } else { const GLbitfield supportedMask = supported_buffer_bitmask(ctx, ctx->DrawBuffer); destMask = draw_buffer_enum_to_bitmask(ctx, buffer); if (destMask == BAD_MASK) { /* totally bogus buffer */ _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffer(buffer=0x%x)", buffer); return; } destMask &= supportedMask; if (destMask == 0x0) { /* none of the named color buffers exist! */ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffer(buffer=0x%x)", buffer); return; } } /* if we get here, there's no error so set new state */ _mesa_drawbuffers(ctx, 1, &buffer, &destMask); /* * Call device driver function. */ if (ctx->Driver.DrawBuffers) ctx->Driver.DrawBuffers(ctx, 1, &buffer); else if (ctx->Driver.DrawBuffer) ctx->Driver.DrawBuffer(ctx, buffer); }
GLuint GLAPIENTRY _mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name) { GET_CURRENT_CONTEXT(ctx); struct gl_program_resource *res; struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramResourceIndex"); if (!shProg || !name) return GL_INVALID_INDEX; /* * For the interface TRANSFORM_FEEDBACK_VARYING, the value INVALID_INDEX * should be returned when querying the index assigned to the special names * "gl_NextBuffer", "gl_SkipComponents1", "gl_SkipComponents2", * "gl_SkipComponents3", and "gl_SkipComponents4". */ if (programInterface == GL_TRANSFORM_FEEDBACK_VARYING && is_xfb_marker(name)) return GL_INVALID_INDEX; switch (programInterface) { case GL_PROGRAM_INPUT: case GL_PROGRAM_OUTPUT: case GL_UNIFORM: case GL_UNIFORM_BLOCK: case GL_TRANSFORM_FEEDBACK_VARYING: /* Validate name syntax for arrays. */ if (!valid_program_resource_index_name(name)) return GL_INVALID_INDEX; res = _mesa_program_resource_find_name(shProg, programInterface, name); if (!res) return GL_INVALID_INDEX; return _mesa_program_resource_index(shProg, res); case GL_ATOMIC_COUNTER_BUFFER: default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceIndex(%s)", _mesa_lookup_enum_by_nr(programInterface)); } return GL_INVALID_INDEX; }
/** * Return pointer-valued state, such as a vertex array pointer. * * \param pname names state to be queried * \param params returns the pointer value * * \sa glGetPointerv(). * * Tries to get the specified pointer via dd_function_table::GetPointerv, * otherwise gets the specified pointer from the current context. */ void GLAPIENTRY _mesa_GetPointerv( GLenum pname, GLvoid **params ) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (!params) return; if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glGetPointerv %s\n", _mesa_lookup_enum_by_nr(pname)); switch (pname) { case GL_VERTEX_ARRAY_POINTER: *params = (GLvoid *) ctx->Array.VertexAttrib[VERT_ATTRIB_POS].Ptr; break; case GL_NORMAL_ARRAY_POINTER: *params = (GLvoid *) ctx->Array.VertexAttrib[VERT_ATTRIB_NORMAL].Ptr; break; case GL_COLOR_ARRAY_POINTER: *params = (GLvoid *) ctx->Array.VertexAttrib[VERT_ATTRIB_COLOR].Ptr; break; case GL_FOG_COORDINATE_ARRAY_POINTER_EXT: *params = (GLvoid *) ctx->Array.VertexAttrib[VERT_ATTRIB_FOG].Ptr; break; case GL_INDEX_ARRAY_POINTER: *params = (GLvoid *) ctx->Array.VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Ptr; break; case GL_TEXTURE_COORD_ARRAY_POINTER: *params = (GLvoid *) ctx->Array.VertexAttrib[VERT_ATTRIB_TEX].Ptr; break; case GL_EDGE_FLAG_ARRAY_POINTER: *params = (GLvoid *) ctx->Array.VertexAttrib[VERT_ATTRIB_EDGEFLAG].Ptr; break; case GL_FEEDBACK_BUFFER_POINTER: *params = ctx->Feedback.Buffer; break; case GL_SELECTION_BUFFER_POINTER: *params = ctx->Select.Buffer; break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glGetPointerv" ); return; } }
/** * This function is called by software rendering commands (all point, * line triangle drawing, glClear, glDrawPixels, glCopyPixels, and * glBitmap, glBlitFramebuffer) to determine if subsequent drawing * commands should be * executed or discarded depending on the current conditional * rendering state. Ideally, this check would be implemented by the * GPU when doing hardware rendering. XXX should this function be * called via a new driver hook? * * \return GL_TRUE if we should render, GL_FALSE if we should discard */ GLboolean _mesa_check_conditional_render(struct gl_context *ctx) { struct gl_query_object *q = ctx->Query.CondRenderQuery; if (!q) { /* no query in progress - draw normally */ return GL_TRUE; } switch (ctx->Query.CondRenderMode) { case GL_QUERY_BY_REGION_WAIT: /* fall-through */ case GL_QUERY_WAIT: if (!q->Ready) { ctx->Driver.WaitQuery(ctx, q); } return q->Result > 0; case GL_QUERY_BY_REGION_WAIT_INVERTED: /* fall-through */ case GL_QUERY_WAIT_INVERTED: if (!q->Ready) { ctx->Driver.WaitQuery(ctx, q); } return q->Result == 0; case GL_QUERY_BY_REGION_NO_WAIT: /* fall-through */ case GL_QUERY_NO_WAIT: if (!q->Ready) ctx->Driver.CheckQuery(ctx, q); return q->Ready ? (q->Result > 0) : GL_TRUE; case GL_QUERY_BY_REGION_NO_WAIT_INVERTED: /* fall-through */ case GL_QUERY_NO_WAIT_INVERTED: if (!q->Ready) ctx->Driver.CheckQuery(ctx, q); return q->Ready ? (q->Result == 0) : GL_TRUE; default: _mesa_problem(ctx, "Bad cond render mode %s in " " _mesa_check_conditional_render()", _mesa_lookup_enum_by_nr(ctx->Query.CondRenderMode)); return GL_TRUE; } }
void GLAPIENTRY _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) { GLsizei elementSize; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (stride < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" ); return; } if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API)) _mesa_debug(ctx, "glNormalPointer( type %s stride %d )\n", _mesa_lookup_enum_by_nr( type ), stride); switch (type) { case GL_BYTE: elementSize = 3 * sizeof(GLbyte); break; case GL_SHORT: elementSize = 3 * sizeof(GLshort); break; case GL_INT: elementSize = 3 * sizeof(GLint); break; case GL_FLOAT: elementSize = 3 * sizeof(GLfloat); break; case GL_DOUBLE: elementSize = 3 * sizeof(GLdouble); break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" ); return; } update_array(ctx, &ctx->Array.Normal, _NEW_ARRAY_NORMAL, elementSize, 3, type, stride, GL_FALSE, ptr); if (ctx->Driver.NormalPointer) ctx->Driver.NormalPointer( ctx, type, stride, ptr ); }
/* System to flush dma and emit state changes based on the rasterized * primitive. */ static void intelRasterPrimitive(GLcontext * ctx, GLenum rprim, GLuint hwprim) { struct intel_context *intel = intel_context(ctx); if (0) fprintf(stderr, "%s %s %x\n", __FUNCTION__, _mesa_lookup_enum_by_nr(rprim), hwprim); intel->vtbl.reduced_primitive_state(intel, rprim); /* Start a new primitive. Arrange to have it flushed later on. */ if (hwprim != intel->prim.primitive) { INTEL_FIREVERTICES(intel); intelStartInlinePrimitive(intel, hwprim, INTEL_BATCH_CLIPRECTS); } }
/** * Given vertex array type/size/format/normalized info, return * the appopriate hardware surface type. * Format will be GL_RGBA or possibly GL_BGRA for GLubyte[4] color arrays. */ static GLuint get_surface_type( GLenum type, GLuint size, GLenum format, GLboolean normalized ) { if (INTEL_DEBUG & DEBUG_VERTS) _mesa_printf("type %s size %d normalized %d\n", _mesa_lookup_enum_by_nr(type), size, normalized); if (normalized) { switch (type) { case GL_DOUBLE: return double_types[size]; case GL_FLOAT: return float_types[size]; case GL_INT: return int_types_norm[size]; case GL_SHORT: return short_types_norm[size]; case GL_BYTE: return byte_types_norm[size]; case GL_UNSIGNED_INT: return uint_types_norm[size]; case GL_UNSIGNED_SHORT: return ushort_types_norm[size]; case GL_UNSIGNED_BYTE: if (format == GL_BGRA) { /* See GL_EXT_vertex_array_bgra */ assert(size == 4); return BRW_SURFACEFORMAT_B8G8R8A8_UNORM; } else { return ubyte_types_norm[size]; } default: assert(0); return 0; } } else { assert(format == GL_RGBA); /* sanity check */ switch (type) { case GL_DOUBLE: return double_types[size]; case GL_FLOAT: return float_types[size]; case GL_INT: return int_types_scale[size]; case GL_SHORT: return short_types_scale[size]; case GL_BYTE: return byte_types_scale[size]; case GL_UNSIGNED_INT: return uint_types_scale[size]; case GL_UNSIGNED_SHORT: return ushort_types_scale[size]; case GL_UNSIGNED_BYTE: return ubyte_types_scale[size]; default: assert(0); return 0; } } }
/** * Called from glDrawArrays when in immediate mode (not display list mode). */ static void GLAPIENTRY vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count) { GET_CURRENT_CONTEXT(ctx); if (MESA_VERBOSE & VERBOSE_DRAW) _mesa_debug(ctx, "glDrawArrays(%s, %d, %d)\n", _mesa_lookup_enum_by_nr(mode), start, count); if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) return; if (0) check_draw_arrays_data(ctx, start, count); vbo_draw_arrays(ctx, mode, start, count, 1, 0); if (0) print_draw_arrays(ctx, mode, start, count); }
/* This is really an extension function! */ void GLAPIENTRY _mesa_BlendEquation( GLenum mode ) { GLuint buf, numBuffers; GLboolean changed; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glBlendEquation(%s)\n", _mesa_lookup_enum_by_nr(mode)); if (!legal_blend_equation(ctx, mode)) { _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquation"); return; } numBuffers = ctx->Extensions.ARB_draw_buffers_blend ? ctx->Const.MaxDrawBuffers : 1; changed = GL_FALSE; for (buf = 0; buf < numBuffers; buf++) { if (ctx->Color.Blend[buf].EquationRGB != mode || ctx->Color.Blend[buf].EquationA != mode) { changed = GL_TRUE; break; } } if (!changed) return; FLUSH_VERTICES(ctx, _NEW_COLOR); for (buf = 0; buf < numBuffers; buf++) { ctx->Color.Blend[buf].EquationRGB = mode; ctx->Color.Blend[buf].EquationA = mode; } ctx->Color._BlendEquationPerBuffer = GL_FALSE; if (ctx->Driver.BlendEquationSeparate) (*ctx->Driver.BlendEquationSeparate)( ctx, mode, mode ); }
static void brw_emit_prim(struct brw_context *brw, const struct _mesa_prim *prim, uint32_t hw_prim) { struct brw_3d_primitive prim_packet; struct intel_context *intel = &brw->intel; if (INTEL_DEBUG & DEBUG_PRIMS) printf("PRIM: %s %d %d\n", _mesa_lookup_enum_by_nr(prim->mode), prim->start, prim->count); prim_packet.header.opcode = CMD_3D_PRIM; prim_packet.header.length = sizeof(prim_packet)/4 - 2; prim_packet.header.pad = 0; prim_packet.header.topology = hw_prim; prim_packet.header.indexed = prim->indexed; prim_packet.verts_per_instance = trim(prim->mode, prim->count); prim_packet.start_vert_location = prim->start; if (prim->indexed) prim_packet.start_vert_location += brw->ib.start_vertex_offset; prim_packet.instance_count = 1; prim_packet.start_instance_location = 0; prim_packet.base_vert_location = prim->basevertex; /* If we're set to always flush, do it before and after the primitive emit. * We want to catch both missed flushes that hurt instruction/state cache * and missed flushes of the render cache as it heads to other parts of * the besides the draw code. */ if (intel->always_flush_cache) { intel_batchbuffer_emit_mi_flush(intel->batch); } if (prim_packet.verts_per_instance) { intel_batchbuffer_data( brw->intel.batch, &prim_packet, sizeof(prim_packet)); } if (intel->always_flush_cache) { intel_batchbuffer_emit_mi_flush(intel->batch); } }
extern void _mesa_get_program_resourceiv(struct gl_shader_program *shProg, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params) { GET_CURRENT_CONTEXT(ctx); GLint *val = (GLint *) params; const GLenum *prop = props; GLsizei amount = 0; struct gl_program_resource *res = _mesa_program_resource_find_index(shProg, programInterface, index); /* No such resource found or bufSize negative. */ if (!res || bufSize < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramResourceiv(%s index %d bufSize %d)", _mesa_lookup_enum_by_nr(programInterface), index, bufSize); return; } /* Write propCount values until error occurs or bufSize reached. */ for (int i = 0; i < propCount && i < bufSize; i++, val++, prop++) { int props_written = _mesa_program_resource_prop(shProg, res, index, *prop, val, "glGetProgramResourceiv"); /* Error happened. */ if (props_written == 0) return; amount += props_written; } /* If <length> is not NULL, the actual number of integer values * written to <params> will be written to <length>. */ if (length) *length = amount; }
void GLAPIENTRY _mesa_ClampColor(GLenum target, GLenum clamp) { GET_CURRENT_CONTEXT(ctx); if (clamp != GL_TRUE && clamp != GL_FALSE && clamp != GL_FIXED_ONLY_ARB) { _mesa_error(ctx, GL_INVALID_ENUM, "glClampColorARB(clamp)"); return; } switch (target) { case GL_CLAMP_VERTEX_COLOR_ARB: if (ctx->API == API_OPENGL_CORE && !ctx->Extensions.ARB_color_buffer_float) { goto invalid_enum; } FLUSH_VERTICES(ctx, _NEW_LIGHT); ctx->Light.ClampVertexColor = clamp; _mesa_update_clamp_vertex_color(ctx); break; case GL_CLAMP_FRAGMENT_COLOR_ARB: if (ctx->API == API_OPENGL_CORE && !ctx->Extensions.ARB_color_buffer_float) { goto invalid_enum; } FLUSH_VERTICES(ctx, _NEW_FRAG_CLAMP); ctx->Color.ClampFragmentColor = clamp; _mesa_update_clamp_fragment_color(ctx); break; case GL_CLAMP_READ_COLOR_ARB: ctx->Color.ClampReadColor = clamp; break; default: goto invalid_enum; } return; invalid_enum: _mesa_error(ctx, GL_INVALID_ENUM, "glClampColor(%s)", _mesa_lookup_enum_by_nr(target)); }
/** * Specify a logic pixel operation for color index rendering. * * \param opcode operation. * * Verifies that \p opcode is a valid enum and updates gl_colorbuffer_attrib::LogicOp. * On a change, flushes the vertices and notifies the driver via the * dd_function_table::LogicOpcode callback. */ void GLAPIENTRY _mesa_LogicOp( GLenum opcode ) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glLogicOp(%s)\n", _mesa_lookup_enum_by_nr(opcode)); switch (opcode) { case GL_CLEAR: case GL_SET: case GL_COPY: case GL_COPY_INVERTED: case GL_NOOP: case GL_INVERT: case GL_AND: case GL_NAND: case GL_OR: case GL_NOR: case GL_XOR: case GL_EQUIV: case GL_AND_REVERSE: case GL_AND_INVERTED: case GL_OR_REVERSE: case GL_OR_INVERTED: break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glLogicOp" ); return; } if (ctx->Color.LogicOp == opcode) return; FLUSH_VERTICES(ctx, _NEW_COLOR); ctx->Color.LogicOp = opcode; if (ctx->Driver.LogicOpcode) ctx->Driver.LogicOpcode( ctx, opcode ); }
static GLboolean radeon_run_render( struct gl_context *ctx, struct tnl_pipeline_stage *stage ) { r100ContextPtr rmesa = R100_CONTEXT(ctx); TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; tnl_render_func *tab = TAG(render_tab_verts); GLuint i; if (rmesa->radeon.swtcl.RenderIndex != 0 || !radeon_dma_validate_render( ctx, VB )) return GL_TRUE; radeon_prepare_render(&rmesa->radeon); if (rmesa->radeon.NewGLState) radeonValidateState( ctx ); tnl->Driver.Render.Start( ctx ); for (i = 0 ; i < VB->PrimitiveCount ; i++) { GLuint prim = VB->Primitive[i].mode; GLuint start = VB->Primitive[i].start; GLuint length = VB->Primitive[i].count; if (!length) continue; radeon_print(RADEON_SWRENDER, RADEON_NORMAL, "radeon_render.c: prim %s %d..%d\n", _mesa_lookup_enum_by_nr(prim & PRIM_MODE_MASK), start, start+length); if (length) tab[prim & PRIM_MODE_MASK]( ctx, start, start + length, prim ); } tnl->Driver.Render.Finish( ctx ); return GL_FALSE; /* finished the pipe */ }