void
_mesa_meta_glsl_blit_cleanup(struct gl_context *ctx, struct blit_state *blit)
{
   if (blit->VAO) {
      _mesa_DeleteVertexArrays(1, &blit->VAO);
      blit->VAO = 0;
      _mesa_reference_buffer_object(ctx, &blit->buf_obj, NULL);
   }

   _mesa_meta_blit_shader_table_cleanup(&blit->shaders_with_depth);
   _mesa_meta_blit_shader_table_cleanup(&blit->shaders_without_depth);

   _mesa_DeleteTextures(1, &blit->depthTex.TexObj);
   blit->depthTex.TexObj = 0;
}
Пример #2
0
void
brw_delete_transform_feedback(struct gl_context *ctx,
                              struct gl_transform_feedback_object *obj)
{
   struct brw_transform_feedback_object *brw_obj =
      (struct brw_transform_feedback_object *) obj;

   for (unsigned i = 0; i < ARRAY_SIZE(obj->Buffers); i++) {
      _mesa_reference_buffer_object(ctx, &obj->Buffers[i], NULL);
   }

   drm_intel_bo_unreference(brw_obj->offset_bo);
   drm_intel_bo_unreference(brw_obj->prim_count_bo);

   free(brw_obj);
}
/**
 * Helper for initializing a vertex array.
 */
static void
init_array(struct gl_context *ctx, struct gl_vertex_array *cl,
           unsigned size, const void *pointer)
{
   memset(cl, 0, sizeof(*cl));

   cl->Size = size;
   cl->Type = GL_FLOAT;
   cl->Format = GL_RGBA;
   cl->StrideB = 0;
   cl->_ElementSize = cl->Size * sizeof(GLfloat);
   cl->Ptr = pointer;

   _mesa_reference_buffer_object(ctx, &cl->BufferObj,
                                 ctx->Shared->NullBufferObj);
}
Пример #4
0
/**
 * Initialize texture state for the given context.
 */
GLboolean
_mesa_init_texture(struct gl_context *ctx)
{
    GLuint u;

    /* Texture group */
    ctx->Texture.CurrentUnit = 0;      /* multitexture */

    /* Appendix F.2 of the OpenGL ES 3.0 spec says:
     *
     *     "OpenGL ES 3.0 requires that all cube map filtering be
     *     seamless. OpenGL ES 2.0 specified that a single cube map face be
     *     selected and used for filtering."
     *
     * Unfortunatley, a call to _mesa_is_gles3 below will only work if
     * the driver has already computed and set ctx->Version, however drivers
     * seem to call _mesa_initialize_context (which calls this) early
     * in the CreateContext hook and _mesa_compute_version much later (since
     * it needs information about available extensions). So, we will
     * enable seamless cubemaps by default since GLES2. This should work
     * for most implementations and drivers that don't support seamless
     * cubemaps for GLES2 can still disable it.
     */
    ctx->Texture.CubeMapSeamless = ctx->API == API_OPENGLES2;

    for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++)
        init_texture_unit(ctx, u);

    /* After we're done initializing the context's texture state the default
     * texture objects' refcounts should be at least
     * MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1.
     */
    assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount
           >= MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1);

    /* Allocate proxy textures */
    if (!alloc_proxy_textures( ctx ))
        return GL_FALSE;

    /* GL_ARB_texture_buffer_object */
    _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject,
                                  ctx->Shared->NullBufferObj);

    ctx->Texture.NumCurrentTexUsed = 0;

    return GL_TRUE;
}
Пример #5
0
/**
 * Initialize a gl_array_object's arrays.
 */
void
_mesa_initialize_array_object( struct gl_context *ctx,
			       struct gl_array_object *obj,
			       GLuint name )
{
   GLuint i;

   obj->Name = name;

   _glthread_INIT_MUTEX(obj->Mutex);
   obj->RefCount = 1;

   /* Init the individual arrays */
   for (i = 0; i < Elements(obj->VertexAttrib); i++) {
      switch (i) {
      case VERT_ATTRIB_WEIGHT:
         init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_WEIGHT], 1, GL_FLOAT);
         break;
      case VERT_ATTRIB_NORMAL:
         init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_NORMAL], 3, GL_FLOAT);
         break;
      case VERT_ATTRIB_COLOR1:
         init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_COLOR1], 3, GL_FLOAT);
         break;
      case VERT_ATTRIB_FOG:
         init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_FOG], 1, GL_FLOAT);
         break;
      case VERT_ATTRIB_COLOR_INDEX:
         init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX], 1, GL_FLOAT);
         break;
      case VERT_ATTRIB_EDGEFLAG:
         init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_EDGEFLAG], 1, GL_BOOL);
         break;
#if FEATURE_point_size_array
      case VERT_ATTRIB_POINT_SIZE:
         init_array(ctx, &obj->VertexAttrib[VERT_ATTRIB_POINT_SIZE], 1, GL_FLOAT);
         break;
#endif
      default:
         init_array(ctx, &obj->VertexAttrib[i], 4, GL_FLOAT);
         break;
      }
   }

   _mesa_reference_buffer_object(ctx, &obj->ElementArrayBufferObj,
                                 ctx->Shared->NullBufferObj);
}
Пример #6
0
static void
init_array(struct gl_context *ctx,
           struct gl_client_array *array, GLint size, GLint type)
{
   array->Size = size;
   array->Type = type;
   array->Stride = 0;
   array->StrideB = 0;
   array->Ptr = NULL;
   array->Enabled = GL_FALSE;
   array->Normalized = GL_FALSE;
   array->Integer = GL_FALSE;
   array->_ElementSize = size * _mesa_sizeof_type(type);
   /* Vertex array buffers */
   _mesa_reference_buffer_object(ctx, &array->BufferObj,
                                 ctx->Shared->NullBufferObj);
}
Пример #7
0
/**
 * Copy one client vertex array to another.
 */
