Пример #1
0
/* Material
 */
void GLAPIENTRY _mesa_noop_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
{
   GET_CURRENT_CONTEXT(ctx);
   GLint i, nr;
   struct gl_material *mat = &ctx->Light.Material;
   GLuint bitmask = _mesa_material_bitmask( ctx, face, pname, ~0,
                                            "_mesa_noop_Materialfv" );

   if (ctx->Light.ColorMaterialEnabled)
      bitmask &= ~ctx->Light.ColorMaterialBitmask;

   if (bitmask == 0)
      return;

   switch (pname) {
   case GL_SHININESS: nr = 1; break;
   case GL_COLOR_INDEXES: nr = 3; break;
   default: nr = 4 ; break;
   }

   for (i = 0 ; i < MAT_ATTRIB_MAX ; i++) 
      if (bitmask & (1<<i))
	 COPY_SZ_4V( mat->Attrib[i], nr, params ); 

   _mesa_update_material( ctx, bitmask );
}
Пример #2
0
static void _playback_copy_to_current( GLcontext *ctx,
				       const struct tnl_vertex_list *node )
{
   TNLcontext *tnl = TNL_CONTEXT(ctx); 
   const GLfloat *data;
   GLuint i;

   if (node->count)
      data = node->buffer + (node->count-1) * node->vertex_size;
   else
      data = node->buffer;

   for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_INDEX ; i++) {
      if (node->attrsz[i]) {
	 ASSIGN_4V(tnl->vtx.current[i], 0, 0, 0, 1);
	 COPY_SZ_4V(tnl->vtx.current[i], node->attrsz[i], data);
	 data += node->attrsz[i];
      }
   }

   /* Edgeflag requires special treatment:
    */
   if (node->attrsz[_TNL_ATTRIB_EDGEFLAG]) {
      ctx->Current.EdgeFlag = (data[0] == 1.0);
   }

   /* Colormaterial -- this kindof sucks.
    */
   if (ctx->Light.ColorMaterialEnabled) {
      _mesa_update_color_material(ctx, ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
   }

   if (node->have_materials) {
      tnl->Driver.NotifyMaterialChange( ctx );
   }

   /* CurrentExecPrimitive
    */
   if (node->prim_count) {
      GLenum mode = node->prim[node->prim_count - 1].mode;
      if (mode & PRIM_END)
	 ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
      else
	 ctx->Driver.CurrentExecPrimitive = (mode & PRIM_MODE_MASK);
   }
}
Пример #3
0
void vbo_exec_do_EvalCoord1f(struct vbo_exec_context *exec, GLfloat u)
{
    GLuint attr;

    for (attr = 1; attr <= VBO_ATTRIB_TEX7; attr++) {
        struct gl_1d_map *map = exec->eval.map1[attr].map;
        if (map) {
            GLfloat uu = (u - map->u1) * map->du;
            GLfloat data[4];

            ASSIGN_4V(data, 0, 0, 0, 1);

            _math_horner_bezier_curve(map->Points, data, uu,
                                      exec->eval.map1[attr].sz,
                                      map->Order);

            COPY_SZ_4V( exec->vtx.attrptr[attr],
                        exec->vtx.attrsz[attr],
                        data );
        }
    }

    /** Vertex -- EvalCoord1f is a noop if this map not enabled:
     **/
    if (exec->eval.map1[0].map) {
        struct gl_1d_map *map = exec->eval.map1[0].map;
        GLfloat uu = (u - map->u1) * map->du;
        GLfloat vertex[4];

        ASSIGN_4V(vertex, 0, 0, 0, 1);

        _math_horner_bezier_curve(map->Points, vertex, uu,
                                  exec->eval.map1[0].sz,
                                  map->Order);

        if (exec->eval.map1[0].sz == 4)
            CALL_Vertex4fv(GET_DISPATCH(), ( vertex ));
        else
            CALL_Vertex3fv(GET_DISPATCH(), ( vertex ));
    }
}
Пример #4
0
static void feedback_vertex( GLcontext *ctx, GLuint v, GLuint pv )
{
   GLfloat win[4];
   GLfloat color[4];
   GLfloat tc[4];
   GLuint texUnit = ctx->Texture.CurrentTransformUnit;
   const struct vertex_buffer *VB = ctx->VB;
   GLuint index;

   win[0] = VB->Win.data[v][0];
   win[1] = VB->Win.data[v][1];
   win[2] = VB->Win.data[v][2] / ctx->Visual->DepthMaxF;
   win[3] = 1.0 / VB->Win.data[v][3];

   if (ctx->Light.ShadeModel == GL_SMOOTH)
      pv = v;

   UBYTE_RGBA_TO_FLOAT_RGBA( color, VB->ColorPtr->data[pv] );

   if (VB->TexCoordPtr[texUnit]->size == 4 &&     
       VB->TexCoordPtr[texUnit]->data[v][3] != 0.0) {
      GLfloat invq = 1.0F / VB->TexCoordPtr[texUnit]->data[v][3];
      tc[0] = VB->TexCoordPtr[texUnit]->data[v][0] * invq;
      tc[1] = VB->TexCoordPtr[texUnit]->data[v][1] * invq;
      tc[2] = VB->TexCoordPtr[texUnit]->data[v][2] * invq;
      tc[3] = VB->TexCoordPtr[texUnit]->data[v][3];
   }
   else {
      ASSIGN_4V(tc, 0,0,0,1);
      COPY_SZ_4V(tc, 
		 VB->TexCoordPtr[texUnit]->size,
		 VB->TexCoordPtr[texUnit]->data[v]);
   }

   if (VB->IndexPtr)
      index = VB->IndexPtr->data[v];
   else
      index = 0;

   gl_feedback_vertex( ctx, win, color, index, tc );
}
Пример #5
0
static void _save_copy_to_current( GLcontext *ctx )
{
   TNLcontext *tnl = TNL_CONTEXT(ctx); 
   GLuint i;

   for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_INDEX ; i++) {
      if (tnl->save.attrsz[i]) {
	 tnl->save.currentsz[i][0] = tnl->save.attrsz[i];
	 ASSIGN_4V(tnl->save.current[i], 0, 0, 0, 1);
	 COPY_SZ_4V(tnl->save.current[i], 
		    tnl->save.attrsz[i], 
		    tnl->save.attrptr[i]);
      }
   }

   /* Edgeflag requires special treatment:
    */
   if (tnl->save.attrsz[_TNL_ATTRIB_EDGEFLAG]) {
      ctx->ListState.ActiveEdgeFlag = 1;
      ctx->ListState.CurrentEdgeFlag = 
	 (tnl->save.attrptr[_TNL_ATTRIB_EDGEFLAG][0] == 1.0);
   }
}
/* Flush existing data, set new attrib size, replay copied vertices.
 */ 
