示例#1
0
/**
 * Get texture image.  Called by glGetTexImage.
 *
 * \param target texture target.
 * \param level image level.
 * \param format pixel data format for returned image.
 * \param type pixel data type for returned image.
 * \param bufSize size of the pixels data buffer.
 * \param pixels returned pixel data.
 */
void GLAPIENTRY
_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
                   GLenum type, GLvoid *pixels )
{
   struct gl_texture_object *texObj;
   struct gl_texture_image *texImage;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

   if (getteximage_error_check(ctx, target, level, format, type, pixels)) {
      return;
   }

   if (!pixels) {
      /* not an error, do nothing */
      return;
   }

   texObj = _mesa_select_tex_object(ctx, target);
   texImage = _mesa_select_tex_image(ctx, texObj, target, level);

   if (_mesa_is_zero_size_texture(texImage))
      return;

   if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) {
      _mesa_debug(ctx, "glGetTexImage(tex %u) format = %s, w=%d, h=%d,"
                  " dstFmt=0x%x, dstType=0x%x\n",
                  texObj->Name,
                  _mesa_get_format_name(texImage->TexFormat),
                  texImage->Width, texImage->Height,
                  format, type);
   }

   _mesa_lock_texture(ctx, texObj);
   {
      ctx->Driver.GetTexImage(ctx, format, type, pixels, texImage);
   }
   _mesa_unlock_texture(ctx, texObj);
}
示例#2
0
文件: blend.c 项目: dumbbell/mesa
/**
 * Set separate blend equations for one color buffer/target.
 */
void GLAPIENTRY
_mesa_BlendEquationSeparateiARB(GLuint buf, GLenum modeRGB, GLenum modeA)
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glBlendEquationSeparatei(%u, %s %s)\n", buf,
                  _mesa_enum_to_string(modeRGB),
                  _mesa_enum_to_string(modeA));

   if (buf >= ctx->Const.MaxDrawBuffers) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glBlendEquationSeparatei(buffer=%u)",
                  buf);
      return;
   }

   if (!legal_blend_equation(ctx, modeRGB)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparatei(modeRGB)");
      return;
   }

   if (!legal_blend_equation(ctx, modeA)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparatei(modeA)");
      return;
   }

   if (ctx->Color.Blend[buf].EquationRGB == modeRGB &&
       ctx->Color.Blend[buf].EquationA == modeA)
      return;  /* no change */

   FLUSH_VERTICES(ctx, _NEW_COLOR);
   ctx->Color.Blend[buf].EquationRGB = modeRGB;
   ctx->Color.Blend[buf].EquationA = modeA;
   ctx->Color._BlendEquationPerBuffer = GL_TRUE;

   if (ctx->Driver.BlendEquationSeparatei)
      ctx->Driver.BlendEquationSeparatei(ctx, buf, modeRGB, modeA);
}
示例#3
0
文件: texstorage.c 项目: ndesh26/Mesa
/**
 * Helper used by _mesa_TexStorage1/2/3D().
 */
static void
texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,
           GLsizei width, GLsizei height, GLsizei depth, const char *caller)
{
   struct gl_texture_object *texObj;
   GET_CURRENT_CONTEXT(ctx);

   /* Check target.  This is done here so that texture_storage
    * can receive unsized formats.
    */
   if (!legal_texobj_target(ctx, dims, target)) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "%s(illegal target=%s)",
                  caller, _mesa_enum_to_string(target));
      return;
   }

   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
      _mesa_debug(ctx, "%s %s %d %s %d %d %d\n", caller,
                  _mesa_enum_to_string(target), levels,
                  _mesa_enum_to_string(internalformat),
                  width, height, depth);

   /* Check the format to make sure it is sized. */
   if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "%s(internalformat = %s)", caller,
                  _mesa_enum_to_string(internalformat));
      return;
   }

   texObj = _mesa_get_current_tex_object(ctx, target);
   if (!texObj)
      return;

   texture_storage(ctx, dims, texObj, target, levels,
                   internalformat, width, height, depth, false);
}
void GLAPIENTRY
_mesa_GetnCompressedTexImageARB(GLenum target, GLint level, GLsizei bufSize,
                                GLvoid *img)
{
   struct gl_texture_object *texObj;
   struct gl_texture_image *texImage;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

   if (getcompressedteximage_error_check(ctx, target, level, bufSize, img)) {
      return;
   }

   if (!_mesa_is_bufferobj(ctx->Pack.BufferObj) && !img) {
      /* not an error, do nothing */
      return;
   }

   texObj = _mesa_get_current_tex_object(ctx, target);
   texImage = _mesa_select_tex_image(ctx, texObj, target, level);

   if (_mesa_is_zero_size_texture(texImage))
      return;

   if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) {
      _mesa_debug(ctx,
                  "glGetCompressedTexImage(tex %u) format = %s, w=%d, h=%d\n",
                  texObj->Name,
                  _mesa_get_format_name(texImage->TexFormat),
                  texImage->Width, texImage->Height);
   }

   _mesa_lock_texture(ctx, texObj);
   {
      ctx->Driver.GetCompressedTexImage(ctx, texImage, img);
   }
   _mesa_unlock_texture(ctx, texObj);
}
示例#5
0
文件: depth.c 项目: RAOF/mesa
/**
 * Specified by the GL_EXT_depth_bounds_test extension.
 */
void GLAPIENTRY
_mesa_DepthBoundsEXT( GLclampd zmin, GLclampd zmax )
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glDepthBounds(%f, %f)\n", zmin, zmax);

   if (zmin > zmax) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glDepthBoundsEXT(zmin > zmax)");
      return;
   }

   zmin = CLAMP(zmin, 0.0, 1.0);
   zmax = CLAMP(zmax, 0.0, 1.0);

   if (ctx->Depth.BoundsMin == zmin && ctx->Depth.BoundsMax == zmax)
      return;

   FLUSH_VERTICES(ctx, _NEW_DEPTH);
   ctx->Depth.BoundsMin = (GLfloat) zmin;
   ctx->Depth.BoundsMax = (GLfloat) zmax;
}
示例#6
0
文件: debug.c 项目: aosm/X11
void
_mesa_print_tri_caps( const char *name, GLuint flags )
{
   _mesa_debug(NULL,
	   "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
	   name,
	   flags,
	   (flags & DD_FLATSHADE)           ? "flat-shade, " : "",
	   (flags & DD_SEPARATE_SPECULAR)   ? "separate-specular, " : "",
	   (flags & DD_TRI_LIGHT_TWOSIDE)   ? "tri-light-twoside, " : "",
	   (flags & DD_TRI_UNFILLED)        ? "tri-unfilled, " : "",
	   (flags & DD_TRI_STIPPLE)         ? "tri-stipple, " : "",
	   (flags & DD_TRI_OFFSET)          ? "tri-offset, " : "",
	   (flags & DD_TRI_SMOOTH)          ? "tri-smooth, " : "",
	   (flags & DD_LINE_SMOOTH)         ? "line-smooth, " : "",
	   (flags & DD_LINE_STIPPLE)        ? "line-stipple, " : "",
	   (flags & DD_LINE_WIDTH)          ? "line-wide, " : "",
	   (flags & DD_POINT_SMOOTH)        ? "point-smooth, " : "",
	   (flags & DD_POINT_SIZE)          ? "point-size, " : "",
	   (flags & DD_POINT_ATTEN)         ? "point-atten, " : "",
	   (flags & DD_TRI_CULL_FRONT_BACK) ? "cull-all, " : ""
      );
}
示例#7
0
/**
 * Called from glDrawArraysInstancedBaseInstance when in immediate mode.
 */
static void GLAPIENTRY
vbo_exec_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count,
                                         GLsizei numInstances, GLuint baseInstance)
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_DRAW)
      _mesa_debug(ctx, "glDrawArraysInstancedBaseInstance(%s, %d, %d, %d, %d)\n",
                  _mesa_lookup_enum_by_nr(mode), first, count,
                  numInstances, baseInstance);

   if (!_mesa_validate_DrawArraysInstanced(ctx, mode, first, count,
                                           numInstances))
      return;

   if (0)
      check_draw_arrays_data(ctx, first, count);

   vbo_draw_arrays(ctx, mode, first, count, numInstances, baseInstance);

   if (0)
      print_draw_arrays(ctx, mode, first, count);
}
示例#8
0
文件: t_vtx_x86.c 项目: aosm/X11
struct dynfn *tnl_makeX86Attr2f( TNLcontext *tnl, int key )
{
   static  char temp[] = {
      0xba, 0x78, 0x56, 0x34, 0x12,    	/* mov    $DEST,%edx */
      0x8b, 0x44, 0x24, 0x04,          	/* mov    0x4(%esp,1),%eax */
      0x8b, 0x4c, 0x24, 0x08,          	/* mov    0x8(%esp,1),%ecx */
      0x89, 0x02,                	/* mov    %eax,(%edx) */
      0x89, 0x4a, 0x04,             	/* mov    %ecx,0x4(%edx) */
      0xc3,                     	/* ret     */
   };

   struct dynfn *dfn = MALLOC_STRUCT( dynfn );

   if (TNL_DEBUG & DEBUG_CODEGEN)
      _mesa_debug(NULL,  "%s 0x%08x\n", __FUNCTION__, key );