void
_mesa_copy_client_array(struct gl_context *ctx,
                        struct gl_client_array *dst,
                        struct gl_client_array *src)
{
   dst->Size = src->Size;
   dst->Type = src->Type;
   dst->Stride = src->Stride;
   dst->StrideB = src->StrideB;
   dst->Ptr = src->Ptr;
   dst->Enabled = src->Enabled;
   dst->Normalized = src->Normalized;
   dst->Integer = src->Integer;
   dst->_ElementSize = src->_ElementSize;
   _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
   dst->_MaxElement = src->_MaxElement;
}
Пример #8
0
GLboolean
_vbo_CreateContext(struct gl_context *ctx)
{
   struct vbo_context *vbo = CALLOC_STRUCT(vbo_context);

   ctx->vbo_context = vbo;

   /* Initialize the arrayelt helper
    */
   if (!ctx->aelt_context &&
       !_ae_create_context(ctx)) {
      return GL_FALSE;
   }

   vbo->binding.Offset = 0;
   vbo->binding.Stride = 0;
   vbo->binding.InstanceDivisor = 0;
   _mesa_reference_buffer_object(ctx, &vbo->binding.BufferObj,
                                 ctx->Shared->NullBufferObj);
   init_legacy_currval(ctx);
   init_generic_currval(ctx);
   init_mat_currval(ctx);
   _vbo_init_inputs(&vbo->draw_arrays);
   vbo_set_indirect_draw_func(ctx, vbo_draw_indirect_prims);

   /* make sure all VBO_ATTRIB_ values can fit in an unsigned byte */
   STATIC_ASSERT(VBO_ATTRIB_MAX <= 255);

   /* Hook our functions into exec and compile dispatch tables.  These
    * will pretty much be permanently installed, which means that the
    * vtxfmt mechanism can be removed now.
    */
   vbo_exec_init(ctx);
   if (ctx->API == API_OPENGL_COMPAT)
      vbo_save_init(ctx);

   vbo->VAO = _mesa_new_vao(ctx, ~((GLuint)0));
   /* The exec VAO assumes to have all arributes bound to binding 0 */
   for (unsigned i = 0; i < VERT_ATTRIB_MAX; ++i)
      _mesa_vertex_attrib_binding(ctx, vbo->VAO, i, 0, false);

   _math_init_eval();

   return GL_TRUE;
}
Пример #9
0
static void init_mat_currval(struct gl_context *ctx)
{
   struct vbo_context *vbo = vbo_context(ctx);
   struct gl_client_array *arrays =
      &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT];
   GLuint i;

   ASSERT(NR_MAT_ATTRIBS == MAT_ATTRIB_MAX);

   memset(arrays, 0, sizeof(*arrays) * NR_MAT_ATTRIBS);

   /* Set up a constant (StrideB == 0) array for each current
    * attribute:
    */
   for (i = 0; i < NR_MAT_ATTRIBS; i++) {
      struct gl_client_array *cl = &arrays[i];

      /* Size is fixed for the material attributes, for others will
       * be determined at runtime:
       */
      switch (i - VERT_ATTRIB_GENERIC0) {
      case MAT_ATTRIB_FRONT_SHININESS:
      case MAT_ATTRIB_BACK_SHININESS:
	 cl->Size = 1;
	 break;
      case MAT_ATTRIB_FRONT_INDEXES:
      case MAT_ATTRIB_BACK_INDEXES:
	 cl->Size = 3;
	 break;
      default:
	 cl->Size = 4;
	 break;
      }

      cl->Ptr = (const void *)ctx->Light.Material.Attrib[i];
      cl->Type = GL_FLOAT;
      cl->Format = GL_RGBA;
      cl->Stride = 0;
      cl->StrideB = 0;
      cl->Enabled = 1;
      cl->_ElementSize = cl->Size * sizeof(GLfloat);
      _mesa_reference_buffer_object(ctx, &cl->BufferObj,
                                    ctx->Shared->NullBufferObj);
   }
}
Пример #10
0
/**
 * Initialize a gl_vertex_array_object's arrays.
 */