static void _save_upgrade_vertex( GLcontext *ctx, 
				 GLuint attr,
				 GLuint newsz )
{
   struct vbo_save_context *save = &vbo_context(ctx)->save;
   GLuint oldsz;
   GLuint i;
   GLfloat *tmp;

   /* Store the current run of vertices, and emit a GL_END.  Emit a
    * BEGIN in the new buffer.
    */
   if (save->vert_count) 
      _save_wrap_buffers( ctx );
   else
      assert( save->copied.nr == 0 );

   /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
    * when the attribute already exists in the vertex and is having
    * its size increased.  
    */
   _save_copy_to_current( ctx );

   /* Fix up sizes:
    */
   oldsz = save->attrsz[attr];
   save->attrsz[attr] = newsz;

   save->vertex_size += newsz - oldsz;
   save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) / 
		      save->vertex_size);
   save->vert_count = 0;

   /* Recalculate all the attrptr[] values:
    */
   for (i = 0, tmp = save->vertex ; i < VBO_ATTRIB_MAX ; i++) {
      if (save->attrsz[i]) {
	 save->attrptr[i] = tmp;
	 tmp += save->attrsz[i];
      }
      else 
	 save->attrptr[i] = NULL; /* will not be dereferenced. */
   }

   /* Copy from current to repopulate the vertex with correct values.
    */
   _save_copy_from_current( ctx );

   /* Replay stored vertices to translate them to new format here.
    *
    * If there are copied vertices and the new (upgraded) attribute
    * has not been defined before, this list is somewhat degenerate,
    * and will need fixup at runtime.
    */
   if (save->copied.nr)
   {
      GLfloat *data = save->copied.buffer;
      GLfloat *dest = save->buffer;
      GLuint j;

      /* Need to note this and fix up at runtime (or loopback):
       */
      if (attr != VBO_ATTRIB_POS && save->currentsz[attr][0] == 0) {
	 assert(oldsz == 0);
	 save->dangling_attr_ref = GL_TRUE;
      }

      for (i = 0 ; i < save->copied.nr ; i++) {
	 for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) {
	    if (save->attrsz[j]) {
	       if (j == attr) {
		  if (oldsz) {
		     COPY_CLEAN_4V( dest, oldsz, data );
		     data += oldsz;
		     dest += newsz;
		  }
		  else {
		     COPY_SZ_4V( dest, newsz, save->current[attr] );
		     dest += newsz;
		  }
	       }
	       else {
		  GLint sz = save->attrsz[j];
		  COPY_SZ_4V( dest, sz, data );
		  data += sz;
		  dest += sz;
	       }
	    }
	 }
      }

      save->vbptr = dest;
      save->vert_count += save->copied.nr;
   }
}
Пример #7
0
/**
 * Flush existing data, set new attrib size, replay copied vertices.
 * This is called when we transition from a small vertex attribute size
 * to a larger one.  Ex: glTexCoord2f -> glTexCoord4f.
 * We need to go back over the previous 2-component texcoords and insert
 * zero and one values.
 */ 