   insert_at_head( &tnl->dfn_cache.TexCoord2f, dfn );
   dfn->key = key;
   dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
   memcpy (dfn->code, temp, sizeof(temp));
   FIXUP(dfn->code, 1, 0x12345678, (int)tnl->texcoordptr[0]); 
   return dfn;
}
示例#9
0
/**
 * Specify whether to cull front- or back-facing facets.
 *
 * \param mode culling mode.
 *
 * \sa glCullFace().
 *
 * Verifies the parameter and updates gl_polygon_attrib::CullFaceMode. On
 * change, flushes the vertices and notifies the driver via
 * the dd_function_table::CullFace callback.
 */
void GLAPIENTRY
_mesa_CullFace( GLenum mode )
{
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (MESA_VERBOSE&VERBOSE_API)
      _mesa_debug(ctx, "glCullFace %s\n", _mesa_lookup_enum_by_nr(mode));

   if (mode!=GL_FRONT && mode!=GL_BACK && mode!=GL_FRONT_AND_BACK) {
      _mesa_error( ctx, GL_INVALID_ENUM, "glCullFace" );
      return;
   }

   if (ctx->Polygon.CullFaceMode == mode)
      return;

   FLUSH_VERTICES(ctx, _NEW_POLYGON);
   ctx->Polygon.CullFaceMode = mode;

   if (ctx->Driver.CullFace)
      ctx->Driver.CullFace( ctx, mode );
}
示例#10
0
static void vbo_print_vertex_list( struct gl_context *ctx, void *data )
{
   struct vbo_save_vertex_list *node = (struct vbo_save_vertex_list *)data;
   GLuint i;
   (void) ctx;

   printf("VBO-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n",
	  node->count,
	  node->prim_count,
	  node->vertex_size);

   for (i = 0 ; i < node->prim_count ; i++) {
      struct _mesa_prim *prim = &node->prim[i];
      _mesa_debug(NULL, "   prim %d: %s%s %d..%d %s %s\n",
		  i, 
		  _mesa_lookup_prim_by_nr(prim->mode),
		  prim->weak ? " (weak)" : "",
		  prim->start, 
		  prim->start + prim->count,
		  (prim->begin) ? "BEGIN" : "(wrap)",
		  (prim->end) ? "END" : "(wrap)");
   }
}
示例#11
0
/*
 * Called whenever we find an error during parsing.
 */
static void
record_error(struct parse_state *parseState, const char *msg, int lineNo)
{
#ifdef DEBUG
   GLint line, column;
   const GLubyte *lineStr;
   lineStr = _mesa_find_line_column(parseState->start,
                                    parseState->pos, &line, &column);
   _mesa_debug(parseState->ctx,
               "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
               lineNo, line, column, (char *) lineStr, msg);
   _mesa_free((void *) lineStr);
#else
   (void) lineNo;
#endif

   /* Check that no error was already recorded.  Only record the first one. */
   if (parseState->ctx->Program.ErrorString[0] == 0) {
      _mesa_set_program_error(parseState->ctx,
                              parseState->pos - parseState->start,
                              msg);
   }
}
static void GLAPIENTRY
_mesa_GenQueriesARB(GLsizei n, GLuint *ids)
{
   GLuint first;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glGenQueries(%d)\n", n);

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGenQueriesARB(n < 0)");
      return;
   }

   /* No query objects can be active at this time! */
   if (ctx->Query.CurrentOcclusionObject ||
       ctx->Query.CurrentTimerObject) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glGenQueriesARB");
      return;
   }

   first = _mesa_HashFindFreeKeyBlock(ctx->Query.QueryObjects, n);
   if (first) {
      GLsizei i;
      for (i = 0; i < n; i++) {
         struct gl_query_object *q
            = ctx->Driver.NewQueryObject(ctx, first + i);
         if (!q) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenQueriesARB");
            return;
         }
         ids[i] = first + i;
         _mesa_HashInsert(ctx->Query.QueryObjects, first + i, q);
      }
   }
}
示例#13
0
文件: blend.c 项目: ndesh26/Mesa
/**
 * Enable or disable writing of frame buffer color components.
 *
 * \param red whether to mask writing of the red color component.
 * \param green whether to mask writing of the green color component.
 * \param blue whether to mask writing of the blue color component.
 * \param alpha whether to mask writing of the alpha color component.
 *
 * \sa glColorMask().
 *
 * Sets the appropriate value of gl_colorbuffer_attrib::ColorMask.  On a
 * change, flushes the vertices and notifies the driver via the
 * dd_function_table::ColorMask callback.
 */
void GLAPIENTRY
_mesa_ColorMask( GLboolean red, GLboolean green,
                 GLboolean blue, GLboolean alpha )
{
   GET_CURRENT_CONTEXT(ctx);
   GLubyte tmp[4];
   GLuint i;
   GLboolean flushed;

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glColorMask(%d, %d, %d, %d)\n",
                  red, green, blue, alpha);

   /* Shouldn't have any information about channel depth in core mesa
    * -- should probably store these as the native booleans:
    */
   tmp[RCOMP] = red    ? 0xff : 0x0;
   tmp[GCOMP] = green  ? 0xff : 0x0;
   tmp[BCOMP] = blue   ? 0xff : 0x0;
   tmp[ACOMP] = alpha  ? 0xff : 0x0;

   flushed = GL_FALSE;
   for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) {
      if (!TEST_EQ_4V(tmp, ctx->Color.ColorMask[i])) {
         if (!flushed) {
            FLUSH_VERTICES(ctx, ctx->DriverFlags.NewColorMask ? 0 : _NEW_COLOR);
            ctx->NewDriverState |= ctx->DriverFlags.NewColorMask;
         }
         flushed = GL_TRUE;
         COPY_4UBV(ctx->Color.ColorMask[i], tmp);
      }
   }

   if (ctx->Driver.ColorMask)
      ctx->Driver.ColorMask( ctx, red, green, blue, alpha );
}
示例#14
0
文件: blend.c 项目: ndesh26/Mesa
/**
 * Specify the alpha test function.
 *
 * \param func alpha comparison function.
 * \param ref reference value.
 *
 * Verifies the parameters and updates gl_colorbuffer_attrib. 
 * On a change, flushes the vertices and notifies the driver via
 * dd_function_table::AlphaFunc callback.
 */
void GLAPIENTRY
_mesa_AlphaFunc( GLenum func, GLclampf ref )
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glAlphaFunc(%s, %f)\n",
                  _mesa_enum_to_string(func), ref);

   if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRefUnclamped == ref)
      return; /* no change */

   switch (func) {
   case GL_NEVER:
   case GL_LESS:
   case GL_EQUAL:
   case GL_LEQUAL:
   case GL_GREATER:
   case GL_NOTEQUAL:
   case GL_GEQUAL:
   case GL_ALWAYS:
      FLUSH_VERTICES(ctx, ctx->DriverFlags.NewAlphaTest ? 0 : _NEW_COLOR);
      ctx->NewDriverState |= ctx->DriverFlags.NewAlphaTest;
      ctx->Color.AlphaFunc = func;
      ctx->Color.AlphaRefUnclamped = ref;
      ctx->Color.AlphaRef = CLAMP(ref, 0.0F, 1.0F);

      if (ctx->Driver.AlphaFunc)
         ctx->Driver.AlphaFunc(ctx, func, ctx->Color.AlphaRef);
      return;

   default:
      _mesa_error( ctx, GL_INVALID_ENUM, "glAlphaFunc(func)" );
      return;
   }
}
示例#15
0
/* 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];
   }
}
/**
 * New with GL_EXT_timer_query
 */
static void GLAPIENTRY
_mesa_GetQueryObjectui64vEXT(GLuint id, GLenum pname, GLuint64EXT *params)
{
   struct gl_query_object *q = NULL;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glGetQueryObjectui64v(%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,
                  "glGetQueryObjectuui64vARB(id=%d is invalid or active)", id);
      return;
   }

   switch (pname) {
      case GL_QUERY_RESULT_ARB:
         if (!q->Ready)
            ctx->Driver.WaitQuery(ctx, q);
         *params = 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, "glGetQueryObjectui64vARB(pname)");
         return;
   }
}
示例#17
0
void GLAPIENTRY
_mesa_DispatchComputeGroupSizeARB(GLuint num_groups_x, GLuint num_groups_y,
                                  GLuint num_groups_z, GLuint group_size_x,
                                  GLuint group_size_y, GLuint group_size_z)
{
   GET_CURRENT_CONTEXT(ctx);
   const GLuint num_groups[3] = { num_groups_x, num_groups_y, num_groups_z };
   const GLuint group_size[3] = { group_size_x, group_size_y, group_size_z };

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx,
                  "glDispatchComputeGroupSizeARB(%d, %d, %d, %d, %d, %d)\n",
                  num_groups_x, num_groups_y, num_groups_z,
                  group_size_x, group_size_y, group_size_z);

   if (!_mesa_validate_DispatchComputeGroupSizeARB(ctx, num_groups,
                                                   group_size))
      return;

   if (num_groups_x == 0u || num_groups_y == 0u || num_groups_z == 0u)
       return;

   ctx->Driver.DispatchComputeGroupSize(ctx, num_groups, group_size);
}
示例#18
0
/**
 * Specify the alpha test function.
 *
 * \param func alpha comparison function.
 * \param ref reference value.
 *
 * Verifies the parameters and updates gl_colorbuffer_attrib.
 * On a change, flushes the vertices and notifies the driver via
 * dd_function_table::AlphaFunc callback.
 */
