Ejemplo n.º 1
0
static void GLAPIENTRY
_save_End(void)
{
   GET_CURRENT_CONTEXT(ctx);
   struct vbo_save_context *save = &vbo_context(ctx)->save;
   GLint i = save->prim_count - 1;

   ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
   save->prim[i].end = 1;
   save->prim[i].count = (save->vert_count - save->prim[i].start);

   if (i == (GLint) save->prim_max - 1) {
      _save_compile_vertex_list(ctx);
      assert(save->copied.nr == 0);
   }

   /* Swap out this vertex format while outside begin/end.  Any color,
    * etc. received between here and the next begin will be compiled
    * as opcodes.
    */
   if (save->out_of_memory) {
      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
   }
   else {
      _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt);
   }
}
Ejemplo n.º 2
0
/* Cope with EvalCoord/CallList called within a begin/end object:
 *     -- Flush current buffer
 *     -- Fallback to opcodes for the rest of the begin/end object.
 */
static void
dlist_fallback(struct gl_context *ctx)
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;

   if (save->vert_count || save->prim_count) {
      if (save->prim_count > 0) {
         /* Close off in-progress primitive. */
         GLint i = save->prim_count - 1;
         save->prim[i].count = save->vert_count - save->prim[i].start;
      }

      /* Need to replay this display list with loopback,
       * unfortunately, otherwise this primitive won't be handled
       * properly:
       */
      save->dangling_attr_ref = 1;

      _save_compile_vertex_list(ctx);
   }

   _save_copy_to_current(ctx);
   _save_reset_vertex(ctx);
   _save_reset_counters(ctx);
   if (save->out_of_memory) {
      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
   }
   else {
      _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt);
   }
   ctx->Driver.SaveNeedFlush = 0;
}
Ejemplo n.º 3
0
/* This begin is hooked into ...  Updating of
 * ctx->Driver.CurrentSavePrimitive is already taken care of.
 */
GLboolean
vbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode)
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;

   GLuint i = save->prim_count++;

   assert(i < save->prim_max);
   save->prim[i].mode = mode & VBO_SAVE_PRIM_MODE_MASK;
   save->prim[i].begin = 1;
   save->prim[i].end = 0;
   save->prim[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;
   save->prim[i].no_current_update =
      (mode & VBO_SAVE_PRIM_NO_CURRENT_UPDATE) ? 1 : 0;
   save->prim[i].pad = 0;
   save->prim[i].start = save->vert_count;
   save->prim[i].count = 0;
   save->prim[i].num_instances = 1;

   if (save->out_of_memory) {
      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
   }
   else {
      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt);
   }
   ctx->Driver.SaveNeedFlush = 1;
   return GL_TRUE;
}
Ejemplo n.º 4
0
/**
 * Called via ctx->Driver.NotifySaveBegin() when a glBegin is getting
 * compiled into a display list.
 * Updating of ctx->Driver.CurrentSavePrimitive is already taken care of.
 */
GLboolean
vbo_save_NotifyBegin(struct gl_context *ctx, GLenum mode)
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;
   const GLuint i = save->prim_count++;

   assert(i < save->prim_max);
   save->prim[i].mode = mode & VBO_SAVE_PRIM_MODE_MASK;
   save->prim[i].begin = 1;
   save->prim[i].end = 0;
   save->prim[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;
   save->prim[i].no_current_update =
      (mode & VBO_SAVE_PRIM_NO_CURRENT_UPDATE) ? 1 : 0;
   save->prim[i].pad = 0;
   save->prim[i].start = save->vert_count;
   save->prim[i].count = 0;
   save->prim[i].num_instances = 1;
   save->prim[i].base_instance = 0;

   if (save->out_of_memory) {
      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
   }
   else {
      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt);
   }

   /* We need to call SaveFlushVertices() if there's state change */
   ctx->Driver.SaveNeedFlush = GL_TRUE;

   /* GL_TRUE means we've handled this glBegin here; don't compile a BEGIN
    * opcode into the display list.
    */
   return GL_TRUE;
}
/**
 * Initialize the display list compiler
 */