static void
vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
                             GLuint attr, GLuint newSize )
{
   struct gl_context *ctx = exec->ctx;
   struct vbo_context *vbo = vbo_context(ctx);
   const GLint lastcount = exec->vtx.vert_count;
   fi_type *old_attrptr[VBO_ATTRIB_MAX];
   const GLuint old_vtx_size = exec->vtx.vertex_size; /* floats per vertex */
   const GLuint oldSize = exec->vtx.attrsz[attr];
   GLuint i;

   /* Run pipeline on current vertices, copy wrapped vertices
    * to exec->vtx.copied.
    */
   vbo_exec_wrap_buffers( exec );

   if (unlikely(exec->vtx.copied.nr)) {
      /* We're in the middle of a primitive, keep the old vertex
       * format around to be able to translate the copied vertices to
       * the new format.
       */
      memcpy(old_attrptr, exec->vtx.attrptr, sizeof(old_attrptr));
   }

   if (unlikely(oldSize)) {
      /* Do a COPY_TO_CURRENT to ensure back-copying works for the
       * case when the attribute already exists in the vertex and is
       * having its size increased.
       */
      vbo_exec_copy_to_current( exec );
   }

   /* Heuristic: Attempt to isolate attributes received outside
    * begin/end so that they don't bloat the vertices.
    */
   if (!_mesa_inside_begin_end(ctx) &&
       !oldSize && lastcount > 8 && exec->vtx.vertex_size) {
      vbo_exec_copy_to_current( exec );
      reset_attrfv( exec );
   }

   /* Fix up sizes:
    */
   exec->vtx.attrsz[attr] = newSize;
   exec->vtx.vertex_size += newSize - oldSize;
   exec->vtx.max_vert = vbo_compute_max_verts(exec);
   exec->vtx.vert_count = 0;
   exec->vtx.buffer_ptr = exec->vtx.buffer_map;
   exec->vtx.enabled |= BITFIELD64_BIT(attr);

   if (unlikely(oldSize)) {
      /* Size changed, recalculate all the attrptr[] values
       */
      fi_type *tmp = exec->vtx.vertex;

      for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
	 if (exec->vtx.attrsz[i]) {
	    exec->vtx.attrptr[i] = tmp;
	    tmp += exec->vtx.attrsz[i];
	 }
	 else
	    exec->vtx.attrptr[i] = NULL; /* will not be dereferenced */
      }

      /* Copy from current to repopulate the vertex with correct
       * values.
       */
      vbo_exec_copy_from_current( exec );
   }
   else {
      /* Just have to append the new attribute at the end */
      exec->vtx.attrptr[attr] = exec->vtx.vertex +
        exec->vtx.vertex_size - newSize;
   }

   /* Replay stored vertices to translate them
    * to new format here.
    *
    * -- No need to replay - just copy piecewise
    */
   if (unlikely(exec->vtx.copied.nr)) {
      fi_type *data = exec->vtx.copied.buffer;
      fi_type *dest = exec->vtx.buffer_ptr;

      assert(exec->vtx.buffer_ptr == exec->vtx.buffer_map);

      for (i = 0 ; i < exec->vtx.copied.nr ; i++) {
         GLbitfield64 enabled = exec->vtx.enabled;
         while (enabled) {
            const int j = u_bit_scan64(&enabled);
	    GLuint sz = exec->vtx.attrsz[j];
            GLint old_offset = old_attrptr[j] - exec->vtx.vertex;
            GLint new_offset = exec->vtx.attrptr[j] - exec->vtx.vertex;

            assert(sz);

            if (j == attr) {
               if (oldSize) {
                  fi_type tmp[4];
                  COPY_CLEAN_4V_TYPE_AS_UNION(tmp, oldSize,
                                              data + old_offset,
                                              exec->vtx.attrtype[j]);
                  COPY_SZ_4V(dest + new_offset, newSize, tmp);
               } else {
                  fi_type *current = (fi_type *)vbo->currval[j].Ptr;
                  COPY_SZ_4V(dest + new_offset, sz, current);
               }
            }
            else {
               COPY_SZ_4V(dest + new_offset, sz, data + old_offset);
            }
	 }

	 data += old_vtx_size;
	 dest += exec->vtx.vertex_size;
      }

      exec->vtx.buffer_ptr = dest;
      exec->vtx.vert_count += exec->vtx.copied.nr;
      exec->vtx.copied.nr = 0;
   }
}
Пример #8
0
/**
 * Flush existing data, set new attrib size, replay copied vertices.
 * This is called when we transition from a small vertex attribute size
 * to a larger one.  Ex: glTexCoord2f -> glTexCoord4f.
 * We need to go back over the previous 2-component texcoords and insert
 * zero and one values.
 */ 