void
_mesa_initialize_vao(struct gl_context *ctx,
                     struct gl_vertex_array_object *obj,
                     GLuint name)
{
   GLuint i;

   obj->Name = name;

   mtx_init(&obj->Mutex, mtx_plain);
   obj->RefCount = 1;

   /* Init the individual arrays */
   for (i = 0; i < ARRAY_SIZE(obj->VertexAttrib); i++) {
      switch (i) {
      case VERT_ATTRIB_WEIGHT:
         init_array(ctx, obj, VERT_ATTRIB_WEIGHT, 1, GL_FLOAT);
         break;
      case VERT_ATTRIB_NORMAL:
         init_array(ctx, obj, VERT_ATTRIB_NORMAL, 3, GL_FLOAT);
         break;
      case VERT_ATTRIB_COLOR1:
         init_array(ctx, obj, VERT_ATTRIB_COLOR1, 3, GL_FLOAT);
         break;
      case VERT_ATTRIB_FOG:
         init_array(ctx, obj, VERT_ATTRIB_FOG, 1, GL_FLOAT);
         break;
      case VERT_ATTRIB_COLOR_INDEX:
         init_array(ctx, obj, VERT_ATTRIB_COLOR_INDEX, 1, GL_FLOAT);
         break;
      case VERT_ATTRIB_EDGEFLAG:
         init_array(ctx, obj, VERT_ATTRIB_EDGEFLAG, 1, GL_BOOL);
         break;
      case VERT_ATTRIB_POINT_SIZE:
         init_array(ctx, obj, VERT_ATTRIB_POINT_SIZE, 1, GL_FLOAT);
         break;
      default:
         init_array(ctx, obj, i, 4, GL_FLOAT);
         break;
      }
   }

   _mesa_reference_buffer_object(ctx, &obj->IndexBufferObj,
                                 ctx->Shared->NullBufferObj);
}
Пример #11
0
static void
init_array(GLcontext *ctx,
           struct gl_client_array *array, GLint size, GLint type)
{
   array->Size = size;
   array->Type = type;
   array->Format = GL_RGBA; /* only significant for GL_EXT_vertex_array_bgra */
   array->Stride = 0;
   array->StrideB = 0;
   array->Ptr = NULL;
   array->Enabled = GL_FALSE;
   array->Normalized = GL_FALSE;
#if FEATURE_ARB_vertex_buffer_object
   /* Vertex array buffers */
   _mesa_reference_buffer_object(ctx, &array->BufferObj,
                                 ctx->Shared->NullBufferObj);
#endif
}
Пример #12
0
void vbo_exec_vtx_init( struct vbo_exec_context *exec )
{
   GLcontext *ctx = exec->ctx;
   struct vbo_context *vbo = vbo_context(ctx);
   GLuint i;

   /* Allocate a buffer object.  Will just reuse this object
    * continuously, unless vbo_use_buffer_objects() is called to enable
    * use of real VBOs.
    */
   _mesa_reference_buffer_object(ctx,
                                 &exec->vtx.bufferobj,
                                 ctx->Shared->NullBufferObj);

   ASSERT(!exec->vtx.buffer_map);
   exec->vtx.buffer_map = (GLfloat *)ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE, 64);
   exec->vtx.buffer_ptr = exec->vtx.buffer_map;

   vbo_exec_vtxfmt_init( exec );

   /* Hook our functions into the dispatch table.
    */
   _mesa_install_exec_vtxfmt( exec->ctx, &exec->vtxfmt );

   for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
      ASSERT(i < Elements(exec->vtx.attrsz));
      exec->vtx.attrsz[i] = 0;
      ASSERT(i < Elements(exec->vtx.active_sz));
      exec->vtx.active_sz[i] = 0;
   }
   for (i = 0 ; i < VERT_ATTRIB_MAX; i++) {
      ASSERT(i < Elements(exec->vtx.inputs));
      ASSERT(i < Elements(exec->vtx.arrays));
      exec->vtx.inputs[i] = &exec->vtx.arrays[i];
   }
   
   {
      struct gl_client_array *arrays = exec->vtx.arrays;
      memcpy(arrays,      vbo->legacy_currval,  16 * sizeof(arrays[0]));
      memcpy(arrays + 16, vbo->generic_currval, 16 * sizeof(arrays[0]));
   }

   exec->vtx.vertex_size = 0;
}
Пример #13
0
void
_mesa_meta_glsl_generate_mipmap_cleanup(struct gl_context *ctx,
                                        struct gen_mipmap_state *mipmap)
{
   if (mipmap->VAO == 0)
      return;
   _mesa_DeleteVertexArrays(1, &mipmap->VAO);
   mipmap->VAO = 0;
   _mesa_reference_buffer_object(ctx, &mipmap->buf_obj, NULL);
   _mesa_DeleteSamplers(1, &mipmap->Sampler);
   mipmap->Sampler = 0;

   if (mipmap->FBO != 0) {
      _mesa_DeleteFramebuffers(1, &mipmap->FBO);
      mipmap->FBO = 0;
   }

   _mesa_meta_blit_shader_table_cleanup(&mipmap->shaders);
}
Пример #14
0
static void
st_delete_transform_feedback(struct gl_context *ctx,
                             struct gl_transform_feedback_object *obj)
{
   struct st_transform_feedback_object *sobj =
         st_transform_feedback_object(obj);
   unsigned i;

   pipe_so_target_reference(&sobj->draw_count, NULL);

   /* Unreference targets. */
   for (i = 0; i < sobj->num_targets; i++) {
      pipe_so_target_reference(&sobj->targets[i], NULL);
   }

   for (i = 0; i < Elements(sobj->base.Buffers); i++) {
      _mesa_reference_buffer_object(ctx, &sobj->base.Buffers[i], NULL);
   }

   free(obj);
}
Пример #15
0
void
brw_meta_fast_clear_free(struct brw_context *brw)
{
   struct brw_fast_clear_state *clear = brw->fast_clear_state;
   GET_CURRENT_CONTEXT(old_context);

   if (clear == NULL)
      return;

   _mesa_make_current(&brw->ctx, NULL, NULL);

   _mesa_DeleteVertexArrays(1, &clear->vao);
   _mesa_reference_buffer_object(&brw->ctx, &clear->buf_obj, NULL);
   _mesa_reference_shader_program(&brw->ctx, &clear->shader_prog, NULL);
   free(clear);

   if (old_context)
      _mesa_make_current(old_context, old_context->WinSysDrawBuffer, old_context->WinSysReadBuffer);
   else
      _mesa_make_current(NULL, NULL, NULL);
}
Пример #16
0
/**
 * Per-context free/clean-up for transform feedback.
 */
void
_mesa_free_transform_feedback(struct gl_context *ctx)
{
   /* core mesa expects this, even a dummy one, to be available */
   assert(ctx->Driver.NewTransformFeedback);

   _mesa_reference_buffer_object(ctx,
                                 &ctx->TransformFeedback.CurrentBuffer,
                                 NULL);

   /* Delete all feedback objects */
   _mesa_HashDeleteAll(ctx->TransformFeedback.Objects, delete_cb, ctx);
   _mesa_DeleteHashTable(ctx->TransformFeedback.Objects);

   /* Delete the default feedback object */
   assert(ctx->Driver.DeleteTransformFeedback);
   ctx->Driver.DeleteTransformFeedback(ctx,
                                       ctx->TransformFeedback.DefaultObject);

   ctx->TransformFeedback.CurrentObject = NULL;
}
Пример #17
0
void _vbo_DestroyContext( struct gl_context *ctx )
{
   struct vbo_context *vbo = vbo_context(ctx);

   if (ctx->aelt_context) {
      _ae_destroy_context( ctx );
      ctx->aelt_context = NULL;
   }

   if (vbo) {
      GLuint i;

      for (i = 0; i < VBO_ATTRIB_MAX; i++) {
         _mesa_reference_buffer_object(ctx, &vbo->currval[i].BufferObj, NULL);
      }

      vbo_exec_destroy(ctx);
      vbo_save_destroy(ctx);
      FREE(vbo);
      ctx->swtnl_im = NULL;
   }
}
Пример #18
0
/**
 * Per-context init for transform feedback.
 */