void vbo_save_api_init( struct vbo_save_context *save )
{
   GLcontext *ctx = save->ctx;
   GLuint i;

   save->opcode_vertex_list =
      _mesa_alloc_opcode( ctx,
			  sizeof(struct vbo_save_vertex_list),
			  vbo_save_playback_vertex_list,
			  vbo_destroy_vertex_list,
			  vbo_print_vertex_list );

   ctx->Driver.NotifySaveBegin = vbo_save_NotifyBegin;

   _save_vtxfmt_init( ctx );
   _save_current_init( ctx );

   /* These will actually get set again when binding/drawing */
   for (i = 0; i < VBO_ATTRIB_MAX; i++)
      save->inputs[i] = &save->arrays[i];

   /* Hook our array functions into the outside-begin-end vtxfmt in 
    * ctx->ListState.
    */
   ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf;
   ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays;
   ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements;
   ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements;
   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
}
void vbo_save_EndList( GLcontext *ctx )
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;

   /* EndList called inside a (saved) Begin/End pair?
    */
   if (ctx->Driver.CurrentSavePrimitive != PRIM_OUTSIDE_BEGIN_END) {

      if (save->prim_count > 0) {
         GLint i = save->prim_count - 1;
         ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
         save->prim[i].end = 0;
         save->prim[i].count = (save->vert_count - 
                                save->prim[i].start);
      }

      /* Make sure this vertex list gets replayed by the "loopback"
       * mechanism:
       */
      save->dangling_attr_ref = 1;
      vbo_save_SaveFlushVertices( ctx );

      /* Swap out this vertex format while outside begin/end.  Any color,
       * etc. received between here and the next begin will be compiled
       * as opcodes.
       */   
      _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
   }

   unmap_vertex_store( ctx, save->vertex_store );

   assert(save->vertex_size == 0);
}
Ejemplo n.º 7
0
/**
 * Initialize the display list compiler
 */
void _tnl_save_init( GLcontext *ctx )
{
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   struct tnl_vertex_arrays *tmp = &tnl->save_inputs;
   GLuint i;


   for (i = 0; i < _TNL_ATTRIB_MAX; i++)
      _mesa_vector4f_init( &tmp->Attribs[i], 0, 0);

   tnl->save.opcode_vertex_list =
      _mesa_alloc_opcode( ctx,
			  sizeof(struct tnl_vertex_list),
			  _tnl_playback_vertex_list,
			  _tnl_destroy_vertex_list,
			  _tnl_print_vertex_list );

   ctx->Driver.NotifySaveBegin = _save_NotifyBegin;

   _save_vtxfmt_init( ctx );
   _save_current_init( ctx );

   /* Hook our array functions into the outside-begin-end vtxfmt in 
    * ctx->ListState.
    */
   ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf;
   ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays;
   ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements;
   ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements;
   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
}
Ejemplo n.º 8
0
/* Cope with EvalCoord/CallList called within a begin/end object:
 *     -- Flush current buffer
 *     -- Fallback to opcodes for the rest of the begin/end object.
 */
static void DO_FALLBACK( GLcontext *ctx )
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;

   if (save->vert_count || save->prim_count) {
      GLint i = save->prim_count - 1;

      /* Close off in-progress primitive.
       */
      save->prim[i].count = (save->vert_count - 
                             save->prim[i].start);

      /* Need to replay this display list with loopback,
       * unfortunately, otherwise this primitive won't be handled
       * properly:
       */
      save->dangling_attr_ref = 1;
      
      _save_compile_vertex_list( ctx );
   }

   _save_copy_to_current( ctx );
   _save_reset_vertex( ctx );
   _save_reset_counters( ctx );
   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
   ctx->Driver.SaveNeedFlush = 0;
}
Ejemplo n.º 9
0
void
_tnl_wakeup_save_exec( GLcontext *ctx )
{
   TNLcontext *tnl = TNL_CONTEXT(ctx);

   _tnl_wakeup_exec( ctx );
   _mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt );
}
Ejemplo n.º 10
0
/**
 * Install VBO vtxfmt functions.
 *
 * This function depends on ctx->Version.
 */