static void
vbo_exec_wrap_upgrade_vertex(struct vbo_exec_context *exec,
                             GLuint attr, GLuint newSize )
{
   struct gl_context *ctx = exec->ctx;
   struct vbo_context *vbo = vbo_context(ctx);
   const GLint lastcount = exec->vtx.vert_count;
   GLfloat *old_attrptr[VBO_ATTRIB_MAX];
   const GLuint old_vtx_size = exec->vtx.vertex_size; /* floats per vertex */
   const GLuint oldSize = exec->vtx.attrsz[attr];
   GLuint i;

   /* Run pipeline on current vertices, copy wrapped vertices
    * to exec->vtx.copied.
    */
   vbo_exec_wrap_buffers( exec );

   if (unlikely(exec->vtx.copied.nr)) {
      /* We're in the middle of a primitive, keep the old vertex
       * format around to be able to translate the copied vertices to
       * the new format.
       */
      memcpy(old_attrptr, exec->vtx.attrptr, sizeof(old_attrptr));
   }

   if (unlikely(oldSize)) {
      /* Do a COPY_TO_CURRENT to ensure back-copying works for the
       * case when the attribute already exists in the vertex and is
       * having its size increased.
       */
      vbo_exec_copy_to_current( exec );
   }

   /* Heuristic: Attempt to isolate attributes received outside
    * begin/end so that they don't bloat the vertices.
    */
   if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END &&
       !oldSize && lastcount > 8 && exec->vtx.vertex_size) {
      vbo_exec_copy_to_current( exec );
      reset_attrfv( exec );
   }

   /* Fix up sizes:
    */
   exec->vtx.attrsz[attr] = newSize;
   exec->vtx.vertex_size += newSize - oldSize;
   exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) / 
                         (exec->vtx.vertex_size * sizeof(GLfloat)));
   exec->vtx.vert_count = 0;
   exec->vtx.buffer_ptr = exec->vtx.buffer_map;

   if (unlikely(oldSize)) {
      /* Size changed, recalculate all the attrptr[] values
       */
      GLfloat *tmp = exec->vtx.vertex;

      for (i = 0 ; i < VBO_ATTRIB_MAX ; i++) {
	 if (exec->vtx.attrsz[i]) {
	    exec->vtx.attrptr[i] = tmp;
	    tmp += exec->vtx.attrsz[i];
	 }
	 else
	    exec->vtx.attrptr[i] = NULL; /* will not be dereferenced */
      }

      /* Copy from current to repopulate the vertex with correct
       * values.
       */
      vbo_exec_copy_from_current( exec );
   }
   else {
      /* Just have to append the new attribute at the end */
      exec->vtx.attrptr[attr] = exec->vtx.vertex +
	 exec->vtx.vertex_size - newSize;
   }

   /* Replay stored vertices to translate them
    * to new format here.
    *
    * -- No need to replay - just copy piecewise
    */
   if (unlikely(exec->vtx.copied.nr)) {
      GLfloat *data = exec->vtx.copied.buffer;
      GLfloat *dest = exec->vtx.buffer_ptr;
      GLuint j;

      assert(exec->vtx.buffer_ptr == exec->vtx.buffer_map);

      for (i = 0 ; i < exec->vtx.copied.nr ; i++) {
	 for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) {
	    GLuint sz = exec->vtx.attrsz[j];

	    if (sz) {
	       GLint old_offset = old_attrptr[j] - exec->vtx.vertex;
	       GLint new_offset = exec->vtx.attrptr[j] - exec->vtx.vertex;

	       if (j == attr) {
		  if (oldSize) {
		     GLfloat tmp[4];
		     COPY_CLEAN_4V(tmp, oldSize, data + old_offset);
		     COPY_SZ_4V(dest + new_offset, newSize, tmp);
		  } else {
		     GLfloat *current = (GLfloat *)vbo->currval[j].Ptr;
		     COPY_SZ_4V(dest + new_offset, sz, current);
		  }
	       }
	       else {
		  COPY_SZ_4V(dest + new_offset, sz, data + old_offset);
	       }
	    }
	 }

	 data += old_vtx_size;
	 dest += exec->vtx.vertex_size;
      }

      exec->vtx.buffer_ptr = dest;
      exec->vtx.vert_count += exec->vtx.copied.nr;
      exec->vtx.copied.nr = 0;
   }
}
Пример #9
0
/* Flush existing data, set new attrib size, replay copied vertices.
 */ 