void GLAPIENTRY
_mesa_AlphaFunc( GLenum func, GLclampf ref )
{
    GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END(ctx);

    if (MESA_VERBOSE & VERBOSE_API)
        _mesa_debug(ctx, "glAlphaFunc(%s, %f)\n",
                    _mesa_lookup_enum_by_nr(func), ref);

    switch (func) {
    case GL_NEVER:
    case GL_LESS:
    case GL_EQUAL:
    case GL_LEQUAL:
    case GL_GREATER:
    case GL_NOTEQUAL:
    case GL_GEQUAL:
    case GL_ALWAYS:
        if (ctx->Color.AlphaFunc == func && ctx->Color.AlphaRefUnclamped == ref)
            return; /* no change */

        FLUSH_VERTICES(ctx, _NEW_COLOR);
        ctx->Color.AlphaFunc = func;
        ctx->Color.AlphaRefUnclamped = ref;
        ctx->Color.AlphaRef = CLAMP(ref, 0.0F, 1.0F);

        if (ctx->Driver.AlphaFunc)
            ctx->Driver.AlphaFunc(ctx, func, ctx->Color.AlphaRef);
        return;

    default:
        _mesa_error( ctx, GL_INVALID_ENUM, "glAlphaFunc(func)" );
        return;
    }
}
示例#19
0
文件: bufferobj.c 项目: GYGit/reactos
/**
 * Generate a set of unique buffer object IDs and store them in \c buffer.
 * 
 * \param n       Number of IDs to generate.
 * \param buffer  Array of \c n locations to store the IDs.
 */
void GLAPIENTRY
_mesa_GenBuffersARB(GLsizei n, GLuint *buffer)
{
   GET_CURRENT_CONTEXT(ctx);
   GLuint first;
   GLint i;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glGenBuffers(%d)\n", n);

   if (n < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGenBuffersARB");
      return;
   }

   if (!buffer) {
      return;
   }

   /*
    * This must be atomic (generation and allocation of buffer object IDs)
    */
   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);

   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->BufferObjects, n);

   /* Insert the ID and pointer to dummy buffer object into hash table */
   for (i = 0; i < n; i++) {
      _mesa_HashInsert(ctx->Shared->BufferObjects, first + i,
                       &DummyBufferObject);
      buffer[i] = first + i;
   }

   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
}
示例#20
0
文件: t_vtx_x86.c 项目: aosm/X11
struct dynfn *tnl_makeX86Attr4ub( TNLcontext *tnl, int key )
{
   if (TNL_DEBUG & DEBUG_CODEGEN)
      _mesa_debug(NULL,  "%s 0x%08x\n", __FUNCTION__, key );

   if (key & TNL_CP_VC_FRMT_PKCOLOR) {
      /* XXX push/pop */
      static  char temp[] = {
	 0x53,                     	/* push   %ebx */
	 0x8b, 0x44, 0x24, 0x08,          	/* mov    0x8(%esp,1),%eax */
	 0x8b, 0x54, 0x24, 0x0c,          	/* mov    0xc(%esp,1),%edx */
	 0x8b, 0x4c, 0x24, 0x10,          	/* mov    0x10(%esp,1),%ecx */
	 0x8b, 0x5c, 0x24, 0x14,          	/* mov    0x14(%esp,1),%ebx */
	 0xa2, 0, 0, 0, 0,		/* mov    %al,DEST */
	 0x88, 0x15, 0, 0, 0, 0,	/* mov    %dl,DEST+1 */
	 0x88, 0x0d, 0, 0, 0, 0,	/* mov    %cl,DEST+2 */
	 0x88, 0x1d, 0, 0, 0, 0,	/* mov    %bl,DEST+3 */
	 0x5b,                      	/* pop    %ebx */
	 0xc3,                     	/* ret     */
      };

      struct dynfn *dfn = MALLOC_STRUCT( dynfn );
      insert_at_head( &tnl->dfn_cache.Color4ub, dfn );
      dfn->key = key;

      dfn->code = ALIGN_MALLOC( sizeof(temp), 16 );
      memcpy (dfn->code, temp, sizeof(temp));
      FIXUP(dfn->code, 18, 0x0, (int)tnl->ubytecolorptr); 
      FIXUP(dfn->code, 24, 0x0, (int)tnl->ubytecolorptr+1); 
      FIXUP(dfn->code, 30, 0x0, (int)tnl->ubytecolorptr+2); 
      FIXUP(dfn->code, 36, 0x0, (int)tnl->ubytecolorptr+3); 
      return dfn;
   }
   else
      return 0;
}
示例#21
0
void GLAPIENTRY
_mesa_GetProgramResourceiv(GLuint program, GLenum programInterface,
                           GLuint index, GLsizei propCount,
                           const GLenum *props, GLsizei bufSize,
                           GLsizei *length, GLint *params)
{
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API) {
      _mesa_debug(ctx, "glGetProgramResourceiv(%u, %s, %u, %d, %p, %d, %p, %p)\n",
                  program, _mesa_enum_to_string(programInterface), index,
                  propCount, props, bufSize, length, params);
   }

   struct gl_shader_program *shProg =
      _mesa_lookup_shader_program_err(ctx, program, "glGetProgramResourceiv");

   if (!shProg || !params)
      return;

   /* The error INVALID_VALUE is generated if <propCount> is zero.
    * Note that we check < 0 here because it makes sense to bail early.
    */
   if (propCount <= 0) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glGetProgramResourceiv(propCount <= 0)");
      return;
   }

   /* No need to write any properties, user requested none. */
   if (bufSize == 0)
      return;

   _mesa_get_program_resourceiv(shProg, programInterface, index,
                                propCount, props, bufSize, length, params);
}
示例#22
0
文件: viewport.c 项目: ndesh26/Mesa
/**
 * Update a range DepthRange values
 *
 * \param first   starting array index
 * \param count   count of DepthRange items to update
 * \param v       pointer to memory containing
 *                GLclampd near and far clip-plane values
 */
void GLAPIENTRY
_mesa_DepthRangeArrayv(GLuint first, GLsizei count, const GLclampd *v)
{
   int i;
   const struct gl_depthrange_inputs *const p =
      (struct gl_depthrange_inputs *) v;
   GET_CURRENT_CONTEXT(ctx);

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glDepthRangeArrayv %d %d\n", first, count);

   if ((first + count) > ctx->Const.MaxViewports) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glDepthRangev: first (%d) + count (%d) >= MaxViewports (%d)",
                  first, count, ctx->Const.MaxViewports);
      return;
   }

   for (i = 0; i < count; i++)
      set_depth_range_no_notify(ctx, i + first, p[i].Near, p[i].Far);

   if (ctx->Driver.DepthRange)
      ctx->Driver.DepthRange(ctx);
}
示例#23
0
文件: texobj.c 项目: RAOF/mesa
/**
 * 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;
}
示例#24
0
文件: blend.c 项目: etnaviv/mesa
void GLAPIENTRY
_mesa_BlendEquationSeparate( GLenum modeRGB, GLenum modeA )
{
   GET_CURRENT_CONTEXT(ctx);
   const unsigned numBuffers = num_buffers(ctx);
   unsigned buf;
   bool changed = false;

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glBlendEquationSeparateEXT(%s %s)\n",
                  _mesa_enum_to_string(modeRGB),
                  _mesa_enum_to_string(modeA));

   if (ctx->Color._BlendEquationPerBuffer) {
      /* Check all per-buffer states */
      for (buf = 0; buf < numBuffers; buf++) {
         if (ctx->Color.Blend[buf].EquationRGB != modeRGB ||
             ctx->Color.Blend[buf].EquationA != modeA) {
            changed = true;
            break;
         }
      }
   }
   else {
      /* only need to check 0th per-buffer state */
      if (ctx->Color.Blend[0].EquationRGB != modeRGB ||
          ctx->Color.Blend[0].EquationA != modeA) {
         changed = true;
      }
   }

   if (!changed)
      return;

   if ( (modeRGB != modeA) && !ctx->Extensions.EXT_blend_equation_separate ) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
		  "glBlendEquationSeparateEXT not supported by driver");
      return;
   }

   /* Only allow simple blending equations.
    * The GL_KHR_blend_equation_advanced spec says:
    *
    *    "NOTE: These enums are not accepted by the <modeRGB> or <modeAlpha>
    *     parameters of BlendEquationSeparate or BlendEquationSeparatei."
    */
   if (!legal_simple_blend_equation(ctx, modeRGB)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeRGB)");
      return;
   }

   if (!legal_simple_blend_equation(ctx, modeA)) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBlendEquationSeparateEXT(modeA)");
      return;
   }

   FLUSH_VERTICES(ctx, _NEW_COLOR);

   for (buf = 0; buf < numBuffers; buf++) {
      ctx->Color.Blend[buf].EquationRGB = modeRGB;
      ctx->Color.Blend[buf].EquationA = modeA;
   }
   ctx->Color._BlendEquationPerBuffer = GL_FALSE;
   ctx->Color._AdvancedBlendMode = BLEND_NONE;

   if (ctx->Driver.BlendEquationSeparate)
      ctx->Driver.BlendEquationSeparate(ctx, modeRGB, modeA);
}
示例#25
0
/**
 * Bind a named texture to a texturing target.
 * 
 * \param target texture target.
 * \param texName texture name.
 * 
 * \sa glBindTexture().
 *
 * Determines the old texture object bound and returns immediately if rebinding
 * the same texture.  Get the current texture which is either a default texture
 * if name is null, a named texture from the hash, or a new texture if the
 * given texture name is new. Increments its reference count, binds it, and
 * calls dd_function_table::BindTexture. Decrements the old texture reference
 * count and deletes it if it reaches zero.
 */
