Example #1
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);
   }
}
Example #2
0
/* Could do better by copying the arrays and element list intact and
 * then emitting an indexed prim at runtime.
 */
static void GLAPIENTRY
_save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type,
                       const GLvoid * indices)
{
   GET_CURRENT_CONTEXT(ctx);
   struct vbo_save_context *save = &vbo_context(ctx)->save;
   GLint i;

   if (!_mesa_validate_DrawElements(ctx, mode, count, type, indices, 0))
      return;

   if (save->out_of_memory)
      return;

   _ae_map_vbos(ctx);

   if (_mesa_is_bufferobj(ctx->Array.ArrayObj->ElementArrayBufferObj))
      indices =
         ADD_POINTERS(ctx->Array.ArrayObj->ElementArrayBufferObj->Pointer, indices);

   vbo_save_NotifyBegin(ctx, (mode | VBO_SAVE_PRIM_WEAK |
                              VBO_SAVE_PRIM_NO_CURRENT_UPDATE));

   switch (type) {
   case GL_UNSIGNED_BYTE:
      for (i = 0; i < count; i++)
         CALL_ArrayElement(GET_DISPATCH(), (((GLubyte *) indices)[i]));
      break;
   case GL_UNSIGNED_SHORT:
      for (i = 0; i < count; i++)
         CALL_ArrayElement(GET_DISPATCH(), (((GLushort *) indices)[i]));
      break;
   case GL_UNSIGNED_INT:
      for (i = 0; i < count; i++)
         CALL_ArrayElement(GET_DISPATCH(), (((GLuint *) indices)[i]));
      break;
   default:
      _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(type)");
      break;
   }

   CALL_End(GET_DISPATCH(), ());

   _ae_unmap_vbos(ctx);
}
Example #3
0
/**
 * Copy current vertex attribute values into the current vertex.
 */
static void
vbo_exec_copy_from_current(struct vbo_exec_context *exec)
{
   struct gl_context *ctx = exec->ctx;
   struct vbo_context *vbo = vbo_context(ctx);
   GLint i;

   for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
      const GLfloat *current = (GLfloat *) vbo->currval[i].Ptr;
      switch (exec->vtx.attrsz[i]) {
      case 4: exec->vtx.attrptr[i][3] = current[3];
      case 3: exec->vtx.attrptr[i][2] = current[2];
      case 2: exec->vtx.attrptr[i][1] = current[1];
      case 1: exec->vtx.attrptr[i][0] = current[0];
	 break;
      }
   }
}
void vbo_save_NewList( GLcontext *ctx, GLuint list, GLenum mode )
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;

   (void) list; (void) mode;

   if (!save->prim_store)
      save->prim_store = alloc_prim_store( ctx );

   if (!save->vertex_store) 
      save->vertex_store = alloc_vertex_store( ctx );
      
   save->vbptr = map_vertex_store( ctx, save->vertex_store );
   
   _save_reset_vertex( ctx );
   _save_reset_counters( ctx );  
   ctx->Driver.SaveNeedFlush = 0;
}
Example #5
0
void
vbo_save_SaveFlushVertices(struct gl_context *ctx)
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;

   /* Noop when we are actually active:
    */
   if (ctx->Driver.CurrentSavePrimitive <= PRIM_MAX)
      return;

   if (save->vert_count || save->prim_count)
      _save_compile_vertex_list(ctx);

   _save_copy_to_current(ctx);
   _save_reset_vertex(ctx);
   _save_reset_counters(ctx);
   ctx->Driver.SaveNeedFlush = GL_FALSE;
}
Example #6
0
/**
 * Print info/data for glDrawArrays(), for debugging.
 */