static void _tnl_wrap_upgrade_vertex( GLcontext *ctx, 
				      GLuint attr,
				      GLuint newsz )
{
   TNLcontext *tnl = TNL_CONTEXT(ctx); 
   GLuint oldsz;
   GLuint i;
   GLfloat *tmp;
   GLint lastcount = tnl->vtx.initial_counter - tnl->vtx.counter;

   /* Run pipeline on current vertices, copy wrapped vertices
    * to tnl->vtx.copied.
    */
   _tnl_wrap_buffers( ctx );


   /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
    * when the attribute already exists in the vertex and is having
    * its size increased.  
    */
   _tnl_copy_to_current( ctx );


   /* Heuristic: Attempt to isolate attributes received outside
    * begin/end so that they don't bloat the vertices.
    */
   if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END &&
       tnl->vtx.attrsz[attr] == 0 && 
       lastcount > 8 &&
       tnl->vtx.vertex_size) {
      reset_attrfv( tnl );
   }

   /* Fix up sizes:
    */
   oldsz = tnl->vtx.attrsz[attr];
   tnl->vtx.attrsz[attr] = newsz;

   tnl->vtx.vertex_size += newsz - oldsz;
   tnl->vtx.counter = MIN2( VERT_BUFFER_SIZE / tnl->vtx.vertex_size,
			    ctx->Const.MaxArrayLockSize );
   tnl->vtx.initial_counter = tnl->vtx.counter;
   tnl->vtx.vbptr = tnl->vtx.buffer;


   /* Recalculate all the attrptr[] values
    */
   for (i = 0, tmp = tnl->vtx.vertex ; i < _TNL_ATTRIB_MAX ; i++) {
      if (tnl->vtx.attrsz[i]) {
	 tnl->vtx.attrptr[i] = tmp;
	 tmp += tnl->vtx.attrsz[i];
      }
      else 
	 tnl->vtx.attrptr[i] = NULL; /* will not be dereferenced */
   }

   /* Copy from current to repopulate the vertex with correct values.
    */
   _tnl_copy_from_current( ctx );

   /* Replay stored vertices to translate them
    * to new format here.
    *
    * -- No need to replay - just copy piecewise
    */
   if (tnl->vtx.copied.nr)
   {
      GLfloat *data = tnl->vtx.copied.buffer;
      GLfloat *dest = tnl->vtx.buffer;
      GLuint j;

      for (i = 0 ; i < tnl->vtx.copied.nr ; i++) {
	 for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) {
	    if (tnl->vtx.attrsz[j]) {
	       if (j == attr) {
		  if (oldsz) {
		     COPY_CLEAN_4V( dest, oldsz, data );
		     data += oldsz;
		     dest += newsz;
		  } else {
		     COPY_SZ_4V( dest, newsz, tnl->vtx.current[j] );
		     dest += newsz;
		  }
	       }
	       else {
		  GLuint sz = tnl->vtx.attrsz[j];
		  COPY_SZ_4V( dest, sz, data );
		  dest += sz;
		  data += sz;
	       }
	    }
	 }
      }

      tnl->vtx.vbptr = dest;
      tnl->vtx.counter -= tnl->vtx.copied.nr;
      tnl->vtx.copied.nr = 0;
   }

   /* For codegen - attrptr's may have changed, so need to redo
    * codegen.  Might be a reasonable place to try & detect attributes
    * in the vertex which aren't being submitted any more.
    */
   for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) 
      if (tnl->vtx.attrsz[i]) {
	 GLuint j = tnl->vtx.attrsz[i] - 1;

	 if (i < _TNL_MAX_ATTR_CODEGEN)
	    tnl->vtx.tabfv[i][j] = choose[i][j];
      }

}
Пример #10
0
/* Flush existing data, set new attrib size, replay copied vertices.
 */ 