void
_mesa_initialize_vbo_vtxfmt(struct gl_context *ctx)
{
   struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
   _mesa_install_exec_vtxfmt(ctx, &exec->vtxfmt);
   if (ctx->API == API_OPENGL_COMPAT) {
      _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt);
   }
}
/* This begin is hooked into ...  Updating of
 * ctx->Driver.CurrentSavePrimitive is already taken care of.
 */
GLboolean vbo_save_NotifyBegin( GLcontext *ctx, GLenum mode )
{
   struct vbo_save_context *save = &vbo_context(ctx)->save; 

   GLuint i = save->prim_count++;

   assert(i < save->prim_max);
   save->prim[i].mode = mode & ~VBO_SAVE_PRIM_WEAK;
   save->prim[i].begin = 1;
   save->prim[i].end = 0;
   save->prim[i].weak = (mode & VBO_SAVE_PRIM_WEAK) ? 1 : 0;
   save->prim[i].pad = 0;
   save->prim[i].start = save->vert_count;
   save->prim[i].count = 0;   

   _mesa_install_save_vtxfmt( ctx, &save->vtxfmt );      
   ctx->Driver.SaveNeedFlush = 1;
   return GL_TRUE;
}
Ejemplo n.º 12
0
/* This begin is hooked into ...  Updating of
 * ctx->Driver.CurrentSavePrimitive is already taken care of.
 */
static GLboolean _save_NotifyBegin( GLcontext *ctx, GLenum mode )
{
   TNLcontext *tnl = TNL_CONTEXT(ctx); 

   if (1) {
      GLuint i = tnl->save.prim_count++;

      assert(i < tnl->save.prim_max);
      tnl->save.prim[i].mode = mode | PRIM_BEGIN;
      tnl->save.prim[i].start = tnl->save.initial_counter - tnl->save.counter;
      tnl->save.prim[i].count = 0;   

      _mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt );      
      ctx->Driver.SaveNeedFlush = 1;
      return GL_TRUE;
   }
   else 
      return GL_FALSE;
}
Ejemplo n.º 13
0
static void GLAPIENTRY _save_End( void )
{
   GET_CURRENT_CONTEXT( ctx ); 
   TNLcontext *tnl = TNL_CONTEXT(ctx); 
   GLint i = tnl->save.prim_count - 1;

   ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
   tnl->save.prim[i].mode |= PRIM_END;
   tnl->save.prim[i].count = ((tnl->save.initial_counter - tnl->save.counter) - 
			      tnl->save.prim[i].start);

   if (i == (GLint) tnl->save.prim_max - 1) {
      _save_compile_vertex_list( ctx );
      assert(tnl->save.copied.nr == 0);
   }

   /* Swap out this vertex format while outside begin/end.  Any color,
    * etc. received between here and the next begin will be compiled
    * as opcodes.
    */   
   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
}
Ejemplo n.º 14
0
static struct vbo_save_vertex_store *
alloc_vertex_store(struct gl_context *ctx)
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;
   struct vbo_save_vertex_store *vertex_store =
      CALLOC_STRUCT(vbo_save_vertex_store);

   /* obj->Name needs to be non-zero, but won't ever be examined more
    * closely than that.  In particular these buffers won't be entered
    * into the hash and can never be confused with ones visible to the
    * user.  Perhaps there could be a special number for internal
    * buffers:
    */
   vertex_store->bufferobj = ctx->Driver.NewBufferObject(ctx,
                                                         VBO_BUF_ID,
                                                         GL_ARRAY_BUFFER_ARB);
   if (vertex_store->bufferobj) {
      save->out_of_memory =
         !ctx->Driver.BufferData(ctx,
                                 GL_ARRAY_BUFFER_ARB,
                                 VBO_SAVE_BUFFER_SIZE * sizeof(GLfloat),
                                 NULL, GL_STATIC_DRAW_ARB,
                                 vertex_store->bufferobj);
   }
   else {
      save->out_of_memory = GL_TRUE;
   }

   if (save->out_of_memory) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "internal VBO allocation");
      _mesa_install_save_vtxfmt(ctx, &save->vtxfmt_noop);
   }

   vertex_store->buffer = NULL;
   vertex_store->used = 0;
   vertex_store->refcount = 1;

   return vertex_store;
}
Ejemplo n.º 15
0
/**
 * Initialize a GLcontext struct (rendering context).
 *
 * This includes allocating all the other structs and arrays which hang off of
 * the context by pointers.
 * Note that the driver needs to pass in its dd_function_table here since
 * we need to at least call driverFunctions->NewTextureObject to create the
 * default texture objects.
 * 
 * Called by _mesa_create_context().
 *
 * Performs the imports and exports callback tables initialization, and
 * miscellaneous one-time initializations. If no shared context is supplied one
 * is allocated, and increase its reference count.  Setups the GL API dispatch
 * tables.  Initialize the TNL module. Sets the maximum Z buffer depth.
 * Finally queries the \c MESA_DEBUG and \c MESA_VERBOSE environment variables
 * for debug flags.
 *
 * \param ctx the context to initialize
 * \param visual describes the visual attributes for this context
 * \param share_list points to context to share textures, display lists,
 *        etc with, or NULL
 * \param driverFunctions table of device driver functions for this context
 *        to use
 * \param driverContext pointer to driver-specific context data
 */