void
_mesa_init_transform_feedback(struct gl_context *ctx)
{
   /* core mesa expects this, even a dummy one, to be available */
   assert(ctx->Driver.NewTransformFeedback);

   ctx->TransformFeedback.DefaultObject =
      ctx->Driver.NewTransformFeedback(ctx, 0);

   assert(ctx->TransformFeedback.DefaultObject->RefCount == 1);

   reference_transform_feedback_object(&ctx->TransformFeedback.CurrentObject,
                                       ctx->TransformFeedback.DefaultObject);

   assert(ctx->TransformFeedback.DefaultObject->RefCount == 2);

   ctx->TransformFeedback.Objects = _mesa_NewHashTable();

   _mesa_reference_buffer_object(ctx,
                                 &ctx->TransformFeedback.CurrentBuffer,
                                 ctx->Shared->NullBufferObj);
}
Пример #19
0
void
_vbo_DestroyContext(struct gl_context *ctx)
{
   struct vbo_context *vbo = vbo_context(ctx);

   if (ctx->aelt_context) {
      _ae_destroy_context(ctx);
      ctx->aelt_context = NULL;
   }

   if (vbo) {

      _mesa_reference_buffer_object(ctx, &vbo->binding.BufferObj, NULL);

      vbo_exec_destroy(ctx);
      if (ctx->API == API_OPENGL_COMPAT)
         vbo_save_destroy(ctx);
      _mesa_reference_vao(ctx, &vbo->VAO, NULL);
      free(vbo);
      ctx->vbo_context = NULL;
   }
}
Пример #20
0
/**
 * Helper used by BindBufferRange() and BindBufferBase().
 */
static void
bind_buffer_range(struct gl_context *ctx,
                  struct gl_transform_feedback_object *obj,
                  GLuint index,
                  struct gl_buffer_object *bufObj,
                  GLintptr offset, GLsizeiptr size,
                  bool dsa)
{
   /* Note: no need to FLUSH_VERTICES or flag NewTransformFeedback, because
    * transform feedback buffers can't be changed while transform feedback is
    * active.
    */

   if (!dsa) {
      /* The general binding point */
      _mesa_reference_buffer_object(ctx,
                                    &ctx->TransformFeedback.CurrentBuffer,
                                    bufObj);
   }

   /* The per-attribute binding point */
   _mesa_set_transform_feedback_binding(ctx, obj, index, bufObj, offset, size);
}
Пример #21
0
/**
 * Tell the VBO module to use a real OpenGL vertex buffer object to
 * store accumulated immediate-mode vertex data.
 * This replaces the malloced buffer which was created in
 * vb_exec_vtx_init() below.
 */
void vbo_use_buffer_objects(struct gl_context *ctx)
{
   struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
   /* Any buffer name but 0 can be used here since this bufferobj won't
    * go into the bufferobj hashtable.
    */
   GLuint bufName = IMM_BUFFER_NAME;
   GLenum target = GL_ARRAY_BUFFER_ARB;
   GLenum usage = GL_STREAM_DRAW_ARB;
   GLsizei size = VBO_VERT_BUFFER_SIZE;

   /* Make sure this func is only used once */
   assert(exec->vtx.bufferobj == ctx->Shared->NullBufferObj);
   if (exec->vtx.buffer_map) {
      _mesa_align_free(exec->vtx.buffer_map);
      exec->vtx.buffer_map = NULL;
      exec->vtx.buffer_ptr = NULL;
   }

   /* Allocate a real buffer object now */
   _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL);
   exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName, target);
   ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj);
}
Пример #22
0
static void init_generic_currval(GLcontext *ctx)
{
   struct vbo_context *vbo = vbo_context(ctx);
   struct gl_client_array *arrays = vbo->generic_currval;
   GLuint i;

   memset(arrays, 0, sizeof(*arrays) * NR_GENERIC_ATTRIBS);

   for (i = 0; i < NR_GENERIC_ATTRIBS; i++) {
      struct gl_client_array *cl = &arrays[i];

      /* This will have to be determined at runtime:
       */
      cl->Size = 1;
      cl->Type = GL_FLOAT;
      cl->Format = GL_RGBA;
      cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i];
      cl->Stride = 0;
      cl->StrideB = 0;
      cl->Enabled = 1;
      _mesa_reference_buffer_object(ctx, &cl->BufferObj,
                                    ctx->Shared->NullBufferObj);
   }
}
Пример #23
0
/**
 * Bind the specified target to buffer for the specified context.
 */