static void _save_upgrade_vertex( GLcontext *ctx, 
				 GLuint attr,
				 GLuint newsz )
{
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   GLuint oldsz;
   GLuint i;
   GLfloat *tmp;

   /* Store the current run of vertices, and emit a GL_END.  Emit a
    * BEGIN in the new buffer.
    */
   if (tnl->save.initial_counter != tnl->save.counter) 
      _save_wrap_buffers( ctx );
   else
      assert( tnl->save.copied.nr == 0 );

   /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
    * when the attribute already exists in the vertex and is having
    * its size increased.  
    */
   _save_copy_to_current( ctx );

   /* Fix up sizes:
    */
   oldsz = tnl->save.attrsz[attr];
   tnl->save.attrsz[attr] = newsz;

   tnl->save.vertex_size += newsz - oldsz;
   tnl->save.counter = ((SAVE_BUFFER_SIZE - tnl->save.vertex_store->used) / 
			tnl->save.vertex_size);
   if (tnl->save.counter > ctx->Const.MaxArrayLockSize )
      tnl->save.counter = ctx->Const.MaxArrayLockSize;
   tnl->save.initial_counter = tnl->save.counter;

   /* Recalculate all the attrptr[] values:
    */
   for (i = 0, tmp = tnl->save.vertex ; i < _TNL_ATTRIB_MAX ; i++) {
      if (tnl->save.attrsz[i]) {
	 tnl->save.attrptr[i] = tmp;
	 tmp += tnl->save.attrsz[i];
      }
      else 
	 tnl->save.attrptr[i] = 0; /* will not be dereferenced. */
   }

   /* Copy from current to repopulate the vertex with correct values.
    */
   _save_copy_from_current( ctx );

   /* Replay stored vertices to translate them to new format here.
    *
    * If there are copied vertices and the new (upgraded) attribute
    * has not been defined before, this list is somewhat degenerate,
    * and will need fixup at runtime.
    */
   if (tnl->save.copied.nr)
   {
      GLfloat *data = tnl->save.copied.buffer;
      GLfloat *dest = tnl->save.buffer;
      GLuint j;

      /* Need to note this and fix up at runtime (or loopback):
       */
      if (tnl->save.currentsz[attr][0] == 0) {
	 assert(oldsz == 0);
	 tnl->save.dangling_attr_ref = GL_TRUE;
	 _mesa_debug(0, "_save_upgrade_vertex: dangling reference attr %d\n", 
                     attr); 

#if 0
	 /* The current strategy is to punt these degenerate cases
	  * through _tnl_loopback_vertex_list(), a lower-performance
	  * option.  To minimize the impact of this, artificially
	  * reduce the size of this vertex_list.
	  */
	 if (t->save.counter > 10) {
	    t->save.initial_counter = 10;
	    t->save.counter = 10;
	 }
#endif
      }

      for (i = 0 ; i < tnl->save.copied.nr ; i++) {
	 for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) {
	    if (tnl->save.attrsz[j]) {
	       if (j == attr) {
		  if (oldsz) {
		     ASSIGN_4V( dest, 0, 0, 0, 1 );
		     COPY_SZ_4V( dest, oldsz, data );
		     data += oldsz;
		     dest += newsz;
		  }
		  else {
		     COPY_SZ_4V( dest, newsz, tnl->save.current[attr] );
		     dest += newsz;
		  }
	       }
	       else {
		  GLint sz = tnl->save.attrsz[j];
		  COPY_SZ_4V( dest, sz, data );
		  data += sz;
		  dest += sz;
	       }
	    }
	 }
      }

      tnl->save.vbptr = dest;
      tnl->save.counter -= tnl->save.copied.nr;
   }
}
Пример #11
0
void vbo_exec_do_EvalCoord2f( struct vbo_exec_context *exec,
                              GLfloat u, GLfloat v )
{
    GLuint attr;

    for (attr = 1; attr <= VBO_ATTRIB_TEX7; attr++) {
        struct gl_2d_map *map = exec->eval.map2[attr].map;
        if (map) {
            GLfloat uu = (u - map->u1) * map->du;
            GLfloat vv = (v - map->v1) * map->dv;
            GLfloat data[4];

            ASSIGN_4V(data, 0, 0, 0, 1);

            _math_horner_bezier_surf(map->Points,
                                     data,
                                     uu, vv,
                                     exec->eval.map2[attr].sz,
                                     map->Uorder, map->Vorder);

            COPY_SZ_4V( exec->vtx.attrptr[attr],
                        exec->vtx.attrsz[attr],
                        data );
        }
    }

    /** Vertex -- EvalCoord2f is a noop if this map not enabled:
     **/
    if (exec->eval.map2[0].map) {
        struct gl_2d_map *map = exec->eval.map2[0].map;
        GLfloat uu = (u - map->u1) * map->du;
        GLfloat vv = (v - map->v1) * map->dv;
        GLfloat vertex[4];

        ASSIGN_4V(vertex, 0, 0, 0, 1);

        if (exec->ctx->Eval.AutoNormal) {
            GLfloat normal[4];
            GLfloat du[4], dv[4];

            _math_de_casteljau_surf(map->Points, vertex, du, dv, uu, vv,
                                    exec->eval.map2[0].sz,
                                    map->Uorder, map->Vorder);

            if (exec->eval.map2[0].sz == 4) {
                du[0] = du[0]*vertex[3] - du[3]*vertex[0];
                du[1] = du[1]*vertex[3] - du[3]*vertex[1];
                du[2] = du[2]*vertex[3] - du[3]*vertex[2];

                dv[0] = dv[0]*vertex[3] - dv[3]*vertex[0];
                dv[1] = dv[1]*vertex[3] - dv[3]*vertex[1];
                dv[2] = dv[2]*vertex[3] - dv[3]*vertex[2];
            }


            CROSS3(normal, du, dv);
            NORMALIZE_3FV(normal);
            normal[3] = 1.0;

            COPY_SZ_4V( exec->vtx.attrptr[VBO_ATTRIB_NORMAL],
                        exec->vtx.attrsz[VBO_ATTRIB_NORMAL],
                        normal );

        }
        else {
            _math_horner_bezier_surf(map->Points, vertex, uu, vv,
                                     exec->eval.map2[0].sz,
                                     map->Uorder, map->Vorder);
        }

        if (exec->vtx.attrsz[0] == 4)
            CALL_Vertex4fv(GET_DISPATCH(), ( vertex ));
        else
            CALL_Vertex3fv(GET_DISPATCH(), ( vertex ));
    }
}
Пример #12
0
/**
 * Flush existing data, set new attrib size, replay copied vertices.
 */ 