GLboolean
_mesa_initialize_context(GLcontext *ctx,
                         const GLvisual *visual,
                         GLcontext *share_list,
                         const struct dd_function_table *driverFunctions,
                         void *driverContext)
{
   struct gl_shared_state *shared;

   /*ASSERT(driverContext);*/
   assert(driverFunctions->NewTextureObject);
   assert(driverFunctions->FreeTexImageData);

   /* misc one-time initializations */
   one_time_init(ctx);

   ctx->Visual = *visual;
   ctx->DrawBuffer = NULL;
   ctx->ReadBuffer = NULL;
   ctx->WinSysDrawBuffer = NULL;
   ctx->WinSysReadBuffer = NULL;

   /* Plug in driver functions and context pointer here.
    * This is important because when we call alloc_shared_state() below
    * we'll call ctx->Driver.NewTextureObject() to create the default
    * textures.
    */
   ctx->Driver = *driverFunctions;
   ctx->DriverCtx = driverContext;

   if (share_list) {
      /* share state with another context */
      shared = share_list->Shared;
   }
   else {
      /* allocate new, unshared state */
      shared = _mesa_alloc_shared_state(ctx);
      if (!shared)
         return GL_FALSE;
   }

   _glthread_LOCK_MUTEX(shared->Mutex);
   ctx->Shared = shared;
   shared->RefCount++;
   _glthread_UNLOCK_MUTEX(shared->Mutex);

   if (!init_attrib_groups( ctx )) {
      _mesa_free_shared_state(ctx, ctx->Shared);
      return GL_FALSE;
   }

   /* setup the API dispatch tables */
   ctx->Exec = alloc_dispatch_table();
   ctx->Save = alloc_dispatch_table();
   if (!ctx->Exec || !ctx->Save) {
      _mesa_free_shared_state(ctx, ctx->Shared);
      if (ctx->Exec)
         _mesa_free(ctx->Exec);
      return GL_FALSE;
   }
#if FEATURE_dispatch
   _mesa_init_exec_table(ctx->Exec);
#endif
   ctx->CurrentDispatch = ctx->Exec;

#if FEATURE_dlist
   _mesa_init_save_table(ctx->Save);
   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
#endif

   /* Neutral tnl module stuff */
   _mesa_init_exec_vtxfmt( ctx ); 
   ctx->TnlModule.Current = NULL;
   ctx->TnlModule.SwapCount = 0;

   ctx->FragmentProgram._MaintainTexEnvProgram
      = (_mesa_getenv("MESA_TEX_PROG") != NULL);

   ctx->VertexProgram._MaintainTnlProgram
      = (_mesa_getenv("MESA_TNL_PROG") != NULL);
   if (ctx->VertexProgram._MaintainTnlProgram) {
      /* this is required... */
      ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
   }

#ifdef FEATURE_extra_context_init
   _mesa_initialize_context_extra(ctx);
#endif

   ctx->FirstTimeCurrent = GL_TRUE;

   return GL_TRUE;
}