void GLAPIENTRY
_mesa_BindTexture( GLenum target, GLuint texName )
{
   GET_CURRENT_CONTEXT(ctx);
   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
   struct gl_texture_object *newTexObj = NULL;
   GLint targetIndex;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
      _mesa_debug(ctx, "glBindTexture %s %d\n",
                  _mesa_lookup_enum_by_nr(target), (GLint) texName);

   targetIndex = target_enum_to_index(ctx, target);
   if (targetIndex < 0) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target)");
      return;
   }
   assert(targetIndex < NUM_TEXTURE_TARGETS);

   /*
    * Get pointer to new texture object (newTexObj)
    */
   if (texName == 0) {
      /* Use a default texture object */
      newTexObj = ctx->Shared->DefaultTex[targetIndex];
   }
   else {
      /* non-default texture object */
      newTexObj = _mesa_lookup_texture(ctx, texName);
      if (newTexObj) {
         /* error checking */
         if (newTexObj->Target != 0 && newTexObj->Target != target) {
            /* the named texture object's target doesn't match the given target */
            _mesa_error( ctx, GL_INVALID_OPERATION,
                         "glBindTexture(target mismatch)" );
            return;
         }
         if (newTexObj->Target == 0) {
            finish_texture_init(ctx, target, newTexObj);
         }
      }
      else {
         if (ctx->API == API_OPENGL_CORE) {
            _mesa_error(ctx, GL_INVALID_OPERATION, "glBindTexture");
            return;
         }

         /* if this is a new texture id, allocate a texture object now */
         newTexObj = ctx->Driver.NewTextureObject(ctx, texName, target);
         if (!newTexObj) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture");
            return;
         }

         /* and insert it into hash table */
         _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
         _mesa_HashInsert(ctx->Shared->TexObjects, texName, newTexObj);
         _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
      }
      newTexObj->Target = target;
   }

   assert(valid_texture_object(newTexObj));

   /* Check if this texture is only used by this context and is already bound.
    * If so, just return.
    */
   {
      GLboolean early_out;
      _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
      early_out = ((ctx->Shared->RefCount == 1)
                   && (newTexObj == texUnit->CurrentTex[targetIndex]));
      _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
      if (early_out) {
         return;
      }
   }

   /* flush before changing binding */
   FLUSH_VERTICES(ctx, _NEW_TEXTURE);

   /* Do the actual binding.  The refcount on the previously bound
    * texture object will be decremented.  It'll be deleted if the
    * count hits zero.
    */
   _mesa_reference_texobj(&texUnit->CurrentTex[targetIndex], newTexObj);
   ASSERT(texUnit->CurrentTex[targetIndex]);

   /* Pass BindTexture call to device driver */
   if (ctx->Driver.BindTexture)
      ctx->Driver.BindTexture(ctx, target, newTexObj);
}
示例#26
0
文件: blend.c 项目: etnaviv/mesa
/**
 * Set the separate blend source/dest factors for all draw buffers.
 *
 * \param sfactorRGB RGB source factor operator.
 * \param dfactorRGB RGB destination factor operator.
 * \param sfactorA alpha source factor operator.
 * \param dfactorA alpha destination factor operator.
 */
void GLAPIENTRY
_mesa_BlendFuncSeparate( GLenum sfactorRGB, GLenum dfactorRGB,
                            GLenum sfactorA, GLenum dfactorA )
{
   GET_CURRENT_CONTEXT(ctx);
   const unsigned numBuffers = num_buffers(ctx);
   unsigned buf;
   bool changed = false;

   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "glBlendFuncSeparate %s %s %s %s\n",
                  _mesa_enum_to_string(sfactorRGB),
                  _mesa_enum_to_string(dfactorRGB),
                  _mesa_enum_to_string(sfactorA),
                  _mesa_enum_to_string(dfactorA));

   /* Check if we're really changing any state.  If not, return early. */
   if (ctx->Color._BlendFuncPerBuffer) {
      /* Check all per-buffer states */
      for (buf = 0; buf < numBuffers; buf++) {
         if (ctx->Color.Blend[buf].SrcRGB != sfactorRGB ||
             ctx->Color.Blend[buf].DstRGB != dfactorRGB ||
             ctx->Color.Blend[buf].SrcA != sfactorA ||
             ctx->Color.Blend[buf].DstA != dfactorA) {
            changed = true;
            break;
         }
      }
   }
   else {
      /* only need to check 0th per-buffer state */
      if (ctx->Color.Blend[0].SrcRGB != sfactorRGB ||
          ctx->Color.Blend[0].DstRGB != dfactorRGB ||
          ctx->Color.Blend[0].SrcA != sfactorA ||
          ctx->Color.Blend[0].DstA != dfactorA) {
         changed = true;
      }
   }

   if (!changed)
      return;

   if (!validate_blend_factors(ctx, "glBlendFuncSeparate",
                               sfactorRGB, dfactorRGB,
                               sfactorA, dfactorA)) {
      return;
   }

   FLUSH_VERTICES(ctx, _NEW_COLOR);

   for (buf = 0; buf < numBuffers; buf++) {
      ctx->Color.Blend[buf].SrcRGB = sfactorRGB;
      ctx->Color.Blend[buf].DstRGB = dfactorRGB;
      ctx->Color.Blend[buf].SrcA = sfactorA;
      ctx->Color.Blend[buf].DstA = dfactorA;
   }

   update_uses_dual_src(ctx, 0);
   for (buf = 1; buf < numBuffers; buf++) {
      ctx->Color.Blend[buf]._UsesDualSrc = ctx->Color.Blend[0]._UsesDualSrc;
   }

   ctx->Color._BlendFuncPerBuffer = GL_FALSE;

   if (ctx->Driver.BlendFuncSeparate) {
      ctx->Driver.BlendFuncSeparate(ctx, sfactorRGB, dfactorRGB,
                                    sfactorA, dfactorA);
   }
}
示例#27
0
/**
 * 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);
   const GLuint clientUnit = ctx->Array.ActiveTexture;
   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:
         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Ptr;
         break;
      case GL_NORMAL_ARRAY_POINTER:
         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Ptr;
         break;
      case GL_COLOR_ARRAY_POINTER:
         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Ptr;
         break;
      case GL_SECONDARY_COLOR_ARRAY_POINTER_EXT:
         if (ctx->API != API_OPENGL_COMPAT)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Ptr;
         break;
      case GL_FOG_COORDINATE_ARRAY_POINTER_EXT:
         if (ctx->API != API_OPENGL_COMPAT)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_FOG].Ptr;
         break;
      case GL_INDEX_ARRAY_POINTER:
         if (ctx->API != API_OPENGL_COMPAT)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Ptr;
         break;
      case GL_TEXTURE_COORD_ARRAY_POINTER:
         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_TEX(clientUnit)].Ptr;
         break;
      case GL_EDGE_FLAG_ARRAY_POINTER:
         if (ctx->API != API_OPENGL_COMPAT)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Ptr;
         break;
      case GL_FEEDBACK_BUFFER_POINTER:
         if (ctx->API != API_OPENGL_COMPAT)
            goto invalid_pname;
         *params = ctx->Feedback.Buffer;
         break;
      case GL_SELECTION_BUFFER_POINTER:
         if (ctx->API != API_OPENGL_COMPAT)
            goto invalid_pname;
         *params = ctx->Select.Buffer;
         break;
      case GL_POINT_SIZE_ARRAY_POINTER_OES:
         if (ctx->API != API_OPENGLES)
            goto invalid_pname;
         *params = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Ptr;
         break;
      case GL_DEBUG_CALLBACK_FUNCTION_ARB:
         if (!_mesa_is_desktop_gl(ctx))
            goto invalid_pname;
         *params = (GLvoid *) ctx->Debug.Callback;
         break;
      case GL_DEBUG_CALLBACK_USER_PARAM_ARB:
         if (!_mesa_is_desktop_gl(ctx))
            goto invalid_pname;
         *params = ctx->Debug.CallbackData;
         break;
      default:
         goto invalid_pname;
   }

   return;

invalid_pname:
   _mesa_error( ctx, GL_INVALID_ENUM, "glGetPointerv" );
   return;
}
示例#28
0
/**
 * Construct the GL_EXTENSIONS string.  Called the first time that
 * glGetString(GL_EXTENSIONS) is called.
 */