static void
print_draw_arrays(struct gl_context *ctx,
                  GLenum mode, GLint start, GLsizei count)
{
   struct vbo_context *vbo = vbo_context(ctx);
   struct vbo_exec_context *exec = &vbo->exec;
   struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
   int i;

   printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n",
	  mode, start, count);

   for (i = 0; i < 32; i++) {
      struct gl_buffer_object *bufObj = exec->array.inputs[i]->BufferObj;
      GLuint bufName = bufObj->Name;
      GLint stride = exec->array.inputs[i]->Stride;
      printf("attr %2d: size %d stride %d  enabled %d  "
	     "ptr %p  Bufobj %u\n",
	     i,
	     exec->array.inputs[i]->Size,
	     stride,
	     /*exec->array.inputs[i]->Enabled,*/
	     arrayObj->VertexAttrib[VERT_ATTRIB_FF(i)].Enabled,
	     exec->array.inputs[i]->Ptr,
	     bufName);

      if (bufName) {
         GLubyte *p = ctx->Driver.MapBufferRange(ctx, 0, bufObj->Size,
						 GL_MAP_READ_BIT, bufObj);
         int offset = (int) (GLintptr) exec->array.inputs[i]->Ptr;
         float *f = (float *) (p + offset);
         int *k = (int *) f;
         int i;
         int n = (count * stride) / 4;
         if (n > 32)
            n = 32;
         printf("  Data at offset %d:\n", offset);
         for (i = 0; i < n; i++) {
            printf("    float[%d] = 0x%08x %f\n", i, k[i], f[i]);
         }
         ctx->Driver.UnmapBuffer(ctx, bufObj);
      }
   }
}
Example #7
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;
}
Example #8
0
/**
 * Fallback for when a driver does not call vbo_set_indirect_draw_func().
 */
static void
vbo_draw_indirect_prims(struct gl_context *ctx,
                        GLuint mode,
                        struct gl_buffer_object *indirect_buffer,
                        GLsizeiptr indirect_offset,
                        unsigned draw_count,
                        unsigned stride,
                        struct gl_buffer_object *indirect_draw_count_buffer,
                        GLsizeiptr indirect_draw_count_offset,
                        const struct _mesa_index_buffer *ib)
{
   struct vbo_context *vbo = vbo_context(ctx);
   struct _mesa_prim *prim;
   GLsizei i;

   prim = calloc(draw_count, sizeof(*prim));
   if (prim == NULL) {
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "gl%sDraw%sIndirect%s",
                  (draw_count > 1) ? "Multi" : "",
                  ib ? "Elements" : "Arrays",
                  indirect_buffer ? "CountARB" : "");
      return;
   }

   prim[0].begin = 1;
   prim[draw_count - 1].end = 1;
   for (i = 0; i < draw_count; ++i, indirect_offset += stride) {
      prim[i].mode = mode;
      prim[i].indexed = !!ib;
      prim[i].indirect_offset = indirect_offset;
      prim[i].is_indirect = 1;
      prim[i].draw_id = i;
   }

   /* This should always be true at this time */
   assert(indirect_buffer == ctx->DrawIndirectBuffer);

   vbo->draw_prims(ctx, prim, draw_count,
                   ib, false, 0, ~0,
                   NULL, 0,
                   indirect_buffer);

   free(prim);
}
void vbo_save_SaveFlushVertices( GLcontext *ctx )
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;

   /* Noop when we are actually active:
    */
   if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM ||
       ctx->Driver.CurrentSavePrimitive <= GL_POLYGON)
      return;

   if (save->vert_count ||
       save->prim_count) 
      _save_compile_vertex_list( ctx );
   
   _save_copy_to_current( ctx );
   _save_reset_vertex( ctx );
   _save_reset_counters( ctx );  
   ctx->Driver.SaveNeedFlush = 0;
}
Example #10
0
static void init_mat_currval(GLcontext *ctx)
{
   struct vbo_context *vbo = vbo_context(ctx);
   struct gl_client_array *arrays = vbo->mat_currval;
   GLuint i;

   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;
      }

      if (i < MAT_ATTRIB_MAX)
	 cl->Ptr = (const void *)ctx->Light.Material.Attrib[i];
      else 
	 cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i];

      cl->Type = GL_FLOAT;
      cl->Stride = 0;
      cl->StrideB = 0;
      cl->Enabled = 1;
      cl->BufferObj = ctx->Array.NullBufferObj;
   }
}
static void _save_current_init( GLcontext *ctx ) 
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;
   GLint i;

   for (i = VBO_ATTRIB_POS; i <= VBO_ATTRIB_GENERIC15; i++) {
      const GLuint j = i - VBO_ATTRIB_POS;
      ASSERT(j < VERT_ATTRIB_MAX);
      save->currentsz[i] = &ctx->ListState.ActiveAttribSize[j];
      save->current[i] = ctx->ListState.CurrentAttrib[j];
   }

   for (i = VBO_ATTRIB_FIRST_MATERIAL; i <= VBO_ATTRIB_LAST_MATERIAL; i++) {
      const GLuint j = i - VBO_ATTRIB_FIRST_MATERIAL;
      ASSERT(j < MAT_ATTRIB_MAX);
      save->currentsz[i] = &ctx->ListState.ActiveMaterialSize[j];
      save->current[i] = ctx->ListState.CurrentMaterial[j];
   }
}
/* 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;
}
Example #13
0
/* Build a list of primitives on the fly.  Keep
 * ctx->Driver.CurrentExecPrimitive uptodate as well.
 */