static void
bind_buffer_object(GLcontext *ctx, GLenum target, GLuint buffer)
{
   struct gl_buffer_object *oldBufObj;
   struct gl_buffer_object *newBufObj = NULL;
   struct gl_buffer_object **bindTarget = NULL;

   switch (target) {
   case GL_ARRAY_BUFFER_ARB:
      bindTarget = &ctx->Array.ArrayBufferObj;
      break;
   case GL_ELEMENT_ARRAY_BUFFER_ARB:
      bindTarget = &ctx->Array.ElementArrayBufferObj;
      break;
   case GL_PIXEL_PACK_BUFFER_EXT:
      bindTarget = &ctx->Pack.BufferObj;
      break;
   case GL_PIXEL_UNPACK_BUFFER_EXT:
      bindTarget = &ctx->Unpack.BufferObj;
      break;
   case GL_COPY_READ_BUFFER:
      if (ctx->Extensions.ARB_copy_buffer) {
         bindTarget = &ctx->CopyReadBuffer;
      }
      break;
   case GL_COPY_WRITE_BUFFER:
      if (ctx->Extensions.ARB_copy_buffer) {
         bindTarget = &ctx->CopyWriteBuffer;
      }
      break;
   default:
      ; /* no-op / we'll hit the follow error test next */
   }

   if (!bindTarget) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target 0x%x)");
      return;
   }

   /* Get pointer to old buffer object (to be unbound) */
   oldBufObj = get_buffer(ctx, target);
   if (oldBufObj && oldBufObj->Name == buffer)
      return;   /* rebinding the same buffer object- no change */

   /*
    * Get pointer to new buffer object (newBufObj)
    */
   if (buffer == 0) {
      /* The spec says there's not a buffer object named 0, but we use
       * one internally because it simplifies things.
       */
      newBufObj = ctx->Shared->NullBufferObj;
   }
   else {
      /* non-default buffer object */
      newBufObj = _mesa_lookup_bufferobj(ctx, buffer);
      if (!newBufObj) {
         /* if this is a new buffer object id, allocate a buffer object now */
         ASSERT(ctx->Driver.NewBufferObject);
         newBufObj = ctx->Driver.NewBufferObject(ctx, buffer, target);
         if (!newBufObj) {
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindBufferARB");
            return;
         }
         _mesa_HashInsert(ctx->Shared->BufferObjects, buffer, newBufObj);
      }
   }
   
   /* bind new buffer */
   _mesa_reference_buffer_object(ctx, bindTarget, newBufObj);

   /* Pass BindBuffer call to device driver */
   if (ctx->Driver.BindBuffer)
      ctx->Driver.BindBuffer( ctx, target, newBufObj );
}
Пример #24
0
void vbo_exec_vtx_init( struct vbo_exec_context *exec )
{
   struct gl_context *ctx = exec->ctx;
   struct vbo_context *vbo = vbo_context(ctx);
   GLuint i;

   /* Allocate a buffer object.  Will just reuse this object
    * continuously, unless vbo_use_buffer_objects() is called to enable
    * use of real VBOs.
    */
   _mesa_reference_buffer_object(ctx,
                                 &exec->vtx.bufferobj,
                                 ctx->Shared->NullBufferObj);

   ASSERT(!exec->vtx.buffer_map);
   exec->vtx.buffer_map = (GLfloat *)_mesa_align_malloc(VBO_VERT_BUFFER_SIZE, 64);
   exec->vtx.buffer_ptr = exec->vtx.buffer_map;

   vbo_exec_vtxfmt_init( exec );
   _mesa_noop_vtxfmt_init(&exec->vtxfmt_noop);

   /* Hook our functions into the dispatch table.
    */
   _mesa_install_exec_vtxfmt( ctx, &exec->vtxfmt );

   for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
      ASSERT(i < Elements(exec->vtx.attrsz));
      exec->vtx.attrsz[i] = 0;
      ASSERT(i < Elements(exec->vtx.active_sz));
      exec->vtx.active_sz[i] = 0;
   }
   for (i = 0 ; i < VERT_ATTRIB_MAX; i++) {
      ASSERT(i < Elements(exec->vtx.inputs));
      ASSERT(i < Elements(exec->vtx.arrays));
      exec->vtx.inputs[i] = &exec->vtx.arrays[i];
   }
   
   {
      struct gl_client_array *arrays = exec->vtx.arrays;
      unsigned i;

      memcpy(arrays, vbo->legacy_currval,
             VERT_ATTRIB_FF_MAX * sizeof(arrays[0]));
      for (i = 0; i < VERT_ATTRIB_FF_MAX; ++i) {
         struct gl_client_array *array;
         array = &arrays[VERT_ATTRIB_FF(i)];
         array->BufferObj = NULL;
         _mesa_reference_buffer_object(ctx, &arrays->BufferObj,
                                       vbo->legacy_currval[i].BufferObj);
      }

      memcpy(arrays + VERT_ATTRIB_GENERIC(0), vbo->generic_currval,
             VERT_ATTRIB_GENERIC_MAX * sizeof(arrays[0]));
      for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; ++i) {
         struct gl_client_array *array;
         array = &arrays[VERT_ATTRIB_GENERIC(i)];
         array->BufferObj = NULL;
         _mesa_reference_buffer_object(ctx, &array->BufferObj,
                                       vbo->generic_currval[i].BufferObj);
      }
   }

   exec->vtx.vertex_size = 0;

   exec->begin_vertices_flags = FLUSH_UPDATE_CURRENT;
}
Пример #25
0
/**
 * Free the data associated with the given context.
 * 
 * But doesn't free the GLcontext struct itself.
 *
 * \sa _mesa_initialize_context() and init_attrib_groups().
 */
void
_mesa_free_context_data( GLcontext *ctx )
{
   GLint RefCount;

   if (!_mesa_get_current_context()){
      /* No current context, but we may need one in order to delete
       * texture objs, etc.  So temporarily bind the context now.
       */
      _mesa_make_current(ctx, NULL, NULL);
   }

   /* unreference WinSysDraw/Read buffers */
   _mesa_reference_framebuffer(&ctx->WinSysDrawBuffer, NULL);
   _mesa_reference_framebuffer(&ctx->WinSysReadBuffer, NULL);
   _mesa_reference_framebuffer(&ctx->DrawBuffer, NULL);
   _mesa_reference_framebuffer(&ctx->ReadBuffer, NULL);

   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
   _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL);
   _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL);

   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL);

   _mesa_free_attrib_data(ctx);
   _mesa_free_lighting_data( ctx );
   _mesa_free_eval_data( ctx );
   _mesa_free_texture_data( ctx );
   _mesa_free_matrix_data( ctx );
   _mesa_free_viewport_data( ctx );
   _mesa_free_colortables_data( ctx );
   _mesa_free_program_data(ctx);
   _mesa_free_shader_state(ctx);
   _mesa_free_queryobj_data(ctx);
#if FEATURE_ARB_sync
   _mesa_free_sync_data(ctx);
#endif
   _mesa_free_varray_data(ctx);

   _mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj);

#if FEATURE_ARB_pixel_buffer_object
   _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL);
   _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL);
#endif

#if FEATURE_ARB_vertex_buffer_object
   _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL);
   _mesa_reference_buffer_object(ctx, &ctx->Array.ElementArrayBufferObj, NULL);