static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec,
					  GLuint attr,
					  GLuint newsz )
{
   GLcontext *ctx = exec->ctx;
   struct vbo_context *vbo = vbo_context(ctx);
   GLint lastcount = exec->vtx.vert_count;
   GLfloat *tmp;
   GLuint oldsz;
   GLuint i;

   /* Run pipeline on current vertices, copy wrapped vertices
    * to exec->vtx.copied.
    */
   vbo_exec_wrap_buffers( exec );


   /* Do a COPY_TO_CURRENT to ensure back-copying works for the case
    * when the attribute already exists in the vertex and is having
    * its size increased.  
    */
   vbo_exec_copy_to_current( exec );


   /* Heuristic: Attempt to isolate attributes received outside
    * begin/end so that they don't bloat the vertices.
    */
   if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END &&
       exec->vtx.attrsz[attr] == 0 && 
       lastcount > 8 &&
       exec->vtx.vertex_size) {
      reset_attrfv( exec );
   }

   /* Fix up sizes:
    */
   oldsz = exec->vtx.attrsz[attr];
   exec->vtx.attrsz[attr] = newsz;

   exec->vtx.vertex_size += newsz - oldsz;
   exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) / 
                         (exec->vtx.vertex_size * sizeof(GLfloat)));
   exec->vtx.vert_count = 0;
   exec->vtx.buffer_ptr = exec->vtx.buffer_map;
   

   /* Recalculate all the attrptr[] values
    */
   for (i = 0, tmp = exec->vtx.vertex ; i < VBO_ATTRIB_MAX ; i++) {
      if (exec->vtx.attrsz[i]) {
	 exec->vtx.attrptr[i] = tmp;
	 tmp += exec->vtx.attrsz[i];
      }
      else 
	 exec->vtx.attrptr[i] = NULL; /* will not be dereferenced */
   }

   /* Copy from current to repopulate the vertex with correct values.
    */
   vbo_exec_copy_from_current( exec );

   /* Replay stored vertices to translate them
    * to new format here.
    *
    * -- No need to replay - just copy piecewise
    */
   if (exec->vtx.copied.nr)
   {
      GLfloat *data = exec->vtx.copied.buffer;
      GLfloat *dest = exec->vtx.buffer_ptr;
      GLuint j;

      assert(exec->vtx.buffer_ptr == exec->vtx.buffer_map);
      
      for (i = 0 ; i < exec->vtx.copied.nr ; i++) {
	 for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) {
	    if (exec->vtx.attrsz[j]) {
	       if (j == attr) {
		  if (oldsz) {
		     COPY_CLEAN_4V( dest, oldsz, data );
		     data += oldsz;
		     dest += newsz;
		  } else {
		     const GLfloat *current = (const GLfloat *)vbo->currval[j].Ptr;
		     COPY_SZ_4V( dest, newsz, current );
		     dest += newsz;
		  }
	       }
	       else {
		  GLuint sz = exec->vtx.attrsz[j];
		  COPY_SZ_4V( dest, sz, data );
		  dest += sz;
		  data += sz;
	       }
	    }
	 }
      }

      exec->vtx.buffer_ptr = dest;
      exec->vtx.vert_count += exec->vtx.copied.nr;
      exec->vtx.copied.nr = 0;
   }
}