static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
{
   GET_CURRENT_CONTEXT( ctx ); 

   if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) {
      struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
      int i;

      if (ctx->NewState) {
	 _mesa_update_state( ctx );

	 CALL_Begin(ctx->Exec, (mode));
	 return;
      }

      if (!vbo_validate_shaders(ctx)) {
         _mesa_error(ctx, GL_INVALID_OPERATION,
                     "glBegin (invalid vertex/fragment program)");
         return;
      }

      /* Heuristic: attempt to isolate attributes occuring outside
       * begin/end pairs.
       */
      if (exec->vtx.vertex_size && !exec->vtx.attrsz[0]) 
	 vbo_exec_FlushVertices_internal( ctx, GL_FALSE );

      i = exec->vtx.prim_count++;
      exec->vtx.prim[i].mode = mode;
      exec->vtx.prim[i].begin = 1;
      exec->vtx.prim[i].end = 0;
      exec->vtx.prim[i].indexed = 0;
      exec->vtx.prim[i].weak = 0;
      exec->vtx.prim[i].pad = 0;
      exec->vtx.prim[i].start = exec->vtx.vert_count;
      exec->vtx.prim[i].count = 0;

      ctx->Driver.CurrentExecPrimitive = mode;
   }
   else 
      _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" );
      
}
Example #14
0
void
vbo_exec_invalidate_state(struct gl_context *ctx)
{
   struct vbo_context *vbo = vbo_context(ctx);
   struct vbo_exec_context *exec = &vbo->exec;

   if (ctx->NewState & (_NEW_PROGRAM | _NEW_ARRAY)) {
      exec->array.recalculate_inputs = GL_TRUE;

      _ae_invalidate_state(ctx);
   }
   /* If _mesa_update_state is called in a non draw code path,
    * changes in the VAO need to be captured.
    */
   if (ctx->Array.VAO->NewArrays)
      exec->array.recalculate_inputs = GL_TRUE;

   if (ctx->NewState & _NEW_EVAL)
      exec->eval.recalculate_maps = GL_TRUE;
}
Example #15
0
/**
 * Called via glEnd.
 */