#endif

   /* free dispatch tables */
   _mesa_free(ctx->Exec);
   _mesa_free(ctx->Save);

   /* Shared context state (display lists, textures, etc) */
   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
   RefCount = --ctx->Shared->RefCount;
   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
   assert(RefCount >= 0);
   if (RefCount == 0) {
      /* free shared state */
      _mesa_free_shared_state( ctx, ctx->Shared );
   }

   /* needs to be after freeing shared state */
   _mesa_free_display_list_data(ctx);

   if (ctx->Extensions.String)
      _mesa_free((void *) ctx->Extensions.String);

   /* unbind the context if it's currently bound */
   if (ctx == _mesa_get_current_context()) {
      _mesa_make_current(NULL, NULL, NULL);
   }
}
Пример #26
0
/* TODO: populate these as the vertex is defined:
 */
static void
vbo_exec_bind_arrays( struct gl_context *ctx )
{
   struct vbo_context *vbo = vbo_context(ctx);
   struct vbo_exec_context *exec = &vbo->exec;
   struct gl_client_array *arrays = exec->vtx.arrays;
   const GLuint count = exec->vtx.vert_count;
   const GLuint *map;
   GLuint attr;
   GLbitfield64 varying_inputs = 0x0;

   /* Install the default (ie Current) attributes first, then overlay
    * all active ones.
    */
   switch (get_program_mode(exec->ctx)) {
   case VP_NONE:
      for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) {
         exec->vtx.inputs[attr] = &vbo->legacy_currval[attr];
      }
      for (attr = 0; attr < MAT_ATTRIB_MAX; attr++) {
         ASSERT(VERT_ATTRIB_GENERIC(attr) < Elements(exec->vtx.inputs));
         exec->vtx.inputs[VERT_ATTRIB_GENERIC(attr)] = &vbo->mat_currval[attr];
      }
      map = vbo->map_vp_none;
      break;
   case VP_NV:
   case VP_ARB:
      /* The aliasing of attributes for NV vertex programs has already
       * occurred.  NV vertex programs cannot access material values,
       * nor attributes greater than VERT_ATTRIB_TEX7.  
       */
      for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) {
         exec->vtx.inputs[attr] = &vbo->legacy_currval[attr];
      }
      for (attr = 0; attr < VERT_ATTRIB_GENERIC_MAX; attr++) {
         ASSERT(VERT_ATTRIB_GENERIC(attr) < Elements(exec->vtx.inputs));
         exec->vtx.inputs[VERT_ATTRIB_GENERIC(attr)] = &vbo->generic_currval[attr];
      }
      map = vbo->map_vp_arb;

      /* check if VERT_ATTRIB_POS is not read but VERT_BIT_GENERIC0 is read.
       * In that case we effectively need to route the data from
       * glVertexAttrib(0, val) calls to feed into the GENERIC0 input.
       */
      if ((ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_POS) == 0 &&
          (ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_GENERIC0)) {
         exec->vtx.inputs[VERT_ATTRIB_GENERIC0] = exec->vtx.inputs[0];
         exec->vtx.attrsz[VERT_ATTRIB_GENERIC0] = exec->vtx.attrsz[0];
         exec->vtx.attrptr[VERT_ATTRIB_GENERIC0] = exec->vtx.attrptr[0];
         exec->vtx.attrsz[0] = 0;
      }
      break;
   default:
      assert(0);
   }

   /* Make all active attributes (including edgeflag) available as
    * arrays of floats.
    */
   for (attr = 0; attr < VERT_ATTRIB_MAX ; attr++) {
      const GLuint src = map[attr];

      if (exec->vtx.attrsz[src]) {
	 GLsizeiptr offset = (GLbyte *)exec->vtx.attrptr[src] -
	    (GLbyte *)exec->vtx.vertex;

         /* override the default array set above */
         ASSERT(attr < Elements(exec->vtx.inputs));
         ASSERT(attr < Elements(exec->vtx.arrays)); /* arrays[] */
         exec->vtx.inputs[attr] = &arrays[attr];

         if (_mesa_is_bufferobj(exec->vtx.bufferobj)) {
            /* a real buffer obj: Ptr is an offset, not a pointer*/
            assert(exec->vtx.bufferobj->Pointer);  /* buf should be mapped */
            assert(offset >= 0);
            arrays[attr].Ptr = (GLubyte *)exec->vtx.bufferobj->Offset + offset;
         }
         else {
            /* Ptr into ordinary app memory */
            arrays[attr].Ptr = (GLubyte *)exec->vtx.buffer_map + offset;
         }
	 arrays[attr].Size = exec->vtx.attrsz[src];
	 arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat);
	 arrays[attr].Stride = exec->vtx.vertex_size * sizeof(GLfloat);
	 arrays[attr].Type = GL_FLOAT;
         arrays[attr].Format = GL_RGBA;
	 arrays[attr].Enabled = 1;
         arrays[attr]._ElementSize = arrays[attr].Size * sizeof(GLfloat);
         _mesa_reference_buffer_object(ctx,
                                       &arrays[attr].BufferObj,
                                       exec->vtx.bufferobj);
	 arrays[attr]._MaxElement = count; /* ??? */

         varying_inputs |= VERT_BIT(attr);
         ctx->NewState |= _NEW_ARRAY;
      }
   }

   _mesa_set_varying_vp_inputs( ctx, varying_inputs );
}
Пример #27
0
void vbo_exec_vtx_init( struct vbo_exec_context *exec )
{
   struct gl_context *ctx = exec->ctx;
   struct vbo_context *vbo = vbo_context(ctx);
   GLuint i;

   /* Allocate a buffer object.  Will just reuse this object
    * continuously, unless vbo_use_buffer_objects() is called to enable
    * use of real VBOs.
    */
   _mesa_reference_buffer_object(ctx,
                                 &exec->vtx.bufferobj,
                                 ctx->Shared->NullBufferObj);

   assert(!exec->vtx.buffer_map);
   exec->vtx.buffer_map = _mesa_align_malloc(VBO_VERT_BUFFER_SIZE, 64);
   exec->vtx.buffer_ptr = exec->vtx.buffer_map;

   vbo_exec_vtxfmt_init( exec );
   _mesa_noop_vtxfmt_init(&exec->vtxfmt_noop);

   exec->vtx.enabled = 0;
   for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
      assert(i < ARRAY_SIZE(exec->vtx.attrsz));
      exec->vtx.attrsz[i] = 0;
      assert(i < ARRAY_SIZE(exec->vtx.attrtype));
      exec->vtx.attrtype[i] = GL_FLOAT;
      assert(i < ARRAY_SIZE(exec->vtx.active_sz));
      exec->vtx.active_sz[i] = 0;
   }
   for (i = 0 ; i < VERT_ATTRIB_MAX; i++) {
      assert(i < ARRAY_SIZE(exec->vtx.inputs));
      assert(i < ARRAY_SIZE(exec->vtx.arrays));
      exec->vtx.inputs[i] = &exec->vtx.arrays[i];
   }
   
   {
      struct gl_client_array *arrays = exec->vtx.arrays;
      unsigned i;

      memcpy(arrays, &vbo->currval[VBO_ATTRIB_POS],
             VERT_ATTRIB_FF_MAX * sizeof(arrays[0]));
      for (i = 0; i < VERT_ATTRIB_FF_MAX; ++i) {
         struct gl_client_array *array;
         array = &arrays[VERT_ATTRIB_FF(i)];
         array->BufferObj = NULL;
         _mesa_reference_buffer_object(ctx, &array->BufferObj,
                                 vbo->currval[VBO_ATTRIB_POS+i].BufferObj);
      }

      memcpy(arrays + VERT_ATTRIB_GENERIC(0),
             &vbo->currval[VBO_ATTRIB_GENERIC0],
             VERT_ATTRIB_GENERIC_MAX * sizeof(arrays[0]));

      for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; ++i) {
         struct gl_client_array *array;
         array = &arrays[VERT_ATTRIB_GENERIC(i)];
         array->BufferObj = NULL;
         _mesa_reference_buffer_object(ctx, &array->BufferObj,
                           vbo->currval[VBO_ATTRIB_GENERIC0+i].BufferObj);
      }
   }

   exec->vtx.vertex_size = 0;

   exec->begin_vertices_flags = FLUSH_UPDATE_CURRENT;
}
Пример #28
0
/**
 * Delete a set of buffer objects.
 * 
 * \param n      Number of buffer objects to delete.
 * \param ids    Array of \c n buffer object IDs.
 */