GLubyte*
_mesa_make_extension_string(struct gl_context *ctx)
{
   /* The extension string. */
   char *exts = 0;
   /* Length of extension string. */
   size_t length = 0;
   /* Number of extensions */
   unsigned count;
   /* Indices of the extensions sorted by year */
   extension_index *extension_indices;
   /* String of extra extensions. */
   char *extra_extensions = get_extension_override(ctx);
   GLboolean *base = (GLboolean *) &ctx->Extensions;
   const struct extension *i;
   unsigned j;
   unsigned maxYear = ~0;
   unsigned api_set = (1 << ctx->API);
   if (_mesa_is_gles3(ctx))
      api_set |= ES3;

   /* Check if the MESA_EXTENSION_MAX_YEAR env var is set */
   {
      const char *env = getenv("MESA_EXTENSION_MAX_YEAR");
      if (env) {
         maxYear = atoi(env);
         _mesa_debug(ctx, "Note: limiting GL extensions to %u or earlier\n",
                     maxYear);
      }
   }

   /* Compute length of the extension string. */
   count = 0;
   for (i = extension_table; i->name != 0; ++i) {
      if (base[i->offset] &&
          i->year <= maxYear &&
          (i->api_set & api_set)) {
	 length += strlen(i->name) + 1; /* +1 for space */
	 ++count;
      }
   }
   if (extra_extensions != NULL)
      length += 1 + strlen(extra_extensions); /* +1 for space */

   exts = calloc(ALIGN(length + 1, 4), sizeof(char));
   if (exts == NULL) {
      free(extra_extensions);
      return NULL;
   }

   extension_indices = malloc(count * sizeof(extension_index));
   if (extension_indices == NULL) {
      free(exts);
      free(extra_extensions);
      return NULL;
   }

   /* Sort extensions in chronological order because certain old applications (e.g.,
    * Quake3 demo) store the extension list in a static size buffer so chronologically
    * order ensure that the extensions that such applications expect will fit into
    * that buffer.
    */
   j = 0;
   for (i = extension_table; i->name != 0; ++i) {
      if (base[i->offset] &&
          i->year <= maxYear &&
          (i->api_set & api_set)) {
         extension_indices[j++] = i - extension_table;
      }
   }
   assert(j == count);
   qsort(extension_indices, count, sizeof *extension_indices, extension_compare);

   /* Build the extension string.*/
   for (j = 0; j < count; ++j) {
      i = &extension_table[extension_indices[j]];
      assert(base[i->offset] && (i->api_set & api_set));
      strcat(exts, i->name);
      strcat(exts, " ");
   }
   free(extension_indices);
   if (extra_extensions != 0) {
      strcat(exts, extra_extensions);
      free(extra_extensions);
   }

   return (GLubyte *) exts;
}
示例#29
0
文件: enable.c 项目: toastpp/toastpp
/**
 * Helper function to enable or disable state.
 *
 * \param ctx GL context.
 * \param cap  the state to enable/disable
 * \param state whether to enable or disable the specified capability.
 *
 * Updates the current context and flushes the vertices as needed. For
 * capabilities associated with extensions it verifies that those extensions
 * are effectivly present before updating. Notifies the driver via
 * dd_function_table::Enable.
 */