static void GLAPIENTRY vbo_exec_End( void )
{
   GET_CURRENT_CONTEXT( ctx ); 

   if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
      struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
      int idx = exec->vtx.vert_count;
      int i = exec->vtx.prim_count - 1;

      exec->vtx.prim[i].end = 1; 
      exec->vtx.prim[i].count = idx - exec->vtx.prim[i].start;

      ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;

      if (exec->vtx.prim_count == VBO_MAX_PRIM)
	 vbo_exec_vtx_flush( exec, GL_FALSE );
   }
   else 
      _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
}
Example #16
0
static void
_save_copy_from_current(struct gl_context *ctx)
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;
   GLint i;

   for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
      switch (save->attrsz[i]) {
      case 4:
         save->attrptr[i][3] = save->current[i][3];
      case 3:
         save->attrptr[i][2] = save->current[i][2];
      case 2:
         save->attrptr[i][1] = save->current[i][1];
      case 1:
         save->attrptr[i][0] = save->current[i][0];
      case 0:
         break;
      }
   }
}
Example #17
0
void vbo_exec_init( struct gl_context *ctx )
{
   struct vbo_exec_context *exec = &vbo_context(ctx)->exec;

   exec->ctx = ctx;

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

   vbo_exec_vtx_init( exec );

   ctx->Driver.NeedFlush = 0;
   ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
   ctx->Driver.BeginVertices = vbo_exec_BeginVertices;
   ctx->Driver.FlushVertices = vbo_exec_FlushVertices;

   vbo_exec_invalidate_state( ctx, ~0 );
}
/* Called only when buffers are wrapped as the result of filling the
 * vertex_store struct.  
 */
static void _save_wrap_filled_vertex( GLcontext *ctx )
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;
   GLfloat *data = save->copied.buffer;
   GLuint i;

   /* Emit a glEnd to close off the last vertex list.
    */
   _save_wrap_buffers( ctx );
   
    /* Copy stored stored vertices to start of new list.
    */
   assert(save->max_vert - save->vert_count > save->copied.nr);

   for (i = 0 ; i < save->copied.nr ; i++) {
      _mesa_memcpy( save->vbptr, data, save->vertex_size * sizeof(GLfloat));
      data += save->vertex_size;
      save->vbptr += save->vertex_size;
      save->vert_count++;
   }
}
static void _save_reset_counters( GLcontext *ctx )
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;

   save->prim = save->prim_store->buffer + save->prim_store->used;
   save->buffer = (save->vertex_store->buffer + 
		   save->vertex_store->used);

   assert(save->buffer == save->vbptr);

   if (save->vertex_size)
      save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) / 
			 save->vertex_size);
   else
      save->max_vert = 0;

   save->vert_count = 0;
   save->prim_count = 0;
   save->prim_max = VBO_SAVE_PRIM_SIZE - save->prim_store->used;
   save->dangling_attr_ref = 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.
    */   
   _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
}
Example #21
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;
   }
}
Example #22
0
File: vbo_save.c Project: RAOF/mesa
/**
 * Called at context creation time.
 */
void vbo_save_init( struct gl_context *ctx )
{
   struct vbo_context *vbo = vbo_context(ctx);
   struct vbo_save_context *save = &vbo->save;

   save->ctx = ctx;

   vbo_save_api_init( save );
   vbo_save_callback_init(ctx);

   {
      struct gl_client_array *arrays = save->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, &arrays->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);
      }
   }

   ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN;
}
Example #23
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->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i];
      cl->Stride = 0;
      cl->StrideB = 0;
      cl->Enabled = 1;
      cl->BufferObj = ctx->Array.NullBufferObj;
   }
}
Example #24
0
/**
 * Handle a draw case that potentially has primitive restart enabled.
 *
 * If primitive restart is enabled, and PrimitiveRestartInSoftware is
 * set, then vbo_sw_primitive_restart is used to handle the primitive
 * restart case in software.
 */
static void
vbo_handle_primitive_restart(struct gl_context *ctx,
                             const struct _mesa_prim *prim,
                             GLuint nr_prims,
                             const struct _mesa_index_buffer *ib,
                             GLboolean index_bounds_valid,
                             GLuint min_index,
                             GLuint max_index)
{
   struct vbo_context *vbo = vbo_context(ctx);

   if ((ib != NULL) &&
       ctx->Const.PrimitiveRestartInSoftware &&
       ctx->Array._PrimitiveRestart) {
      /* Handle primitive restart in software */
      vbo_sw_primitive_restart(ctx, prim, nr_prims, ib);
   } else {
      /* Call driver directly for draw_prims */
      vbo->draw_prims(ctx, prim, nr_prims, ib,
                      index_bounds_valid, min_index, max_index, NULL);
   }
}
Example #25
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;
}
Example #26
0
/**
 * Copy current vertex attribute values into the current vertex.
 */