void GLAPIENTRY
_mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids)
{
   GET_CURRENT_CONTEXT(ctx);
   GLsizei i;
   ASSERT_OUTSIDE_BEGIN_END(ctx);

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

   _glthread_LOCK_MUTEX(ctx->Shared->Mutex);

   for (i = 0; i < n; i++) {
      struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, ids[i]);
      if (bufObj) {
         struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
         GLuint j;

         ASSERT(bufObj->Name == ids[i]);

         if (bufObj->Pointer) {
            /* if mapped, unmap it now */
            ctx->Driver.UnmapBuffer(ctx, 0, bufObj);
            bufObj->AccessFlags = DEFAULT_ACCESS;
            bufObj->Pointer = NULL;
         }

         /* unbind any vertex pointers bound to this buffer */
         unbind(ctx, &arrayObj->Vertex.BufferObj, bufObj);
         unbind(ctx, &arrayObj->Weight.BufferObj, bufObj);
         unbind(ctx, &arrayObj->Normal.BufferObj, bufObj);
         unbind(ctx, &arrayObj->Color.BufferObj, bufObj);
         unbind(ctx, &arrayObj->SecondaryColor.BufferObj, bufObj);
         unbind(ctx, &arrayObj->FogCoord.BufferObj, bufObj);
         unbind(ctx, &arrayObj->Index.BufferObj, bufObj);
         unbind(ctx, &arrayObj->EdgeFlag.BufferObj, bufObj);
         for (j = 0; j < Elements(arrayObj->TexCoord); j++) {
            unbind(ctx, &arrayObj->TexCoord[j].BufferObj, bufObj);
         }
         for (j = 0; j < Elements(arrayObj->VertexAttrib); j++) {
            unbind(ctx, &arrayObj->VertexAttrib[j].BufferObj, bufObj);
         }

         if (ctx->Array.ArrayBufferObj == bufObj) {
            _mesa_BindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
         }
         if (ctx->Array.ElementArrayBufferObj == bufObj) {
            _mesa_BindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 );
         }

         /* unbind any pixel pack/unpack pointers bound to this buffer */
         if (ctx->Pack.BufferObj == bufObj) {
            _mesa_BindBufferARB( GL_PIXEL_PACK_BUFFER_EXT, 0 );
         }
         if (ctx->Unpack.BufferObj == bufObj) {
            _mesa_BindBufferARB( GL_PIXEL_UNPACK_BUFFER_EXT, 0 );
         }

         /* The ID is immediately freed for re-use */
         _mesa_HashRemove(ctx->Shared->BufferObjects, bufObj->Name);
         _mesa_reference_buffer_object(ctx, &bufObj, NULL);
      }
   }

   _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
}
Пример #29
0
/**
 * Treat the vertex storage as a VBO, define vertex arrays pointing
 * into it:
 */
