Exemplo n.º 1
0
/**
 * Copy the active vertex's values to the ctx->Current fields.
 */
static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )
{
   struct gl_context *ctx = exec->ctx;
   struct vbo_context *vbo = vbo_context(ctx);
   GLuint i;

   for (i = VBO_ATTRIB_POS+1 ; i < VBO_ATTRIB_MAX ; i++) {
      if (exec->vtx.attrsz[i]) {
         /* Note: the exec->vtx.current[i] pointers point into the
          * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays.
          */
	 GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
         GLfloat tmp[4];

         COPY_CLEAN_4V_TYPE_AS_FLOAT(tmp,
                                     exec->vtx.attrsz[i],
                                     exec->vtx.attrptr[i],
                                     exec->vtx.attrtype[i]);
         
         if (exec->vtx.attrtype[i] != vbo->currval[i].Type ||
             memcmp(current, tmp, sizeof(tmp)) != 0) {
            memcpy(current, tmp, sizeof(tmp));
	 
            /* Given that we explicitly state size here, there is no need
             * for the COPY_CLEAN above, could just copy 16 bytes and be
             * done.  The only problem is when Mesa accesses ctx->Current
             * directly.
             */
            vbo->currval[i].Size = exec->vtx.attrsz[i];
            vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat);
            vbo->currval[i].Type = exec->vtx.attrtype[i];
            vbo->currval[i].Integer =
                  vbo_attrtype_to_integer_flag(exec->vtx.attrtype[i]);

            /* This triggers rather too much recalculation of Mesa state
             * that doesn't get used (eg light positions).
             */
            if (i >= VBO_ATTRIB_MAT_FRONT_AMBIENT &&
                i <= VBO_ATTRIB_MAT_BACK_INDEXES)
               ctx->NewState |= _NEW_LIGHT;
            
            ctx->NewState |= _NEW_CURRENT_ATTRIB;
         }
      }
   }

   /* Colormaterial -- this kindof sucks.
    */
   if (ctx->Light.ColorMaterialEnabled &&
       exec->vtx.attrsz[VBO_ATTRIB_COLOR0]) {
      _mesa_update_color_material(ctx, 
				  ctx->Current.Attrib[VBO_ATTRIB_COLOR0]);
   }
}
Exemplo n.º 2
0
/**
 * Copy the active vertex's values to the ctx->Current fields.
 */
static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )
{
   struct gl_context *ctx = exec->ctx;
   struct vbo_context *vbo = vbo_context(ctx);
   GLbitfield64 enabled = exec->vtx.enabled & (~BITFIELD64_BIT(VBO_ATTRIB_POS));

   while (enabled) {
      const int i = u_bit_scan64(&enabled);

      /* Note: the exec->vtx.current[i] pointers point into the
       * ctx->Current.Attrib and ctx->Light.Material.Attrib arrays.
       */
      GLfloat *current = (GLfloat *)vbo->currval[i].Ptr;
      fi_type tmp[8]; /* space for doubles */
      int dmul = exec->vtx.attrtype[i] == GL_DOUBLE ? 2 : 1;

      assert(exec->vtx.attrsz[i]);

      if (exec->vtx.attrtype[i] == GL_DOUBLE) {
         memset(tmp, 0, sizeof(tmp));
         memcpy(tmp, exec->vtx.attrptr[i], exec->vtx.attrsz[i] * sizeof(GLfloat));
      } else {
         COPY_CLEAN_4V_TYPE_AS_UNION(tmp,
                                     exec->vtx.attrsz[i],
                                     exec->vtx.attrptr[i],
                                     exec->vtx.attrtype[i]);
      }

      if (exec->vtx.attrtype[i] != vbo->currval[i].Type ||
          memcmp(current, tmp, 4 * sizeof(GLfloat) * dmul) != 0) {
         memcpy(current, tmp, 4 * sizeof(GLfloat) * dmul);
	 
         /* Given that we explicitly state size here, there is no need
          * for the COPY_CLEAN above, could just copy 16 bytes and be
          * done.  The only problem is when Mesa accesses ctx->Current
          * directly.
          */
         /* Size here is in components - not bytes */
         vbo->currval[i].Size = exec->vtx.attrsz[i] / dmul;
         vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat) * dmul;
         vbo->currval[i].Type = exec->vtx.attrtype[i];
         vbo->currval[i].Integer =
            vbo_attrtype_to_integer_flag(exec->vtx.attrtype[i]);
         vbo->currval[i].Doubles =
            vbo_attrtype_to_double_flag(exec->vtx.attrtype[i]);

         /* This triggers rather too much recalculation of Mesa state
          * that doesn't get used (eg light positions).
          */
         if (i >= VBO_ATTRIB_MAT_FRONT_AMBIENT &&
             i <= VBO_ATTRIB_MAT_BACK_INDEXES)
            ctx->NewState |= _NEW_LIGHT;

         ctx->NewState |= _NEW_CURRENT_ATTRIB;
      }
   }

   /* Colormaterial -- this kindof sucks.
    */
   if (ctx->Light.ColorMaterialEnabled &&
       exec->vtx.attrsz[VBO_ATTRIB_COLOR0]) {
      _mesa_update_color_material(ctx, 
				  ctx->Current.Attrib[VBO_ATTRIB_COLOR0]);
   }
}
Exemplo n.º 3
0
/**
 * After playback, copy everything but the position from the
 * last vertex to the saved state
 */