void
_mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
{
   if (MESA_VERBOSE & VERBOSE_API)
      _mesa_debug(ctx, "%s %s (newstate is %x)\n",
                  state ? "glEnable" : "glDisable",
                  _mesa_lookup_enum_by_nr(cap),
                  ctx->NewState);

   switch (cap) {
      case GL_ALPHA_TEST:
         if (ctx->Color.AlphaEnabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_COLOR);
         ctx->Color.AlphaEnabled = state;
         break;
      case GL_AUTO_NORMAL:
         if (ctx->Eval.AutoNormal == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.AutoNormal = state;
         break;
      case GL_BLEND:
         if (ctx->Color.BlendEnabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_COLOR);
         ctx->Color.BlendEnabled = state;
         break;
#if FEATURE_userclip
      case GL_CLIP_PLANE0:
      case GL_CLIP_PLANE1:
      case GL_CLIP_PLANE2:
      case GL_CLIP_PLANE3:
      case GL_CLIP_PLANE4:
      case GL_CLIP_PLANE5:
         {
            const GLuint p = cap - GL_CLIP_PLANE0;

            if ((ctx->Transform.ClipPlanesEnabled & (1 << p)) == ((GLuint) state << p))
               return;

            FLUSH_VERTICES(ctx, _NEW_TRANSFORM);

            if (state) {
               ctx->Transform.ClipPlanesEnabled |= (1 << p);

               if (_math_matrix_is_dirty(ctx->ProjectionMatrixStack.Top))
                  _math_matrix_analyse( ctx->ProjectionMatrixStack.Top );

               /* This derived state also calculated in clip.c and
                * from _mesa_update_state() on changes to EyeUserPlane
                * and ctx->ProjectionMatrix respectively.
                */
               _mesa_transform_vector( ctx->Transform._ClipUserPlane[p],
                                    ctx->Transform.EyeUserPlane[p],
                                    ctx->ProjectionMatrixStack.Top->inv );
            }
            else {
               ctx->Transform.ClipPlanesEnabled &= ~(1 << p);
            }               
         }
         break;
#endif
      case GL_COLOR_MATERIAL:
         if (ctx->Light.ColorMaterialEnabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_LIGHT);
         FLUSH_CURRENT(ctx, 0);
         ctx->Light.ColorMaterialEnabled = state;
         if (state) {
            _mesa_update_color_material( ctx,
                                  ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
         }
         break;
      case GL_CULL_FACE:
         if (ctx->Polygon.CullFlag == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_POLYGON);
         ctx->Polygon.CullFlag = state;
         break;
      case GL_CULL_VERTEX_EXT:
         CHECK_EXTENSION(EXT_cull_vertex, cap);
         if (ctx->Transform.CullVertexFlag == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
         ctx->Transform.CullVertexFlag = state;
         break;
      case GL_DEPTH_TEST:
         if (ctx->Depth.Test == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_DEPTH);
         ctx->Depth.Test = state;
         break;
      case GL_DITHER:
         if (ctx->NoDither) {
            state = GL_FALSE; /* MESA_NO_DITHER env var */
         }
         if (ctx->Color.DitherFlag == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_COLOR);
         ctx->Color.DitherFlag = state;
         break;
      case GL_FOG:
         if (ctx->Fog.Enabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_FOG);
         ctx->Fog.Enabled = state;
         break;
      case GL_HISTOGRAM:
         CHECK_EXTENSION(EXT_histogram, cap);
         if (ctx->Pixel.HistogramEnabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_PIXEL);
         ctx->Pixel.HistogramEnabled = state;
         break;
      case GL_LIGHT0:
      case GL_LIGHT1:
      case GL_LIGHT2:
      case GL_LIGHT3:
      case GL_LIGHT4:
      case GL_LIGHT5:
      case GL_LIGHT6:
      case GL_LIGHT7:
         if (ctx->Light.Light[cap-GL_LIGHT0].Enabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_LIGHT);
         ctx->Light.Light[cap-GL_LIGHT0].Enabled = state;
         if (state) {
            insert_at_tail(&ctx->Light.EnabledList,
                           &ctx->Light.Light[cap-GL_LIGHT0]);
         }
         else {
            remove_from_list(&ctx->Light.Light[cap-GL_LIGHT0]);
         }
         break;
      case GL_LIGHTING:
         if (ctx->Light.Enabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_LIGHT);
         ctx->Light.Enabled = state;
         if (ctx->Light.Enabled && ctx->Light.Model.TwoSide)
            ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE;
         else
            ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE;
         break;
      case GL_LINE_SMOOTH:
         if (ctx->Line.SmoothFlag == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_LINE);
         ctx->Line.SmoothFlag = state;
         ctx->_TriangleCaps ^= DD_LINE_SMOOTH;
         break;
      case GL_LINE_STIPPLE:
         if (ctx->Line.StippleFlag == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_LINE);
         ctx->Line.StippleFlag = state;
         ctx->_TriangleCaps ^= DD_LINE_STIPPLE;
         break;
      case GL_INDEX_LOGIC_OP:
         if (ctx->Color.IndexLogicOpEnabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_COLOR);
         ctx->Color.IndexLogicOpEnabled = state;
         break;
      case GL_COLOR_LOGIC_OP:
         if (ctx->Color.ColorLogicOpEnabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_COLOR);
         ctx->Color.ColorLogicOpEnabled = state;
         break;
      case GL_MAP1_COLOR_4:
         if (ctx->Eval.Map1Color4 == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map1Color4 = state;
         break;
      case GL_MAP1_INDEX:
         if (ctx->Eval.Map1Index == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map1Index = state;
         break;
      case GL_MAP1_NORMAL:
         if (ctx->Eval.Map1Normal == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map1Normal = state;
         break;
      case GL_MAP1_TEXTURE_COORD_1:
         if (ctx->Eval.Map1TextureCoord1 == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map1TextureCoord1 = state;
         break;
      case GL_MAP1_TEXTURE_COORD_2:
         if (ctx->Eval.Map1TextureCoord2 == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map1TextureCoord2 = state;
         break;
      case GL_MAP1_TEXTURE_COORD_3:
         if (ctx->Eval.Map1TextureCoord3 == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map1TextureCoord3 = state;
         break;
      case GL_MAP1_TEXTURE_COORD_4:
         if (ctx->Eval.Map1TextureCoord4 == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map1TextureCoord4 = state;
         break;
      case GL_MAP1_VERTEX_3:
         if (ctx->Eval.Map1Vertex3 == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map1Vertex3 = state;
         break;
      case GL_MAP1_VERTEX_4:
         if (ctx->Eval.Map1Vertex4 == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map1Vertex4 = state;
         break;
      case GL_MAP2_COLOR_4:
         if (ctx->Eval.Map2Color4 == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map2Color4 = state;
         break;
      case GL_MAP2_INDEX:
         if (ctx->Eval.Map2Index == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map2Index = state;
         break;
      case GL_MAP2_NORMAL:
         if (ctx->Eval.Map2Normal == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map2Normal = state;
         break;
      case GL_MAP2_TEXTURE_COORD_1:
         if (ctx->Eval.Map2TextureCoord1 == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map2TextureCoord1 = state;
         break;
      case GL_MAP2_TEXTURE_COORD_2:
         if (ctx->Eval.Map2TextureCoord2 == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map2TextureCoord2 = state;
         break;
      case GL_MAP2_TEXTURE_COORD_3:
         if (ctx->Eval.Map2TextureCoord3 == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map2TextureCoord3 = state;
         break;
      case GL_MAP2_TEXTURE_COORD_4:
         if (ctx->Eval.Map2TextureCoord4 == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map2TextureCoord4 = state;
         break;
      case GL_MAP2_VERTEX_3:
         if (ctx->Eval.Map2Vertex3 == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map2Vertex3 = state;
         break;
      case GL_MAP2_VERTEX_4:
         if (ctx->Eval.Map2Vertex4 == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_EVAL);
         ctx->Eval.Map2Vertex4 = state;
         break;
      case GL_MINMAX:
         if (ctx->Pixel.MinMaxEnabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_PIXEL);
         ctx->Pixel.MinMaxEnabled = state;
         break;
      case GL_NORMALIZE:
         if (ctx->Transform.Normalize == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
         ctx->Transform.Normalize = state;
         break;
      case GL_POINT_SMOOTH:
         if (ctx->Point.SmoothFlag == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_POINT);
         ctx->Point.SmoothFlag = state;
         ctx->_TriangleCaps ^= DD_POINT_SMOOTH;
         break;
      case GL_POLYGON_SMOOTH:
         if (ctx->Polygon.SmoothFlag == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_POLYGON);
         ctx->Polygon.SmoothFlag = state;
         ctx->_TriangleCaps ^= DD_TRI_SMOOTH;
         break;
      case GL_POLYGON_STIPPLE:
         if (ctx->Polygon.StippleFlag == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_POLYGON);
         ctx->Polygon.StippleFlag = state;
         ctx->_TriangleCaps ^= DD_TRI_STIPPLE;
         break;
      case GL_POLYGON_OFFSET_POINT:
         if (ctx->Polygon.OffsetPoint == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_POLYGON);
         ctx->Polygon.OffsetPoint = state;
         break;
      case GL_POLYGON_OFFSET_LINE:
         if (ctx->Polygon.OffsetLine == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_POLYGON);
         ctx->Polygon.OffsetLine = state;
         break;
      case GL_POLYGON_OFFSET_FILL:
         /*case GL_POLYGON_OFFSET_EXT:*/
         if (ctx->Polygon.OffsetFill == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_POLYGON);
         ctx->Polygon.OffsetFill = state;
         break;
      case GL_RESCALE_NORMAL_EXT:
         if (ctx->Transform.RescaleNormals == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
         ctx->Transform.RescaleNormals = state;
         break;
      case GL_SCISSOR_TEST:
         if (ctx->Scissor.Enabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_SCISSOR);
         ctx->Scissor.Enabled = state;
         break;
      case GL_SHARED_TEXTURE_PALETTE_EXT:
         if (ctx->Texture.SharedPalette == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
         ctx->Texture.SharedPalette = state;
         break;
      case GL_STENCIL_TEST:
         if (ctx->Stencil.Enabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_STENCIL);
         ctx->Stencil.Enabled = state;
         break;
      case GL_TEXTURE_1D:
         if (!enable_texture(ctx, state, TEXTURE_1D_BIT)) {
            return;
         }
         break;
      case GL_TEXTURE_2D:
         if (!enable_texture(ctx, state, TEXTURE_2D_BIT)) {
            return;
         }
         break;
      case GL_TEXTURE_3D:
         if (!enable_texture(ctx, state, TEXTURE_3D_BIT)) {
            return;
         }
         break;
      case GL_TEXTURE_GEN_Q:
         {
            struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
            if (texUnit) {
               GLuint newenabled = texUnit->TexGenEnabled & ~Q_BIT;
               if (state)
                  newenabled |= Q_BIT;
               if (texUnit->TexGenEnabled == newenabled)
                  return;
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
               texUnit->TexGenEnabled = newenabled;
            }
         }
         break;
      case GL_TEXTURE_GEN_R:
         {
            struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
            if (texUnit) {
               GLuint newenabled = texUnit->TexGenEnabled & ~R_BIT;
               if (state)
                  newenabled |= R_BIT;
               if (texUnit->TexGenEnabled == newenabled)
                  return;
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
               texUnit->TexGenEnabled = newenabled;
            }
         }
         break;
      case GL_TEXTURE_GEN_S:
         {
            struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
            if (texUnit) {
               GLuint newenabled = texUnit->TexGenEnabled & ~S_BIT;
               if (state)
                  newenabled |= S_BIT;
               if (texUnit->TexGenEnabled == newenabled)
                  return;
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
               texUnit->TexGenEnabled = newenabled;
            }
         }
         break;
      case GL_TEXTURE_GEN_T:
         {
            struct gl_texture_unit *texUnit = get_texcoord_unit(ctx);
            if (texUnit) {
               GLuint newenabled = texUnit->TexGenEnabled & ~T_BIT;
               if (state)
                  newenabled |= T_BIT;
               if (texUnit->TexGenEnabled == newenabled)
                  return;
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
               texUnit->TexGenEnabled = newenabled;
            }
         }
         break;

      /*
       * CLIENT STATE!!!
       */
      case GL_VERTEX_ARRAY:
      case GL_NORMAL_ARRAY:
      case GL_COLOR_ARRAY:
      case GL_INDEX_ARRAY:
      case GL_TEXTURE_COORD_ARRAY:
      case GL_EDGE_FLAG_ARRAY:
      case GL_FOG_COORDINATE_ARRAY_EXT:
      case GL_SECONDARY_COLOR_ARRAY_EXT:
      case GL_POINT_SIZE_ARRAY_OES:
         client_state( ctx, cap, state );
         return;

      /* GL_SGI_color_table */
      case GL_COLOR_TABLE_SGI:
         CHECK_EXTENSION(SGI_color_table, cap);
         if (ctx->Pixel.ColorTableEnabled[COLORTABLE_PRECONVOLUTION] == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_PIXEL);
         ctx->Pixel.ColorTableEnabled[COLORTABLE_PRECONVOLUTION] = state;
         break;
      case GL_POST_CONVOLUTION_COLOR_TABLE_SGI:
         CHECK_EXTENSION(SGI_color_table, cap);
         if (ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCONVOLUTION] == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_PIXEL);
         ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCONVOLUTION] = state;
         break;
      case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI:
         CHECK_EXTENSION(SGI_color_table, cap);
         if (ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCOLORMATRIX] == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_PIXEL);
         ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCOLORMATRIX] = state;
         break;
      case GL_TEXTURE_COLOR_TABLE_SGI:
         CHECK_EXTENSION(SGI_texture_color_table, cap);
         if (ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
         ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled = state;
         break;

      /* GL_EXT_convolution */
      case GL_CONVOLUTION_1D:
         CHECK_EXTENSION(EXT_convolution, cap);
         if (ctx->Pixel.Convolution1DEnabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_PIXEL);
         ctx->Pixel.Convolution1DEnabled = state;
         break;
      case GL_CONVOLUTION_2D:
         CHECK_EXTENSION(EXT_convolution, cap);
         if (ctx->Pixel.Convolution2DEnabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_PIXEL);
         ctx->Pixel.Convolution2DEnabled = state;
         break;
      case GL_SEPARABLE_2D:
         CHECK_EXTENSION(EXT_convolution, cap);
         if (ctx->Pixel.Separable2DEnabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_PIXEL);
         ctx->Pixel.Separable2DEnabled = state;
         break;

      /* GL_ARB_texture_cube_map */
      case GL_TEXTURE_CUBE_MAP_ARB:
         CHECK_EXTENSION(ARB_texture_cube_map, cap);
         if (!enable_texture(ctx, state, TEXTURE_CUBE_BIT)) {
            return;
         }
         break;

      /* GL_EXT_secondary_color */
      case GL_COLOR_SUM_EXT:
         CHECK_EXTENSION2(EXT_secondary_color, ARB_vertex_program, cap);
         if (ctx->Fog.ColorSumEnabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_FOG);
         ctx->Fog.ColorSumEnabled = state;
         break;

      /* GL_ARB_multisample */
      case GL_MULTISAMPLE_ARB:
         if (ctx->Multisample.Enabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
         ctx->Multisample.Enabled = state;
         break;
      case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
         if (ctx->Multisample.SampleAlphaToCoverage == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
         ctx->Multisample.SampleAlphaToCoverage = state;
         break;
      case GL_SAMPLE_ALPHA_TO_ONE_ARB:
         if (ctx->Multisample.SampleAlphaToOne == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
         ctx->Multisample.SampleAlphaToOne = state;
         break;
      case GL_SAMPLE_COVERAGE_ARB:
         if (ctx->Multisample.SampleCoverage == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
         ctx->Multisample.SampleCoverage = state;
         break;
      case GL_SAMPLE_COVERAGE_INVERT_ARB:
         if (ctx->Multisample.SampleCoverageInvert == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE);
         ctx->Multisample.SampleCoverageInvert = state;
         break;

      /* GL_IBM_rasterpos_clip */
      case GL_RASTER_POSITION_UNCLIPPED_IBM:
         CHECK_EXTENSION(IBM_rasterpos_clip, cap);
         if (ctx->Transform.RasterPositionUnclipped == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
         ctx->Transform.RasterPositionUnclipped = state;
         break;

      /* GL_NV_point_sprite */
      case GL_POINT_SPRITE_NV:
         CHECK_EXTENSION2(NV_point_sprite, ARB_point_sprite, cap);
         if (ctx->Point.PointSprite == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_POINT);
         ctx->Point.PointSprite = state;
         break;

#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
      case GL_VERTEX_PROGRAM_ARB:
         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap);
         if (ctx->VertexProgram.Enabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_PROGRAM); 
         ctx->VertexProgram.Enabled = state;
         break;
      case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap);
         if (ctx->VertexProgram.PointSizeEnabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_PROGRAM);
         ctx->VertexProgram.PointSizeEnabled = state;
         break;
      case GL_VERTEX_PROGRAM_TWO_SIDE_ARB:
         CHECK_EXTENSION2(ARB_vertex_program, NV_vertex_program, cap);
         if (ctx->VertexProgram.TwoSideEnabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_PROGRAM); 
         ctx->VertexProgram.TwoSideEnabled = state;
         break;
#endif
#if FEATURE_NV_vertex_program
      case GL_MAP1_VERTEX_ATTRIB0_4_NV:
      case GL_MAP1_VERTEX_ATTRIB1_4_NV:
      case GL_MAP1_VERTEX_ATTRIB2_4_NV:
      case GL_MAP1_VERTEX_ATTRIB3_4_NV:
      case GL_MAP1_VERTEX_ATTRIB4_4_NV:
      case GL_MAP1_VERTEX_ATTRIB5_4_NV:
      case GL_MAP1_VERTEX_ATTRIB6_4_NV:
      case GL_MAP1_VERTEX_ATTRIB7_4_NV:
      case GL_MAP1_VERTEX_ATTRIB8_4_NV:
      case GL_MAP1_VERTEX_ATTRIB9_4_NV:
      case GL_MAP1_VERTEX_ATTRIB10_4_NV:
      case GL_MAP1_VERTEX_ATTRIB11_4_NV:
      case GL_MAP1_VERTEX_ATTRIB12_4_NV:
      case GL_MAP1_VERTEX_ATTRIB13_4_NV:
      case GL_MAP1_VERTEX_ATTRIB14_4_NV:
      case GL_MAP1_VERTEX_ATTRIB15_4_NV:
         CHECK_EXTENSION(NV_vertex_program, cap);
         {
            const GLuint map = (GLuint) (cap - GL_MAP1_VERTEX_ATTRIB0_4_NV);
            FLUSH_VERTICES(ctx, _NEW_EVAL);
            ctx->Eval.Map1Attrib[map] = state;
         }
         break;
      case GL_MAP2_VERTEX_ATTRIB0_4_NV:
      case GL_MAP2_VERTEX_ATTRIB1_4_NV:
      case GL_MAP2_VERTEX_ATTRIB2_4_NV:
      case GL_MAP2_VERTEX_ATTRIB3_4_NV:
      case GL_MAP2_VERTEX_ATTRIB4_4_NV:
      case GL_MAP2_VERTEX_ATTRIB5_4_NV:
      case GL_MAP2_VERTEX_ATTRIB6_4_NV:
      case GL_MAP2_VERTEX_ATTRIB7_4_NV:
      case GL_MAP2_VERTEX_ATTRIB8_4_NV:
      case GL_MAP2_VERTEX_ATTRIB9_4_NV:
      case GL_MAP2_VERTEX_ATTRIB10_4_NV:
      case GL_MAP2_VERTEX_ATTRIB11_4_NV:
      case GL_MAP2_VERTEX_ATTRIB12_4_NV:
      case GL_MAP2_VERTEX_ATTRIB13_4_NV:
      case GL_MAP2_VERTEX_ATTRIB14_4_NV:
      case GL_MAP2_VERTEX_ATTRIB15_4_NV:
         CHECK_EXTENSION(NV_vertex_program, cap);
         {
            const GLuint map = (GLuint) (cap - GL_MAP2_VERTEX_ATTRIB0_4_NV);
            FLUSH_VERTICES(ctx, _NEW_EVAL);
            ctx->Eval.Map2Attrib[map] = state;
         }
         break;
#endif /* FEATURE_NV_vertex_program */

#if FEATURE_NV_fragment_program
      case GL_FRAGMENT_PROGRAM_NV:
         CHECK_EXTENSION(NV_fragment_program, cap);
         if (ctx->FragmentProgram.Enabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_PROGRAM);
         ctx->FragmentProgram.Enabled = state;
         break;
#endif /* FEATURE_NV_fragment_program */

      /* GL_NV_texture_rectangle */
      case GL_TEXTURE_RECTANGLE_NV:
         CHECK_EXTENSION(NV_texture_rectangle, cap);
         if (!enable_texture(ctx, state, TEXTURE_RECT_BIT)) {
            return;
         }
         break;

      /* GL_EXT_stencil_two_side */
      case GL_STENCIL_TEST_TWO_SIDE_EXT:
         CHECK_EXTENSION(EXT_stencil_two_side, cap);
         if (ctx->Stencil.TestTwoSide == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_STENCIL);
         ctx->Stencil.TestTwoSide = state;
         if (state) {
            ctx->Stencil._BackFace = 2;
            ctx->_TriangleCaps |= DD_TRI_TWOSTENCIL;
         } else {
            ctx->Stencil._BackFace = 1;
            ctx->_TriangleCaps &= ~DD_TRI_TWOSTENCIL;
         }
         break;

#if FEATURE_ARB_fragment_program
      case GL_FRAGMENT_PROGRAM_ARB:
         CHECK_EXTENSION(ARB_fragment_program, cap);
         if (ctx->FragmentProgram.Enabled == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_PROGRAM);
         ctx->FragmentProgram.Enabled = state;
         break;
#endif /* FEATURE_ARB_fragment_program */

      /* GL_EXT_depth_bounds_test */
      case GL_DEPTH_BOUNDS_TEST_EXT:
         CHECK_EXTENSION(EXT_depth_bounds_test, cap);
         if (state && ctx->DrawBuffer->Visual.depthBits == 0) {
            _mesa_warning(ctx,
                   "glEnable(GL_DEPTH_BOUNDS_TEST_EXT) but no depth buffer");
            return;
         }
         if (ctx->Depth.BoundsTest == state)
            return;
         FLUSH_VERTICES(ctx, _NEW_DEPTH);
         ctx->Depth.BoundsTest = state;
         break;

#if FEATURE_ATI_fragment_shader
      case GL_FRAGMENT_SHADER_ATI:
        CHECK_EXTENSION(ATI_fragment_shader, cap);
	if (ctx->ATIFragmentShader.Enabled == state)
	  return;
	FLUSH_VERTICES(ctx, _NEW_PROGRAM);
	ctx->ATIFragmentShader.Enabled = state;
        break;
#endif

      /* GL_MESA_texture_array */
      case GL_TEXTURE_1D_ARRAY_EXT:
         CHECK_EXTENSION(MESA_texture_array, cap);
         if (!enable_texture(ctx, state, TEXTURE_1D_ARRAY_BIT)) {
            return;
         }
         break;

      case GL_TEXTURE_2D_ARRAY_EXT:
         CHECK_EXTENSION(MESA_texture_array, cap);
         if (!enable_texture(ctx, state, TEXTURE_2D_ARRAY_BIT)) {
            return;
         }
         break;

      default:
         _mesa_error(ctx, GL_INVALID_ENUM,
                     "%s(0x%x)", state ? "glEnable" : "glDisable", cap);
         return;
   }

   if (ctx->Driver.Enable) {
      ctx->Driver.Enable( ctx, cap, state );
   }
}
示例#30
0
文件: texenv.c 项目: mariuz/haiku
void GLAPIENTRY
_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
{
   GLuint maxUnit;
   GET_CURRENT_CONTEXT(ctx);
   struct gl_texture_unit *texUnit;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
   if (ctx->Texture.CurrentUnit >= maxUnit) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(current unit)");
      return;
   }

   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];

#define TE_ERROR(errCode, msg, value)				\
   _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value));

   if (target == GL_TEXTURE_ENV) {
      switch (pname) {
      case GL_TEXTURE_ENV_MODE:
         {
            GLenum mode = (GLenum) (GLint) *param;
            if (mode == GL_REPLACE_EXT)
               mode = GL_REPLACE;
	    if (texUnit->EnvMode == mode)
	       return;
            if (mode == GL_MODULATE ||
                mode == GL_BLEND ||
                mode == GL_DECAL ||
                mode == GL_REPLACE ||
                (mode == GL_ADD && ctx->Extensions.EXT_texture_env_add) ||
                (mode == GL_COMBINE &&
                 (ctx->Extensions.EXT_texture_env_combine ||
                  ctx->Extensions.ARB_texture_env_combine))) {
               /* legal */
               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
               texUnit->EnvMode = mode;
            }
            else {
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
               return;
            }
         }
         break;
      case GL_TEXTURE_ENV_COLOR:
         {
            GLfloat tmp[4];
            tmp[0] = CLAMP( param[0], 0.0F, 1.0F );
            tmp[1] = CLAMP( param[1], 0.0F, 1.0F );
            tmp[2] = CLAMP( param[2], 0.0F, 1.0F );
            tmp[3] = CLAMP( param[3], 0.0F, 1.0F );
            if (TEST_EQ_4V(tmp, texUnit->EnvColor))
               return;
            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
            COPY_4FV(texUnit->EnvColor, tmp);
         }
         break;
      case GL_COMBINE_RGB:
	 if (ctx->Extensions.EXT_texture_env_combine ||
             ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum mode = (GLenum) (GLint) *param;
	    if (texUnit->Combine.ModeRGB == mode)
	       return;
	    switch (mode) {
	    case GL_REPLACE:
	    case GL_MODULATE:
	    case GL_ADD:
	    case GL_ADD_SIGNED:
	    case GL_INTERPOLATE:
               /* OK */
	       break;
            case GL_SUBTRACT:
               if (!ctx->Extensions.ARB_texture_env_combine) {
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
                  return;
               }
               break;
	    case GL_DOT3_RGB_EXT:
	    case GL_DOT3_RGBA_EXT:
	       if (!ctx->Extensions.EXT_texture_env_dot3) {
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
		  return;
	       }
	       break;
	    case GL_DOT3_RGB:
	    case GL_DOT3_RGBA:
	       if (!ctx->Extensions.ARB_texture_env_dot3) {
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
		  return;
	       }
	       break;
	    case GL_MODULATE_ADD_ATI:
	    case GL_MODULATE_SIGNED_ADD_ATI:
	    case GL_MODULATE_SUBTRACT_ATI:
	       if (!ctx->Extensions.ATI_texture_env_combine3) {
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
		  return;
	       }
	       break;
	    default:
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
	       return;
	    }
	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	    texUnit->Combine.ModeRGB = mode;
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
         break;
      case GL_COMBINE_ALPHA:
	 if (ctx->Extensions.EXT_texture_env_combine ||
             ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum mode = (GLenum) (GLint) *param;
	    if (texUnit->Combine.ModeA == mode)
	       return;
            switch (mode) {
	    case GL_REPLACE:
	    case GL_MODULATE:
	    case GL_ADD:
	    case GL_ADD_SIGNED:
	    case GL_INTERPOLATE:
	       /* OK */
	       break;
	    case GL_SUBTRACT:
	       if (!ctx->Extensions.ARB_texture_env_combine) {
		  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
		  return;
	       }
	       break;
	    case GL_MODULATE_ADD_ATI:
	    case GL_MODULATE_SIGNED_ADD_ATI:
	    case GL_MODULATE_SUBTRACT_ATI:
	       if (!ctx->Extensions.ATI_texture_env_combine3) {
                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
		  return;
	       }
	       break;
	    default:
	       TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
	       return;
	    }
	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	    texUnit->Combine.ModeA = mode;
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_SOURCE0_RGB:
      case GL_SOURCE1_RGB:
      case GL_SOURCE2_RGB:
	 if (ctx->Extensions.EXT_texture_env_combine ||
	     ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum source = (GLenum) (GLint) *param;
	    const GLuint s = pname - GL_SOURCE0_RGB;
	    if (texUnit->Combine.SourceRGB[s] == source)
	       return;
            if (source == GL_TEXTURE ||
                source == GL_CONSTANT ||
                source == GL_PRIMARY_COLOR ||
                source == GL_PREVIOUS ||
                (ctx->Extensions.ARB_texture_env_crossbar &&
                 source >= GL_TEXTURE0 &&
                 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
                (ctx->Extensions.ATI_texture_env_combine3 &&
                 (source == GL_ZERO || source == GL_ONE))) {
               /* legal */
	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	       texUnit->Combine.SourceRGB[s] = source;
            }
            else {
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
	       return;
	    }
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_SOURCE0_ALPHA:
      case GL_SOURCE1_ALPHA:
      case GL_SOURCE2_ALPHA:
	 if (ctx->Extensions.EXT_texture_env_combine ||
             ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum source = (GLenum) (GLint) *param;
	    const GLuint s = pname - GL_SOURCE0_ALPHA;
	    if (texUnit->Combine.SourceA[s] == source)
	       return;
            if (source == GL_TEXTURE ||
                source == GL_CONSTANT ||
                source == GL_PRIMARY_COLOR ||
                source == GL_PREVIOUS ||
                (ctx->Extensions.ARB_texture_env_crossbar &&
                 source >= GL_TEXTURE0 &&
                 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
		(ctx->Extensions.ATI_texture_env_combine3 &&
                 (source == GL_ZERO || source == GL_ONE))) {
               /* legal */
	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	       texUnit->Combine.SourceA[s] = source;
            }
            else {
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
	       return;
	    }
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_OPERAND0_RGB:
      case GL_OPERAND1_RGB:
	 if (ctx->Extensions.EXT_texture_env_combine ||
	     ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum operand = (GLenum) (GLint) *param;
	    const GLuint s = pname - GL_OPERAND0_RGB;
	    if (texUnit->Combine.OperandRGB[s] == operand)
	       return;
	    switch (operand) {
	    case GL_SRC_COLOR:
	    case GL_ONE_MINUS_SRC_COLOR:
	    case GL_SRC_ALPHA:
	    case GL_ONE_MINUS_SRC_ALPHA:
	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	       texUnit->Combine.OperandRGB[s] = operand;
	       break;
	    default:
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
	       return;
	    }
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_OPERAND0_ALPHA:
      case GL_OPERAND1_ALPHA:
	 if (ctx->Extensions.EXT_texture_env_combine ||
             ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum operand = (GLenum) (GLint) *param;
	    if (texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] == operand)
	       return;
	    switch (operand) {
	    case GL_SRC_ALPHA:
	    case GL_ONE_MINUS_SRC_ALPHA:
	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	       texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] = operand;
	       break;
	    default:
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
	       return;
	    }
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_OPERAND2_RGB:
	 if (ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum operand = (GLenum) (GLint) *param;
	    if (texUnit->Combine.OperandRGB[2] == operand)
	       return;
	    switch (operand) {
	    case GL_SRC_COLOR:           /* ARB combine only */
	    case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */
	    case GL_SRC_ALPHA:
	    case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	       texUnit->Combine.OperandRGB[2] = operand;
               break;
	    default:
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
	       return;
	    }
	 }
	 else if (ctx->Extensions.EXT_texture_env_combine) {
	    const GLenum operand = (GLenum) (GLint) *param;
	    if (texUnit->Combine.OperandRGB[2] == operand)
	       return;
	    /* operand must be GL_SRC_ALPHA which is the initial value - thus
	       don't need to actually compare the operand to the possible value */
	    else {
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
	       return;
	    }
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_OPERAND2_ALPHA:
	 if (ctx->Extensions.ARB_texture_env_combine) {
	    const GLenum operand = (GLenum) (GLint) *param;
	    if (texUnit->Combine.OperandA[2] == operand)
	       return;
	    switch (operand) {
	    case GL_SRC_ALPHA:
	    case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	       texUnit->Combine.OperandA[2] = operand;
	       break;
	    default:
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
	       return;
	    }
	 }
	 else if (ctx->Extensions.EXT_texture_env_combine) {
	    const GLenum operand = (GLenum) (GLint) *param;
	    if (texUnit->Combine.OperandA[2] == operand)
	       return;
	    /* operand must be GL_SRC_ALPHA which is the initial value - thus
	       don't need to actually compare the operand to the possible value */
	    else {
               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
	       return;
	    }
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_RGB_SCALE:
	 if (ctx->Extensions.EXT_texture_env_combine ||
             ctx->Extensions.ARB_texture_env_combine) {
	    GLuint newshift;
	    if (*param == 1.0) {
	       newshift = 0;
	    }
	    else if (*param == 2.0) {
	       newshift = 1;
	    }
	    else if (*param == 4.0) {
	       newshift = 2;
	    }
	    else {
	       _mesa_error( ctx, GL_INVALID_VALUE,
                            "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
	       return;
	    }
	    if (texUnit->Combine.ScaleShiftRGB == newshift)
	       return;
	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	    texUnit->Combine.ScaleShiftRGB = newshift;
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      case GL_ALPHA_SCALE:
	 if (ctx->Extensions.EXT_texture_env_combine ||
             ctx->Extensions.ARB_texture_env_combine) {
	    GLuint newshift;
	    if (*param == 1.0) {
	       newshift = 0;
	    }
	    else if (*param == 2.0) {
	       newshift = 1;
	    }
	    else if (*param == 4.0) {
	       newshift = 2;
	    }
	    else {
	       _mesa_error( ctx, GL_INVALID_VALUE,
                            "glTexEnv(GL_ALPHA_SCALE not 1, 2 or 4)" );
	       return;
	    }
	    if (texUnit->Combine.ScaleShiftA == newshift)
	       return;
	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
	    texUnit->Combine.ScaleShiftA = newshift;
	 }
	 else {
            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	    return;
	 }
	 break;
      default:
	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
	 return;
      }
   }
   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
      /* GL_EXT_texture_lod_bias */
      if (!ctx->Extensions.EXT_texture_lod_bias) {
	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
	 return;
      }
      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
	 if (texUnit->LodBias == param[0])
	    return;
	 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
         texUnit->LodBias = param[0];
      }
      else {
         TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
	 return;
      }
   }
   else if (target == GL_POINT_SPRITE_NV) {
      /* GL_ARB_point_sprite / GL_NV_point_sprite */
      if (!ctx->Extensions.NV_point_sprite
	  && !ctx->Extensions.ARB_point_sprite) {
	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
	 return;
      }
      if (pname == GL_COORD_REPLACE_NV) {
         const GLenum value = (GLenum) param[0];
         if (value == GL_TRUE || value == GL_FALSE) {
            /* It's kind of weird to set point state via glTexEnv,
             * but that's what the spec calls for.
             */
            const GLboolean state = (GLboolean) value;
            if (ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] == state)
               return;
            FLUSH_VERTICES(ctx, _NEW_POINT);
            ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] = state;
         }
         else {
            _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", value);
            return;
         }
      }
      else {
         _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname );
         return;
      }
   }
   else {
      _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)",target );
      return;
   }

   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
      _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n",
                  _mesa_lookup_enum_by_nr(target),
                  _mesa_lookup_enum_by_nr(pname),
                  *param,
                  _mesa_lookup_enum_by_nr((GLenum) (GLint) *param));

   /* Tell device driver about the new texture environment */
   if (ctx->Driver.TexEnv) {
      (*ctx->Driver.TexEnv)( ctx, target, pname, param );
   }
}