static void vbo_bind_vertex_list(struct gl_context *ctx,
                                 const struct vbo_save_vertex_list *node)
{
   struct vbo_context *vbo = vbo_context(ctx);
   struct vbo_save_context *save = &vbo->save;
   struct gl_client_array *arrays = save->arrays;
   GLuint buffer_offset = node->buffer_offset;
   const GLuint *map;
   GLuint attr;
   GLubyte node_attrsz[VBO_ATTRIB_MAX];  /* copy of node->attrsz[] */
   GLenum node_attrtype[VBO_ATTRIB_MAX];  /* copy of node->attrtype[] */
   GLbitfield64 varying_inputs = 0x0;

   memcpy(node_attrsz, node->attrsz, sizeof(node->attrsz));
   memcpy(node_attrtype, node->attrtype, sizeof(node->attrtype));

   /* Install the default (ie Current) attributes first, then overlay
    * all active ones.
    */
   switch (get_program_mode(ctx)) {
   case VP_NONE:
      for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) {
         save->inputs[attr] = &vbo->currval[VBO_ATTRIB_POS+attr];
      }
      for (attr = 0; attr < MAT_ATTRIB_MAX; attr++) {
         save->inputs[VERT_ATTRIB_GENERIC(attr)] =
            &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+attr];
      }
      map = vbo->map_vp_none;
      break;
   case VP_ARB:
      for (attr = 0; attr < VERT_ATTRIB_FF_MAX; attr++) {
         save->inputs[attr] = &vbo->currval[VBO_ATTRIB_POS+attr];
      }
      for (attr = 0; attr < VERT_ATTRIB_GENERIC_MAX; attr++) {
         save->inputs[VERT_ATTRIB_GENERIC(attr)] =
            &vbo->currval[VBO_ATTRIB_GENERIC0+attr];
      }
      map = vbo->map_vp_arb;

      /* check if VERT_ATTRIB_POS is not read but VERT_BIT_GENERIC0 is read.
       * In that case we effectively need to route the data from
       * glVertexAttrib(0, val) calls to feed into the GENERIC0 input.
       */
      if ((ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_POS) == 0 &&
          (ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_GENERIC0)) {
         save->inputs[VERT_ATTRIB_GENERIC0] = save->inputs[0];
         node_attrsz[VERT_ATTRIB_GENERIC0] = node_attrsz[0];
         node_attrtype[VERT_ATTRIB_GENERIC0] = node_attrtype[0];
         node_attrsz[0] = 0;
      }
      break;
   default:
      assert(0);
   }

   for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
      const GLuint src = map[attr];

      if (node_attrsz[src]) {
         /* override the default array set above */
         save->inputs[attr] = &arrays[attr];

	 arrays[attr].Ptr = (const GLubyte *) NULL + buffer_offset;
	 arrays[attr].Size = node_attrsz[src];
	 arrays[attr].StrideB = node->vertex_size * sizeof(GLfloat);
         arrays[attr].Type = node_attrtype[src];
         arrays[attr].Integer =
               vbo_attrtype_to_integer_flag(node_attrtype[src]);
         arrays[attr].Format = GL_RGBA;
         arrays[attr]._ElementSize = arrays[attr].Size * sizeof(GLfloat);
         _mesa_reference_buffer_object(ctx,
                                       &arrays[attr].BufferObj,
                                       node->vertex_store->bufferobj);
	 
	 assert(arrays[attr].BufferObj->Name);

	 buffer_offset += node_attrsz[src] * sizeof(GLfloat);
         varying_inputs |= VERT_BIT(attr);
      }
   }

   _mesa_set_varying_vp_inputs( ctx, varying_inputs );
   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
}
Пример #30
0
/**
 * Initialize texture state for the given context.
 */
GLboolean
_mesa_init_texture(struct gl_context *ctx)
{
   GLuint u;

   /* Texture group */
   ctx->Texture.CurrentUnit = 0;      /* multitexture */

   /* Appendix F.2 of the OpenGL ES 3.0 spec says:
    *
    *     "OpenGL ES 3.0 requires that all cube map filtering be
    *     seamless. OpenGL ES 2.0 specified that a single cube map face be
    *     selected and used for filtering."
    *
    * Unfortunatley, a call to _mesa_is_gles3 below will only work if
    * the driver has already computed and set ctx->Version, however drivers
    * seem to call _mesa_initialize_context (which calls this) early
    * in the CreateContext hook and _mesa_compute_version much later (since
    * it needs information about available extensions). So, we will
    * enable seamless cubemaps by default since GLES2. This should work
    * for most implementations and drivers that don't support seamless
    * cubemaps for GLES2 can still disable it.
    */
   ctx->Texture.CubeMapSeamless = ctx->API == API_OPENGLES2;

   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
      GLuint tex;

      /* initialize current texture object ptrs to the shared default objects */
      for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
         _mesa_reference_texobj(&texUnit->CurrentTex[tex],
                                ctx->Shared->DefaultTex[tex]);
      }

      texUnit->_BoundTextures = 0;
   }

   for (u = 0; u < ARRAY_SIZE(ctx->Texture.FixedFuncUnit); u++) {
      struct gl_fixedfunc_texture_unit *texUnit =
         &ctx->Texture.FixedFuncUnit[u];

      texUnit->EnvMode = GL_MODULATE;
      ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );

      texUnit->Combine = default_combine_state;
      texUnit->_EnvMode = default_combine_state;
      texUnit->_CurrentCombine = & texUnit->_EnvMode;

      texUnit->TexGenEnabled = 0x0;
      texUnit->GenS.Mode = GL_EYE_LINEAR;
      texUnit->GenT.Mode = GL_EYE_LINEAR;
      texUnit->GenR.Mode = GL_EYE_LINEAR;
      texUnit->GenQ.Mode = GL_EYE_LINEAR;
      texUnit->GenS._ModeBit = TEXGEN_EYE_LINEAR;
      texUnit->GenT._ModeBit = TEXGEN_EYE_LINEAR;
      texUnit->GenR._ModeBit = TEXGEN_EYE_LINEAR;
      texUnit->GenQ._ModeBit = TEXGEN_EYE_LINEAR;

      /* Yes, these plane coefficients are correct! */
      ASSIGN_4V( texUnit->GenS.ObjectPlane, 1.0, 0.0, 0.0, 0.0 );
      ASSIGN_4V( texUnit->GenT.ObjectPlane, 0.0, 1.0, 0.0, 0.0 );
      ASSIGN_4V( texUnit->GenR.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
      ASSIGN_4V( texUnit->GenQ.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
      ASSIGN_4V( texUnit->GenS.EyePlane, 1.0, 0.0, 0.0, 0.0 );
      ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
      ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
      ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
   }

   /* After we're done initializing the context's texture state the default
    * texture objects' refcounts should be at least
    * MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1.
    */
   assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount
          >= MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1);

   /* Allocate proxy textures */
   if (!alloc_proxy_textures( ctx ))
      return GL_FALSE;

   /* GL_ARB_texture_buffer_object */
   _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject,
                                 ctx->Shared->NullBufferObj);

   ctx->Texture.NumCurrentTexUsed = 0;

   return GL_TRUE;
}