static void
vbo_exec_copy_from_current(struct vbo_exec_context *exec)
{
   struct gl_context *ctx = exec->ctx;
   struct vbo_context *vbo = vbo_context(ctx);
   GLint i;

   for (i = VBO_ATTRIB_POS + 1; i < VBO_ATTRIB_MAX; i++) {
      if (exec->vtx.attrtype[i] == GL_DOUBLE) {
         memcpy(exec->vtx.attrptr[i], vbo->currval[i].Ptr, exec->vtx.attrsz[i] * sizeof(GLfloat));
      } else {
         const fi_type *current = (fi_type *) vbo->currval[i].Ptr;
         switch (exec->vtx.attrsz[i]) {
         case 4: exec->vtx.attrptr[i][3] = current[3];
         case 3: exec->vtx.attrptr[i][2] = current[2];
         case 2: exec->vtx.attrptr[i][1] = current[1];
         case 1: exec->vtx.attrptr[i][0] = current[0];
            break;
         }
      }
   }
}
Example #27
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;
   }
}
Example #28
0
void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags )
{
   struct vbo_exec_context *exec = &vbo_context(ctx)->exec;

   if (0) _mesa_printf("%s\n", __FUNCTION__);

   if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
      if (0) _mesa_printf("%s - inside begin/end\n", __FUNCTION__);
      return;
   }

   vbo_exec_FlushVertices_internal( ctx, GL_TRUE );

   /* Need to do this to ensure BeginVertices gets called again:
    */
   if (exec->ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) {
      _mesa_restore_exec_vtxfmt( ctx );
      exec->ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
   }

   exec->ctx->Driver.NeedFlush &= ~flags;
}
Example #29
0
/**
 * This is called when we fill a vertex buffer before we hit a glEnd().
 * We
 * TODO -- If no new vertices have been stored, don't bother saving it.
 */
static void
_save_wrap_buffers(struct gl_context *ctx)
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;
   GLint i = save->prim_count - 1;
   GLenum mode;
   GLboolean weak;
   GLboolean no_current_update;

   assert(i < (GLint) save->prim_max);
   assert(i >= 0);

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

   /* store the copied vertices, and allocate a new list.
    */
   _save_compile_vertex_list(ctx);

   /* Restart interrupted primitive
    */
   save->prim[0].mode = mode;
   save->prim[0].weak = weak;
   save->prim[0].no_current_update = no_current_update;
   save->prim[0].begin = 0;
   save->prim[0].end = 0;
   save->prim[0].pad = 0;
   save->prim[0].start = 0;
   save->prim[0].count = 0;
   save->prim[0].num_instances = 1;
   save->prim[0].base_instance = 0;
   save->prim[0].is_indirect = 0;
   save->prim_count = 1;
}
static void save_fixup_vertex( GLcontext *ctx, GLuint attr, GLuint sz )
{
   struct vbo_save_context *save = &vbo_context(ctx)->save; 

   if (sz > save->attrsz[attr]) {
      /* New size is larger.  Need to flush existing vertices and get
       * an enlarged vertex format.
       */
      _save_upgrade_vertex( ctx, attr, sz );
   }
   else if (sz < save->active_sz[attr]) {
      static GLfloat id[4] = { 0, 0, 0, 1 };
      GLuint i;

      /* New size is equal or smaller - just need to fill in some
       * zeros.
       */
      for (i = sz ; i <= save->attrsz[attr] ; i++)
	 save->attrptr[attr][i-1] = id[i-1];
   }

   save->active_sz[attr] = sz;
}