static void
_playback_copy_to_current(struct gl_context *ctx,
                          const struct vbo_save_vertex_list *node)
{
   struct vbo_context *vbo = vbo_context(ctx);
   fi_type vertex[VBO_ATTRIB_MAX * 4];
   fi_type *data;
   GLbitfield64 mask;
   GLuint offset;

   if (node->current_size == 0)
      return;

   if (node->current_data) {
      data = node->current_data;
   }
   else {
      data = vertex;

      if (node->count)
         offset = (node->buffer_offset + 
                   (node->count-1) * node->vertex_size * sizeof(GLfloat));
      else
         offset = node->buffer_offset;

      ctx->Driver.GetBufferSubData( ctx, offset,
                                    node->vertex_size * sizeof(GLfloat), 
                                    data, node->vertex_store->bufferobj );

      data += node->attrsz[0]; /* skip vertex position */
   }

   mask = node->enabled & (~BITFIELD64_BIT(VBO_ATTRIB_POS));
   while (mask) {
      const int i = u_bit_scan64(&mask);
      fi_type *current = (fi_type *)vbo->currval[i].Ptr;
      fi_type tmp[4];
      assert(node->attrsz[i]);

      COPY_CLEAN_4V_TYPE_AS_UNION(tmp,
                                  node->attrsz[i],
                                  data,
                                  node->attrtype[i]);

      if (node->attrtype[i] != vbo->currval[i].Type ||
          memcmp(current, tmp, 4 * sizeof(GLfloat)) != 0) {
         memcpy(current, tmp, 4 * sizeof(GLfloat));
         
         vbo->currval[i].Size = node->attrsz[i];
         vbo->currval[i]._ElementSize = vbo->currval[i].Size * sizeof(GLfloat);
         vbo->currval[i].Type = node->attrtype[i];
         vbo->currval[i].Integer =
            vbo_attrtype_to_integer_flag(node->attrtype[i]);

         if (i >= VBO_ATTRIB_FIRST_MATERIAL &&
             i <= VBO_ATTRIB_LAST_MATERIAL)
            ctx->NewState |= _NEW_LIGHT;

         ctx->NewState |= _NEW_CURRENT_ATTRIB;
      }

      data += node->attrsz[i];
   }

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

   /* CurrentExecPrimitive
    */
   if (node->prim_count) {
      const struct _mesa_prim *prim = &node->prim[node->prim_count - 1];
      if (prim->end)
	 ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
      else
	 ctx->Driver.CurrentExecPrimitive = prim->mode;
   }
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
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 *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->currval[VBO_ATTRIB_POS+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->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++) {
         exec->vtx.inputs[attr] = &vbo->currval[VBO_ATTRIB_POS+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->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)) {
         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);
   }

   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->Mappings[MAP_INTERNAL].Pointer);
            assert(offset >= 0);
            arrays[attr].Ptr = (GLubyte *)
               exec->vtx.bufferobj->Mappings[MAP_INTERNAL].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 = exec->vtx.attrtype[src];
	 arrays[attr].Integer =
               vbo_attrtype_to_integer_flag(exec->vtx.attrtype[src]);
         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);

         varying_inputs |= VERT_BIT(attr);
      }
   }

   _mesa_set_varying_vp_inputs( ctx, varying_inputs );
   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
}