示例#1
0
void GLAPIENTRY
_mesa_DisableVertexAttribArrayARB(GLuint index)
{
   struct gl_array_object *arrayObj;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glDisableVertexAttribArrayARB(index)");
      return;
   }

   arrayObj = ctx->Array.ArrayObj;

   ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(arrayObj->VertexAttrib));

   if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled) {
      /* was enabled, now being disabled */
      FLUSH_VERTICES(ctx, _NEW_ARRAY);
      arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_FALSE;
      arrayObj->_Enabled &= ~VERT_BIT_GENERIC(index);
      arrayObj->NewArrays |= VERT_BIT_GENERIC(index);
   }
}
示例#2
0
/**
 * See GL_ARB_instanced_arrays.
 * Note that the instance divisor only applies to generic arrays, not
 * the legacy vertex arrays.
 */
void GLAPIENTRY
_mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
{
   struct gl_client_array *array;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (!ctx->Extensions.ARB_instanced_arrays) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
      return;
   }

   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glVertexAttribDivisor(index = %u)",
                  index);
      return;
   }

   ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib));

   array = &ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)];
   if (array->InstanceDivisor != divisor) {
      FLUSH_VERTICES(ctx, _NEW_ARRAY);
      array->InstanceDivisor = divisor;
      ctx->Array.ArrayObj->NewArrays |= VERT_BIT(VERT_ATTRIB_GENERIC(index));
   }
}
示例#3
0
/**
 * Return info for a vertex attribute array (no alias with legacy
 * vertex attributes (pos, normal, color, etc)).  This function does
 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query.
 */
static GLuint
get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname,
                  const char *caller)
{
   const struct gl_client_array *array;

   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index);
      return 0;
   }

   ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib));

   array = &ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)];

   switch (pname) {
   case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
      return array->Enabled;
   case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
      return array->Size;
   case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
      return array->Stride;
   case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
      return array->Type;
   case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
      return array->Normalized;
   case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
      return array->BufferObj->Name;
   case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
      if (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4) {
         return array->Integer;
      }
      goto error;
   case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB:
      if (ctx->Extensions.ARB_instanced_arrays) {
         return array->InstanceDivisor;
      }
      goto error;
   default:
      ; /* fall-through */
   }

error:
   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname);
   return 0;
}
示例#4
0
void GLAPIENTRY
_mesa_DisableVertexAttribArrayARB(GLuint index)
{
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glDisableVertexAttribArrayARB(index)");
      return;
   }

   ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib));

   FLUSH_VERTICES(ctx, _NEW_ARRAY);
   ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_FALSE;
   ctx->Array.ArrayObj->_Enabled &= ~VERT_BIT_GENERIC(index);
   ctx->Array.NewState |= VERT_BIT_GENERIC(index);
}
示例#5
0
static const GLfloat *
get_current_attrib(struct gl_context *ctx, GLuint index, const char *function)
{
   if (index == 0) {
      if (ctx->API != API_OPENGLES2) {
	 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function);
	 return NULL;
      }
   }
   else if (index >= ctx->Const.VertexProgram.MaxAttribs) {
      _mesa_error(ctx, GL_INVALID_VALUE,
		  "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function);
      return NULL;
   }

   ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib));

   FLUSH_CURRENT(ctx, 0);
   return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)];
}
示例#6
0
void GLAPIENTRY
_mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
{
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
      return;
   }

   if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
      return;
   }

   ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib));

   *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr;
}
示例#7
0
/**
 * See GL_ARB_instanced_arrays.
 * Note that the instance divisor only applies to generic arrays, not
 * the legacy vertex arrays.
 */
void GLAPIENTRY
_mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
{
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);

   if (!ctx->Extensions.ARB_instanced_arrays) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
      return;
   }

   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glVertexAttribDivisor(index = %u)",
                  index);
      return;
   }

   ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib));

   ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].InstanceDivisor = divisor;
}
示例#8
0
文件: vbo_save.c 项目: 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;
}
示例#9
0
/**
 * Print current vertex object/array info.  For debug.
 */
void
_mesa_print_arrays(struct gl_context *ctx)
{
   struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
   GLuint i;

   _mesa_update_array_object_max_element(ctx, arrayObj);

   printf("Array Object %u\n", arrayObj->Name);
   if (arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled)
      print_array("Vertex", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_POS]);
   if (arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled)
      print_array("Normal", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]);
   if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled)
      print_array("Color", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]);
   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
      if (arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)].Enabled)
         print_array("TexCoord", i, &arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)]);
   for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++)
      if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
         print_array("Attrib", i, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)]);
   printf("  _MaxElement = %u\n", arrayObj->_MaxElement);
}
示例#10
0
static bool
brw_fast_clear_init(struct brw_context *brw)
{
   struct brw_fast_clear_state *clear;
   struct gl_context *ctx = &brw->ctx;

   if (brw->fast_clear_state) {
      clear = brw->fast_clear_state;
      _mesa_BindVertexArray(clear->vao);
      return true;
   }

   brw->fast_clear_state = clear = malloc(sizeof *clear);
   if (clear == NULL)
      return false;

   memset(clear, 0, sizeof *clear);
   _mesa_GenVertexArrays(1, &clear->vao);
   _mesa_BindVertexArray(clear->vao);

   clear->buf_obj = ctx->Driver.NewBufferObject(ctx, 0xDEADBEEF);
   if (clear->buf_obj == NULL)
      return false;

   clear->array_obj = _mesa_lookup_vao(ctx, clear->vao);
   assert(clear->array_obj != NULL);

   _mesa_update_array_format(ctx, clear->array_obj, VERT_ATTRIB_GENERIC(0),
                             2, GL_FLOAT, GL_RGBA, GL_FALSE, GL_FALSE, GL_FALSE,
                             0, true);
   _mesa_bind_vertex_buffer(ctx, clear->array_obj, VERT_ATTRIB_GENERIC(0),
                            clear->buf_obj, 0, sizeof(float) * 2);
   _mesa_enable_vertex_array_attrib(ctx, clear->array_obj,
                                    VERT_ATTRIB_GENERIC(0));

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

   init_legacy_currval( ctx );
   init_generic_currval( ctx );
   init_mat_currval( ctx );
   vbo_set_indirect_draw_func(ctx, vbo_draw_indirect_prims);

   /* Build mappings from VERT_ATTRIB -> VBO_ATTRIB depending on type
    * of vertex program active.
    */
   {
      GLuint i;

      /* identity mapping */
      for (i = 0; i < ARRAY_SIZE(vbo->map_vp_none); i++) 
	 vbo->map_vp_none[i] = i;
      /* map material attribs to generic slots */
      for (i = 0; i < MAT_ATTRIB_MAX; i++)
	 vbo->map_vp_none[VERT_ATTRIB_GENERIC(i)]
            = VBO_ATTRIB_MAT_FRONT_AMBIENT + i;

      for (i = 0; i < ARRAY_SIZE(vbo->map_vp_arb); i++)
	 vbo->map_vp_arb[i] = i;
   }


   /* 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 );

   _math_init_eval();

   return GL_TRUE;
}
示例#12
0
static GLboolean check_active_shininess( struct gl_context *ctx,
                                         const struct state_key *key,
                                         GLuint side )
{
   GLuint attr = MAT_ATTRIB_FRONT_SHININESS + side;

   if ((key->varying_vp_inputs & VERT_BIT_COLOR0) &&
       (key->light_color_material_mask & (1 << attr)))
      return GL_TRUE;

   if (key->varying_vp_inputs & VERT_ATTRIB_GENERIC(attr))
      return GL_TRUE;

   if (ctx->Light.Material.Attrib[attr][0] != 0.0F)
      return GL_TRUE;

   return GL_FALSE;
}
/**
 * Get a vertex array attribute pointer.
 * \note Not compiled into display lists.
 * \note Called from the GL API dispatcher.
 */
void GLAPIENTRY
_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer)
{
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerNV(index)");
      return;
   }

   if (pname != GL_ATTRIB_ARRAY_POINTER_NV) {
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerNV(pname)");
      return;
   }

   *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr;
}
/**
 * Get a vertex (or vertex array) attribute.
 * \note Not compiled into display lists.
 * \note Called from the GL API dispatcher.
 */
void GLAPIENTRY
_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params)
{
   const struct gl_client_array *array;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)");
      return;
   }

   array = &ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)];

   switch (pname) {
      case GL_ATTRIB_ARRAY_SIZE_NV:
         params[0] = array->Size;
         break;
      case GL_ATTRIB_ARRAY_STRIDE_NV:
         params[0] = array->Stride;
         break;
      case GL_ATTRIB_ARRAY_TYPE_NV:
         params[0] = array->Type;
         break;
      case GL_CURRENT_ATTRIB_NV:
         if (index == 0) {
            _mesa_error(ctx, GL_INVALID_OPERATION,
                        "glGetVertexAttribivNV(index == 0)");
            return;
         }
	 FLUSH_CURRENT(ctx, 0);
         params[0] = (GLint) ctx->Current.Attrib[index][0];
         params[1] = (GLint) ctx->Current.Attrib[index][1];
         params[2] = (GLint) ctx->Current.Attrib[index][2];
         params[3] = (GLint) ctx->Current.Attrib[index][3];
         break;
      case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
         params[0] = array->BufferObj->Name;
         break;
      default:
         _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV");
         return;
   }
}
示例#15
0
/**
 * GL_EXT_gpu_shader4 / GL 3.0.
 * Set an integer-valued vertex attribute array.
 * Note that these arrays DO NOT alias the conventional GL vertex arrays
 * (position, normal, color, fog, texcoord, etc).
 */
void GLAPIENTRY
_mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type,
                           GLsizei stride, const GLvoid *ptr)
{
   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
                                  INT_BIT | UNSIGNED_INT_BIT);
   const GLboolean normalized = GL_FALSE;
   const GLboolean integer = GL_TRUE;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)");
      return;
   }

   update_array(ctx, "glVertexAttribIPointer", VERT_ATTRIB_GENERIC(index),
                legalTypes, 1, 4,
                size, type, stride, normalized, integer, ptr);
}
示例#16
0
/**
 * Set a generic vertex attribute array.
 * Note that these arrays DO NOT alias the conventional GL vertex arrays
 * (position, normal, color, fog, texcoord, etc).
 */
void GLAPIENTRY
_mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
                             GLboolean normalized,
                             GLsizei stride, const GLvoid *ptr)
{
   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
                                  INT_BIT | UNSIGNED_INT_BIT |
                                  HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
                                  FIXED_ES_BIT | FIXED_GL_BIT |
                                  UNSIGNED_INT_2_10_10_10_REV_BIT |
                                  INT_2_10_10_10_REV_BIT);
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)");
      return;
   }

   update_array(ctx, "glVertexAttribPointer", VERT_ATTRIB_GENERIC(index),
                legalTypes, 1, BGRA_OR_4,
                size, type, stride, normalized, GL_FALSE, ptr);
}
示例#17
0
/**
 * Set a vertex attribute array.
 * Note that these arrays DO alias the conventional GL vertex arrays
 * (position, normal, color, fog, texcoord, etc).
 * The generic attribute slots at #16 and above are not touched.
 */
void GLAPIENTRY
_mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
                            GLsizei stride, const GLvoid *ptr)
{
   const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT |
                                  FLOAT_BIT | DOUBLE_BIT);
   GLboolean normalized = GL_FALSE;
   GET_CURRENT_CONTEXT(ctx);
   ASSERT_OUTSIDE_BEGIN_END(ctx);

   if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)");
      return;
   }

   if (type == GL_UNSIGNED_BYTE && size != 4) {
      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)");
      return;
   }

   update_array(ctx, "glVertexAttribPointerNV", VERT_ATTRIB_GENERIC(index),
                legalTypes, 1, BGRA_OR_4,
                size, type, stride, normalized, GL_FALSE, ptr);
}
示例#18
0
/**
 * Set the vbo->exec->inputs[] pointers to point to the enabled
 * vertex arrays.  This depends on the current vertex program/shader
 * being executed because of whether or not generic vertex arrays
 * alias the conventional vertex arrays.
 * For arrays that aren't enabled, we set the input[attrib] pointer
 * to point at a zero-stride current value "array".
 */
static void
recalculate_input_bindings(struct gl_context *ctx)
{
   struct vbo_context *vbo = vbo_context(ctx);
   struct vbo_exec_context *exec = &vbo->exec;
   struct gl_client_array *vertexAttrib = ctx->Array.ArrayObj->VertexAttrib;
   const struct gl_client_array **inputs = &exec->array.inputs[0];
   GLbitfield64 const_inputs = 0x0;
   GLuint i;

   switch (get_program_mode(ctx)) {
   case VP_NONE:
      /* When no vertex program is active (or the vertex program is generated
       * from fixed-function state).  We put the material values into the
       * generic slots.  This is the only situation where material values
       * are available as per-vertex attributes.
       */
      for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) {
	 if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled)
	    inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
	 else {
	    inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i];
            const_inputs |= VERT_BIT(i);
         }
      }

      for (i = 0; i < MAT_ATTRIB_MAX; i++) {
	 inputs[VERT_ATTRIB_GENERIC(i)] =
	    &vbo->currval[VBO_ATTRIB_MAT_FRONT_AMBIENT+i];
         const_inputs |= VERT_BIT_GENERIC(i);
      }

      /* Could use just about anything, just to fill in the empty
       * slots:
       */
      for (i = MAT_ATTRIB_MAX; i < VERT_ATTRIB_GENERIC_MAX; i++) {
	 inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i];
         const_inputs |= VERT_BIT_GENERIC(i);
      }
      break;

   case VP_ARB:
      /* GL_ARB_vertex_program or GLSL vertex shader - Only the generic[0]
       * attribute array aliases and overrides the legacy position array.  
       *
       * Otherwise, legacy attributes available in the legacy slots,
       * generic attributes in the generic slots and materials are not
       * available as per-vertex attributes.
       */
      if (vertexAttrib[VERT_ATTRIB_GENERIC0].Enabled)
	 inputs[0] = &vertexAttrib[VERT_ATTRIB_GENERIC0];
      else if (vertexAttrib[VERT_ATTRIB_POS].Enabled)
	 inputs[0] = &vertexAttrib[VERT_ATTRIB_POS];
      else {
	 inputs[0] = &vbo->currval[VBO_ATTRIB_POS];
         const_inputs |= VERT_BIT_POS;
      }

      for (i = 1; i < VERT_ATTRIB_FF_MAX; i++) {
	 if (vertexAttrib[VERT_ATTRIB_FF(i)].Enabled)
	    inputs[i] = &vertexAttrib[VERT_ATTRIB_FF(i)];
	 else {
	    inputs[i] = &vbo->currval[VBO_ATTRIB_POS+i];
            const_inputs |= VERT_BIT_FF(i);
         }
      }

      for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) {
	 if (vertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
	    inputs[VERT_ATTRIB_GENERIC(i)] = &vertexAttrib[VERT_ATTRIB_GENERIC(i)];
	 else {
	    inputs[VERT_ATTRIB_GENERIC(i)] = &vbo->currval[VBO_ATTRIB_GENERIC0+i];
            const_inputs |= VERT_BIT_GENERIC(i);
         }
      }

      inputs[VERT_ATTRIB_GENERIC0] = inputs[0];
      break;
   }

   _mesa_set_varying_vp_inputs( ctx, VERT_BIT_ALL & (~const_inputs) );
   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
}
示例#19
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 );
}
示例#20
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;
}
示例#21
0
/**
 * Generate an R200 vertex program from Mesa's internal representation.
 *
 * \return  GL_TRUE for success, GL_FALSE for failure.
 */
static GLboolean r200_translate_vertex_program(struct gl_context *ctx, struct r200_vertex_program *vp)
{
   struct gl_vertex_program *mesa_vp = &vp->mesa_program;
   struct prog_instruction *vpi;
   int i;
   VERTEX_SHADER_INSTRUCTION *o_inst;
   unsigned long operands;
   int are_srcs_scalar;
   unsigned long hw_op;
   int dofogfix = 0;
   int fog_temp_i = 0;
   int free_inputs;
   int array_count = 0;
   int u_temp_used;

   vp->native = GL_FALSE;
   vp->translated = GL_TRUE;
   vp->fogmode = ctx->Fog.Mode;

   if (mesa_vp->Base.NumInstructions == 0)
      return GL_FALSE;

#if 0
   if ((mesa_vp->Base.InputsRead &
      ~(VERT_BIT_POS | VERT_BIT_NORMAL | VERT_BIT_COLOR0 | VERT_BIT_COLOR1 |
      VERT_BIT_FOG | VERT_BIT_TEX0 | VERT_BIT_TEX1 | VERT_BIT_TEX2 |
      VERT_BIT_TEX3 | VERT_BIT_TEX4 | VERT_BIT_TEX5)) != 0) {
      if (R200_DEBUG & RADEON_FALLBACKS) {
	 fprintf(stderr, "can't handle vert prog inputs 0x%x\n",
	    mesa_vp->Base.InputsRead);
      }
      return GL_FALSE;
   }
#endif

   if ((mesa_vp->Base.OutputsWritten &
      ~((1 << VARYING_SLOT_POS) | (1 << VARYING_SLOT_COL0) | (1 << VARYING_SLOT_COL1) |
      (1 << VARYING_SLOT_FOGC) | (1 << VARYING_SLOT_TEX0) | (1 << VARYING_SLOT_TEX1) |
      (1 << VARYING_SLOT_TEX2) | (1 << VARYING_SLOT_TEX3) | (1 << VARYING_SLOT_TEX4) |
      (1 << VARYING_SLOT_TEX5) | (1 << VARYING_SLOT_PSIZ))) != 0) {
      if (R200_DEBUG & RADEON_FALLBACKS) {
	 fprintf(stderr, "can't handle vert prog outputs 0x%llx\n",
                 (unsigned long long) mesa_vp->Base.OutputsWritten);
      }
      return GL_FALSE;
   }

   /* Initial value should be last tmp reg that hw supports.
      Strangely enough r300 doesnt mind even though these would be out of range.
      Smart enough to realize that it doesnt need it? */
   int u_temp_i = R200_VSF_MAX_TEMPS - 1;
   struct prog_src_register src[3];
   struct prog_dst_register dst;

/* FIXME: is changing the prog safe to do here? */
   if (mesa_vp->IsPositionInvariant &&
      /* make sure we only do this once */
       !(mesa_vp->Base.OutputsWritten & (1 << VARYING_SLOT_POS))) {
	 _mesa_insert_mvp_code(ctx, mesa_vp);
      }

   /* for fogc, can't change mesa_vp, as it would hose swtnl, and exp with
      base e isn't directly available neither. */
   if ((mesa_vp->Base.OutputsWritten & (1 << VARYING_SLOT_FOGC)) && !vp->fogpidx) {
      struct gl_program_parameter_list *paramList;
      gl_state_index tokens[STATE_LENGTH] = { STATE_FOG_PARAMS, 0, 0, 0, 0 };
      paramList = mesa_vp->Base.Parameters;
      vp->fogpidx = _mesa_add_state_reference(paramList, tokens);
   }

   vp->pos_end = 0;
   mesa_vp->Base.NumNativeInstructions = 0;
   if (mesa_vp->Base.Parameters)
      mesa_vp->Base.NumNativeParameters = mesa_vp->Base.Parameters->NumParameters;
   else
      mesa_vp->Base.NumNativeParameters = 0;

   for(i = 0; i < VERT_ATTRIB_MAX; i++)
      vp->inputs[i] = -1;
   for(i = 0; i < 15; i++)
      vp->inputmap_rev[i] = 255;
   free_inputs = 0x2ffd;

/* fglrx uses fixed inputs as follows for conventional attribs.
   generic attribs use non-fixed assignment, fglrx will always use the
   lowest attrib values available. We'll just do the same.
   There are 12 generic attribs possible, corresponding to attrib 0, 2-11
   and 13 in a hw vertex prog.
   attr 1 and 12 aren't used for generic attribs as those cannot be made vec4
   (correspond to vertex normal/weight - maybe weight actually could be made vec4).
   Additionally, not more than 12 arrays in total are possible I think.
   attr 0 is pos, R200_VTX_XY1|R200_VTX_Z1|R200_VTX_W1 in R200_SE_VTX_FMT_0
   attr 2-5 use colors 0-3 (R200_VTX_FP_RGBA << R200_VTX_COLOR_0/1/2/3_SHIFT in R200_SE_VTX_FMT_0)
   attr 6-11 use tex 0-5 (4 << R200_VTX_TEX0/1/2/3/4/5_COMP_CNT_SHIFT in R200_SE_VTX_FMT_1)
   attr 13 uses vtx1 pos (R200_VTX_XY1|R200_VTX_Z1|R200_VTX_W1 in R200_SE_VTX_FMT_0)
*/

/* attr 4,5 and 13 are only used with generic attribs.
   Haven't seen attr 14 used, maybe that's for the hw pointsize vec1 (which is
   not possibe to use with vertex progs as it is lacking in vert prog specification) */
/* may look different when using idx buf / input_route instead of se_vtx_fmt? */
   if (mesa_vp->Base.InputsRead & VERT_BIT_POS) {
      vp->inputs[VERT_ATTRIB_POS] = 0;
      vp->inputmap_rev[0] = VERT_ATTRIB_POS;
      free_inputs &= ~(1 << 0);
      array_count++;
   }
   if (mesa_vp->Base.InputsRead & VERT_BIT_WEIGHT) {
      vp->inputs[VERT_ATTRIB_WEIGHT] = 12;
      vp->inputmap_rev[1] = VERT_ATTRIB_WEIGHT;
      array_count++;
   }
   if (mesa_vp->Base.InputsRead & VERT_BIT_NORMAL) {
      vp->inputs[VERT_ATTRIB_NORMAL] = 1;
      vp->inputmap_rev[2] = VERT_ATTRIB_NORMAL;
      array_count++;
   }
   if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR0) {
      vp->inputs[VERT_ATTRIB_COLOR0] = 2;
      vp->inputmap_rev[4] = VERT_ATTRIB_COLOR0;
      free_inputs &= ~(1 << 2);
      array_count++;
   }
   if (mesa_vp->Base.InputsRead & VERT_BIT_COLOR1) {
      vp->inputs[VERT_ATTRIB_COLOR1] = 3;
      vp->inputmap_rev[5] = VERT_ATTRIB_COLOR1;
      free_inputs &= ~(1 << 3);
      array_count++;
   }
   if (mesa_vp->Base.InputsRead & VERT_BIT_FOG) {
      vp->inputs[VERT_ATTRIB_FOG] = 15; array_count++;
      vp->inputmap_rev[3] = VERT_ATTRIB_FOG;
      array_count++;
   }
   /* VERT_ATTRIB_TEX0-5 */
   for (i = 0; i <= 5; i++) {
      if (mesa_vp->Base.InputsRead & VERT_BIT_TEX(i)) {
	 vp->inputs[VERT_ATTRIB_TEX(i)] = i + 6;
	 vp->inputmap_rev[8 + i] = VERT_ATTRIB_TEX(i);
	 free_inputs &= ~(1 << (i + 6));
	 array_count++;
      }
   }
   /* using VERT_ATTRIB_TEX6/7 would be illegal */
   for (; i < VERT_ATTRIB_TEX_MAX; i++) {
      if (mesa_vp->Base.InputsRead & VERT_BIT_TEX(i)) {
          if (R200_DEBUG & RADEON_FALLBACKS) {
              fprintf(stderr, "texture attribute %d in vert prog\n", i);
          }
          return GL_FALSE;
      }
   }
   /* completely ignore aliasing? */
   for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++) {
      int j;
   /* completely ignore aliasing? */
      if (mesa_vp->Base.InputsRead & VERT_BIT_GENERIC(i)) {
	 array_count++;
	 if (array_count > 12) {
	    if (R200_DEBUG & RADEON_FALLBACKS) {
	       fprintf(stderr, "more than 12 attribs used in vert prog\n");
	    }
	    return GL_FALSE;
	 }
	 for (j = 0; j < 14; j++) {
	    /* will always find one due to limited array_count */
	    if (free_inputs & (1 << j)) {
	       free_inputs &= ~(1 << j);
	       vp->inputs[VERT_ATTRIB_GENERIC(i)] = j;
	       if (j == 0) {
                  /* mapped to pos */
                  vp->inputmap_rev[j] = VERT_ATTRIB_GENERIC(i);
	       } else if (j < 12) {
                  /* mapped to col/tex */
                  vp->inputmap_rev[j + 2] = VERT_ATTRIB_GENERIC(i);
	       } else {
                  /* mapped to pos1 */
                  vp->inputmap_rev[j + 1] = VERT_ATTRIB_GENERIC(i);
               }
	       break;
	    }
	 }
      }
   }

   if (!(mesa_vp->Base.OutputsWritten & (1 << VARYING_SLOT_POS))) {
      if (R200_DEBUG & RADEON_FALLBACKS) {
	 fprintf(stderr, "can't handle vert prog without position output\n");
      }
      return GL_FALSE;
   }
   if (free_inputs & 1) {
      if (R200_DEBUG & RADEON_FALLBACKS) {
	 fprintf(stderr, "can't handle vert prog without position input\n");
      }
      return GL_FALSE;
   }

   o_inst = vp->instr;
   for (vpi = mesa_vp->Base.Instructions; vpi->Opcode != OPCODE_END; vpi++, o_inst++){
      operands = op_operands(vpi->Opcode);
      are_srcs_scalar = operands & SCALAR_FLAG;
      operands &= OP_MASK;

      for(i = 0; i < operands; i++) {
	 src[i] = vpi->SrcReg[i];
	 /* hack up default attrib values as per spec as swizzling.
	    normal, fog, secondary color. Crazy?
	    May need more if we don't submit vec4 elements? */
	 if (src[i].File == PROGRAM_INPUT) {
	    if (src[i].Index == VERT_ATTRIB_NORMAL) {
	       int j;
	       for (j = 0; j < 4; j++) {
		  if (GET_SWZ(src[i].Swizzle, j) == SWIZZLE_W) {
		     src[i].Swizzle &= ~(SWIZZLE_W << (j*3));
		     src[i].Swizzle |= SWIZZLE_ONE << (j*3);
		  }
	       }
	    }
	    else if (src[i].Index == VERT_ATTRIB_COLOR1) {
	       int j;
	       for (j = 0; j < 4; j++) {
		  if (GET_SWZ(src[i].Swizzle, j) == SWIZZLE_W) {
		     src[i].Swizzle &= ~(SWIZZLE_W << (j*3));
		     src[i].Swizzle |= SWIZZLE_ZERO << (j*3);
		  }
	       }
	    }
	    else if (src[i].Index == VERT_ATTRIB_FOG) {
	       int j;
	       for (j = 0; j < 4; j++) {
		  if (GET_SWZ(src[i].Swizzle, j) == SWIZZLE_W) {
		     src[i].Swizzle &= ~(SWIZZLE_W << (j*3));
		     src[i].Swizzle |= SWIZZLE_ONE << (j*3);
		  }
		  else if ((GET_SWZ(src[i].Swizzle, j) == SWIZZLE_Y) ||
			    GET_SWZ(src[i].Swizzle, j) == SWIZZLE_Z) {
		     src[i].Swizzle &= ~(SWIZZLE_W << (j*3));
		     src[i].Swizzle |= SWIZZLE_ZERO << (j*3);
		  }
	       }
	    }
	 }
      }

      if(operands == 3){
	 if( CMP_SRCS(src[1], src[2]) || CMP_SRCS(src[0], src[2]) ){
	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD,
		(u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
		VSF_FLAG_ALL);

	    o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[2]),
		  SWIZZLE_X, SWIZZLE_Y,
		  SWIZZLE_Z, SWIZZLE_W,
		  t_src_class(src[2].File), VSF_FLAG_NONE) | (src[2].RelAddr << 4);

	    o_inst->src1 = ZERO_SRC_0;
	    o_inst->src2 = UNUSED_SRC_1;
	    o_inst++;

	    src[2].File = PROGRAM_TEMPORARY;
	    src[2].Index = u_temp_i;
	    src[2].RelAddr = 0;
	    u_temp_i--;
	 }
      }

      if(operands >= 2){
	 if( CMP_SRCS(src[1], src[0]) ){
	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD,
		(u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
		VSF_FLAG_ALL);

	    o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
		  SWIZZLE_X, SWIZZLE_Y,
		  SWIZZLE_Z, SWIZZLE_W,
		  t_src_class(src[0].File), VSF_FLAG_NONE) | (src[0].RelAddr << 4);

	    o_inst->src1 = ZERO_SRC_0;
	    o_inst->src2 = UNUSED_SRC_1;
	    o_inst++;

	    src[0].File = PROGRAM_TEMPORARY;
	    src[0].Index = u_temp_i;
	    src[0].RelAddr = 0;
	    u_temp_i--;
	 }
      }

      dst = vpi->DstReg;
      if (dst.File == PROGRAM_OUTPUT &&
	  dst.Index == VARYING_SLOT_FOGC &&
	  dst.WriteMask & WRITEMASK_X) {
	  fog_temp_i = u_temp_i;
	  dst.File = PROGRAM_TEMPORARY;
	  dst.Index = fog_temp_i;
	  dofogfix = 1;
	  u_temp_i--;
      }

      /* These ops need special handling. */
      switch(vpi->Opcode){
      case OPCODE_POW:
/* pow takes only one argument, first scalar is in slot x, 2nd in slot z (other slots don't matter).
   So may need to insert additional instruction */
	 if ((src[0].File == src[1].File) &&
	     (src[0].Index == src[1].Index)) {
	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_POW, t_dst(&dst),
		   t_dst_mask(dst.WriteMask));
	    o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
		   t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
		   SWIZZLE_ZERO,
		   t_swizzle(GET_SWZ(src[1].Swizzle, 0)),
		   SWIZZLE_ZERO,
		   t_src_class(src[0].File),
		   src[0].Negate) | (src[0].RelAddr << 4);
	    o_inst->src1 = UNUSED_SRC_0;
	    o_inst->src2 = UNUSED_SRC_0;
	 }
	 else {
	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD,
		   (u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
		   VSF_FLAG_ALL);
	    o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
		   t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
		   SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO,
		   t_src_class(src[0].File),
		   src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4);
	    o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
		   SWIZZLE_ZERO, SWIZZLE_ZERO,
		   t_swizzle(GET_SWZ(src[1].Swizzle, 0)), SWIZZLE_ZERO,
		   t_src_class(src[1].File),
		   src[1].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4);
	    o_inst->src2 = UNUSED_SRC_1;
	    o_inst++;

	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_POW, t_dst(&dst),
		   t_dst_mask(dst.WriteMask));
	    o_inst->src0 = MAKE_VSF_SOURCE(u_temp_i,
		   VSF_IN_COMPONENT_X,
		   VSF_IN_COMPONENT_Y,
		   VSF_IN_COMPONENT_Z,
		   VSF_IN_COMPONENT_W,
		   VSF_IN_CLASS_TMP,
		   VSF_FLAG_NONE);
	    o_inst->src1 = UNUSED_SRC_0;
	    o_inst->src2 = UNUSED_SRC_0;
	    u_temp_i--;
	 }
	 goto next;

      case OPCODE_MOV://ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO} 
      case OPCODE_SWZ:
	 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, t_dst(&dst),
		t_dst_mask(dst.WriteMask));
	 o_inst->src0 = t_src(vp, &src[0]);
	 o_inst->src1 = ZERO_SRC_0;
	 o_inst->src2 = UNUSED_SRC_1;
	 goto next;

      case OPCODE_MAD:
	 /* only 2 read ports into temp memory thus may need the macro op MAD_2
	    instead (requiring 2 clocks) if all inputs are in temp memory
	    (and, only if they actually reference 3 distinct temps) */
	 hw_op=(src[0].File == PROGRAM_TEMPORARY &&
	    src[1].File == PROGRAM_TEMPORARY &&
	    src[2].File == PROGRAM_TEMPORARY &&
	    (((src[0].RelAddr << 8) | src[0].Index) != ((src[1].RelAddr << 8) | src[1].Index)) &&
	    (((src[0].RelAddr << 8) | src[0].Index) != ((src[2].RelAddr << 8) | src[2].Index)) &&
	    (((src[1].RelAddr << 8) | src[1].Index) != ((src[2].RelAddr << 8) | src[2].Index))) ?
	    R200_VPI_OUT_OP_MAD_2 : R200_VPI_OUT_OP_MAD;

	 o_inst->op = MAKE_VSF_OP(hw_op, t_dst(&dst),
	    t_dst_mask(dst.WriteMask));
	 o_inst->src0 = t_src(vp, &src[0]);
#if 0
if ((o_inst - vp->instr) == 31) {
/* fix up the broken vertex program of quake4 demo... */
o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
			SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X,
			t_src_class(src[1].File),
			src[1].Negate) | (src[1].RelAddr << 4);
o_inst->src2 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
			SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y,
			t_src_class(src[1].File),
			src[1].Negate) | (src[1].RelAddr << 4);
}
else {
	 o_inst->src1 = t_src(vp, &src[1]);
	 o_inst->src2 = t_src(vp, &src[2]);
}
#else
	 o_inst->src1 = t_src(vp, &src[1]);
	 o_inst->src2 = t_src(vp, &src[2]);
#endif
	 goto next;

      case OPCODE_DP3://DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ZERO} PARAM 0{} {X Y Z ZERO} 
	 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_DOT, t_dst(&dst),
		t_dst_mask(dst.WriteMask));

	 o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
		t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
		t_swizzle(GET_SWZ(src[0].Swizzle, 1)),
		t_swizzle(GET_SWZ(src[0].Swizzle, 2)),
		SWIZZLE_ZERO,
		t_src_class(src[0].File),
		src[0].Negate) | (src[0].RelAddr << 4);

	 o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
		t_swizzle(GET_SWZ(src[1].Swizzle, 0)),
		t_swizzle(GET_SWZ(src[1].Swizzle, 1)),
		t_swizzle(GET_SWZ(src[1].Swizzle, 2)),
		SWIZZLE_ZERO,
		t_src_class(src[1].File),
		src[1].Negate) | (src[1].RelAddr << 4);

	 o_inst->src2 = UNUSED_SRC_1;
	 goto next;

      case OPCODE_DPH://DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W} 
	 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_DOT, t_dst(&dst),
		t_dst_mask(dst.WriteMask));

	 o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
		t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
		t_swizzle(GET_SWZ(src[0].Swizzle, 1)),
		t_swizzle(GET_SWZ(src[0].Swizzle, 2)),
		VSF_IN_COMPONENT_ONE,
		t_src_class(src[0].File),
		src[0].Negate) | (src[0].RelAddr << 4);
	 o_inst->src1 = t_src(vp, &src[1]);
	 o_inst->src2 = UNUSED_SRC_1;
	 goto next;

      case OPCODE_SUB://ADD RESULT 1.X Y Z W TMP 0{} {X Y Z W} PARAM 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
	 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, t_dst(&dst),
		t_dst_mask(dst.WriteMask));

	 o_inst->src0 = t_src(vp, &src[0]);
	 o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
		t_swizzle(GET_SWZ(src[1].Swizzle, 0)),
		t_swizzle(GET_SWZ(src[1].Swizzle, 1)),
		t_swizzle(GET_SWZ(src[1].Swizzle, 2)),
		t_swizzle(GET_SWZ(src[1].Swizzle, 3)),
		t_src_class(src[1].File),
		(!src[1].Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4);
	 o_inst->src2 = UNUSED_SRC_1;
	 goto next;

      case OPCODE_ABS://MAX RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
	 o_inst->op=MAKE_VSF_OP(R200_VPI_OUT_OP_MAX, t_dst(&dst),
		t_dst_mask(dst.WriteMask));

	 o_inst->src0=t_src(vp, &src[0]);
	 o_inst->src1=MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
		t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
		t_swizzle(GET_SWZ(src[0].Swizzle, 1)),
		t_swizzle(GET_SWZ(src[0].Swizzle, 2)),
		t_swizzle(GET_SWZ(src[0].Swizzle, 3)),
		t_src_class(src[0].File),
		(!src[0].Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[0].RelAddr << 4);
	 o_inst->src2 = UNUSED_SRC_1;
	 goto next;

      case OPCODE_FLR:
      /* FRC TMP 0.X Y Z W PARAM 0{} {X Y Z W} 
         ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} TMP 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W */

	 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_FRC,
	    (u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
	    t_dst_mask(dst.WriteMask));

	 o_inst->src0 = t_src(vp, &src[0]);
	 o_inst->src1 = UNUSED_SRC_0;
	 o_inst->src2 = UNUSED_SRC_1;
	 o_inst++;

	 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD, t_dst(&dst),
		t_dst_mask(dst.WriteMask));

	 o_inst->src0 = t_src(vp, &src[0]);
	 o_inst->src1 = MAKE_VSF_SOURCE(u_temp_i,
		VSF_IN_COMPONENT_X,
		VSF_IN_COMPONENT_Y,
		VSF_IN_COMPONENT_Z,
		VSF_IN_COMPONENT_W,
		VSF_IN_CLASS_TMP,
		/* Not 100% sure about this */
		(!src[0].Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE/*VSF_FLAG_ALL*/);

	 o_inst->src2 = UNUSED_SRC_0;
	 u_temp_i--;
	 goto next;

      case OPCODE_XPD:
	 /* mul r0, r1.yzxw, r2.zxyw
	    mad r0, -r2.yzxw, r1.zxyw, r0
	  */
	 hw_op=(src[0].File == PROGRAM_TEMPORARY &&
	    src[1].File == PROGRAM_TEMPORARY &&
	    (((src[0].RelAddr << 8) | src[0].Index) != ((src[1].RelAddr << 8) | src[1].Index))) ?
	    R200_VPI_OUT_OP_MAD_2 : R200_VPI_OUT_OP_MAD;

	 o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL,
	    (u_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
	    t_dst_mask(dst.WriteMask));

	 o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
		t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y
		t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // z
		t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x
		t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w
		t_src_class(src[0].File),
		src[0].Negate) | (src[0].RelAddr << 4);

	 o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
		t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // z
		t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // x
		t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // y
		t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // w
		t_src_class(src[1].File),
		src[1].Negate) | (src[1].RelAddr << 4);

	 o_inst->src2 = UNUSED_SRC_1;
	 o_inst++;
	 u_temp_i--;

	 o_inst->op = MAKE_VSF_OP(hw_op, t_dst(&dst),
		t_dst_mask(dst.WriteMask));

	 o_inst->src0 = MAKE_VSF_SOURCE(t_src_index(vp, &src[1]),
		t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // y
		t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // z
		t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // x
		t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // w
		t_src_class(src[1].File),
		(!src[1].Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | (src[1].RelAddr << 4);

	 o_inst->src1 = MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
		t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // z
		t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // x
		t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // y
		t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // w
		t_src_class(src[0].File),
		src[0].Negate) | (src[0].RelAddr << 4);

	 o_inst->src2 = MAKE_VSF_SOURCE(u_temp_i+1,
		VSF_IN_COMPONENT_X,
		VSF_IN_COMPONENT_Y,
		VSF_IN_COMPONENT_Z,
		VSF_IN_COMPONENT_W,
		VSF_IN_CLASS_TMP,
		VSF_FLAG_NONE);
	 goto next;

      case OPCODE_END:
	 assert(0);
      default:
	 break;
      }

      o_inst->op = MAKE_VSF_OP(t_opcode(vpi->Opcode), t_dst(&dst),
	    t_dst_mask(dst.WriteMask));

      if(are_srcs_scalar){
	 switch(operands){
	    case 1:
		o_inst->src0 = t_src_scalar(vp, &src[0]);
		o_inst->src1 = UNUSED_SRC_0;
		o_inst->src2 = UNUSED_SRC_1;
	    break;

	    case 2:
		o_inst->src0 = t_src_scalar(vp, &src[0]);
		o_inst->src1 = t_src_scalar(vp, &src[1]);
		o_inst->src2 = UNUSED_SRC_1;
	    break;

	    case 3:
		o_inst->src0 = t_src_scalar(vp, &src[0]);
		o_inst->src1 = t_src_scalar(vp, &src[1]);
		o_inst->src2 = t_src_scalar(vp, &src[2]);
	    break;

	    default:
		fprintf(stderr, "illegal number of operands %lu\n", operands);
		exit(-1);
	    break;
	 }
      } else {
	 switch(operands){
	    case 1:
		o_inst->src0 = t_src(vp, &src[0]);
		o_inst->src1 = UNUSED_SRC_0;
		o_inst->src2 = UNUSED_SRC_1;
	    break;

	    case 2:
		o_inst->src0 = t_src(vp, &src[0]);
		o_inst->src1 = t_src(vp, &src[1]);
		o_inst->src2 = UNUSED_SRC_1;
	    break;

	    case 3:
		o_inst->src0 = t_src(vp, &src[0]);
		o_inst->src1 = t_src(vp, &src[1]);
		o_inst->src2 = t_src(vp, &src[2]);
	    break;

	    default:
		fprintf(stderr, "illegal number of operands %lu\n", operands);
		exit(-1);
	    break;
	 }
      }
      next:

      if (dofogfix) {
	 o_inst++;
	 if (vp->fogmode == GL_EXP) {
	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL,
		(fog_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
		VSF_FLAG_X);
	    o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE);
	    o_inst->src1 = EASY_VSF_SOURCE(vp->fogpidx, X, X, X, X, PARAM, NONE);
	    o_inst->src2 = UNUSED_SRC_1;
	    o_inst++;
	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_EXP_E,
		R200_VSF_OUT_CLASS_RESULT_FOGC,
		VSF_FLAG_X);
	    o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, ALL);
	    o_inst->src1 = UNUSED_SRC_0;
	    o_inst->src2 = UNUSED_SRC_1;
	 }
	 else if (vp->fogmode == GL_EXP2) {
	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL,
		(fog_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
		VSF_FLAG_X);
	    o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE);
	    o_inst->src1 = EASY_VSF_SOURCE(vp->fogpidx, X, X, X, X, PARAM, NONE);
	    o_inst->src2 = UNUSED_SRC_1;
	    o_inst++;
	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL,
		(fog_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
		VSF_FLAG_X);
	    o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE);
	    o_inst->src1 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE);
	    o_inst->src2 = UNUSED_SRC_1;
	    o_inst++;
	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_EXP_E,
		R200_VSF_OUT_CLASS_RESULT_FOGC,
		VSF_FLAG_X);
	    o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, ALL);
	    o_inst->src1 = UNUSED_SRC_0;
	    o_inst->src2 = UNUSED_SRC_1;
	 }
	 else { /* fogmode == GL_LINEAR */
		/* could do that with single op (dot) if using params like
		   with fixed function pipeline fog */
	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_ADD,
		(fog_temp_i << R200_VPI_OUT_REG_INDEX_SHIFT) | R200_VSF_OUT_CLASS_TMP,
		VSF_FLAG_X);
	    o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, ALL);
	    o_inst->src1 = EASY_VSF_SOURCE(vp->fogpidx, Z, Z, Z, Z, PARAM, NONE);
	    o_inst->src2 = UNUSED_SRC_1;
	    o_inst++;
	    o_inst->op = MAKE_VSF_OP(R200_VPI_OUT_OP_MUL,
		R200_VSF_OUT_CLASS_RESULT_FOGC,
		VSF_FLAG_X);
	    o_inst->src0 = EASY_VSF_SOURCE(fog_temp_i, X, X, X, X, TMP, NONE);
	    o_inst->src1 = EASY_VSF_SOURCE(vp->fogpidx, W, W, W, W, PARAM, NONE);
	    o_inst->src2 = UNUSED_SRC_1;

	 }
         dofogfix = 0;
      }

      u_temp_used = (R200_VSF_MAX_TEMPS - 1) - u_temp_i;
      if (mesa_vp->Base.NumNativeTemporaries <
	 (mesa_vp->Base.NumTemporaries + u_temp_used)) {
	 mesa_vp->Base.NumNativeTemporaries =
	    mesa_vp->Base.NumTemporaries + u_temp_used;
      }
      if ((mesa_vp->Base.NumTemporaries + u_temp_used) > R200_VSF_MAX_TEMPS) {
	 if (R200_DEBUG & RADEON_FALLBACKS) {
	    fprintf(stderr, "Ran out of temps, num temps %d, us %d\n", mesa_vp->Base.NumTemporaries, u_temp_used);
	 }
	 return GL_FALSE;
      }
      u_temp_i = R200_VSF_MAX_TEMPS - 1;
      if(o_inst - vp->instr >= R200_VSF_MAX_INST) {
	 mesa_vp->Base.NumNativeInstructions = 129;
	 if (R200_DEBUG & RADEON_FALLBACKS) {
	    fprintf(stderr, "more than 128 native instructions\n");
	 }
	 return GL_FALSE;
      }
      if ((o_inst->op & R200_VSF_OUT_CLASS_MASK) == R200_VSF_OUT_CLASS_RESULT_POS) {
	 vp->pos_end = (o_inst - vp->instr);
      }
   }

   vp->native = GL_TRUE;
   mesa_vp->Base.NumNativeInstructions = (o_inst - vp->instr);
#if 0
   fprintf(stderr, "hw program:\n");
   for(i=0; i < vp->program.length; i++)
      fprintf(stderr, "%08x\n", vp->instr[i]);
#endif
   return GL_TRUE;
}
示例#22
0
/**
 * Make a list of per-vertex functions to call for each glArrayElement call.
 * These functions access the array data (i.e. glVertex, glColor, glNormal,
 * etc).
 * Note: this may be called during display list construction.
 */
static void
_ae_update_state(struct gl_context *ctx)
{
   AEcontext *actx = AE_CONTEXT(ctx);
   AEarray *aa = actx->arrays;  /* non-indexed arrays (ex: glNormal) */
   AEattrib *at = actx->attribs;  /* indexed arrays (ex: glMultiTexCoord) */
   GLuint i;
   struct gl_vertex_array_object *vao = ctx->Array.VAO;

   actx->nr_vbos = 0;

   /* conventional vertex arrays */
   if (vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) {
      aa->array = &vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX];
      aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
      aa->offset = IndexFuncs[TYPE_IDX(aa->array->Type)];
      check_vbo(actx, aa->binding->BufferObj);
      aa++;
   }

   if (vao->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) {
      aa->array = &vao->VertexAttrib[VERT_ATTRIB_EDGEFLAG];
      aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
      aa->offset = _gloffset_EdgeFlagv;
      check_vbo(actx, aa->binding->BufferObj);
      aa++;
   }

   if (vao->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) {
      aa->array = &vao->VertexAttrib[VERT_ATTRIB_NORMAL];
      aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
      aa->offset = NormalFuncs[TYPE_IDX(aa->array->Type)];
      check_vbo(actx, aa->binding->BufferObj);
      aa++;
   }

   if (vao->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) {
      aa->array = &vao->VertexAttrib[VERT_ATTRIB_COLOR0];
      aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
      aa->offset = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)];
      check_vbo(actx, aa->binding->BufferObj);
      aa++;
   }

   if (vao->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) {
      aa->array = &vao->VertexAttrib[VERT_ATTRIB_COLOR1];
      aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
      aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)];
      check_vbo(actx, aa->binding->BufferObj);
      aa++;
   }

   if (vao->VertexAttrib[VERT_ATTRIB_FOG].Enabled) {
      aa->array = &vao->VertexAttrib[VERT_ATTRIB_FOG];
      aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
      aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Type)];
      check_vbo(actx, aa->binding->BufferObj);
      aa++;
   }

   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
      struct gl_vertex_attrib_array *attribArray =
         &vao->VertexAttrib[VERT_ATTRIB_TEX(i)];
      if (attribArray->Enabled) {
         /* NOTE: we use generic glVertexAttribNV functions here.
          * If we ever remove GL_NV_vertex_program this will have to change.
          */
         at->array = attribArray;
         at->binding = &vao->VertexBinding[attribArray->VertexBinding];
         ASSERT(!at->array->Normalized);
         at->func = AttribFuncsNV[at->array->Normalized]
                                 [at->array->Size-1]
                                 [TYPE_IDX(at->array->Type)];
         at->index = VERT_ATTRIB_TEX0 + i;
	 check_vbo(actx, at->binding->BufferObj);
         at++;
      }
   }

   /* generic vertex attribute arrays */
   for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) {  /* skip zero! */
      struct gl_vertex_attrib_array *attribArray =
         &vao->VertexAttrib[VERT_ATTRIB_GENERIC(i)];
      if (attribArray->Enabled) {
         GLint intOrNorm;
         at->array = attribArray;
         at->binding = &vao->VertexBinding[attribArray->VertexBinding];
         /* Note: we can't grab the _glapi_Dispatch->VertexAttrib1fvNV
          * function pointer here (for float arrays) since the pointer may
          * change from one execution of _ae_ArrayElement() to
          * the next.  Doing so caused UT to break.
          */
         if (at->array->Integer)
            intOrNorm = 2;
         else if (at->array->Normalized)
            intOrNorm = 1;
         else
            intOrNorm = 0;

         at->func = AttribFuncsARB[intOrNorm]
            [at->array->Size-1]
            [TYPE_IDX(at->array->Type)];

         at->index = i;
	 check_vbo(actx, at->binding->BufferObj);
         at++;
      }
   }

   /* finally, vertex position */
   if (vao->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) {
      /* Use glVertex(v) instead of glVertexAttrib(0, v) to be sure it's
       * issued as the last (provoking) attribute).
       */
      aa->array = &vao->VertexAttrib[VERT_ATTRIB_GENERIC0];
      aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
      assert(aa->array->Size >= 2); /* XXX fix someday? */
      aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
      check_vbo(actx, aa->binding->BufferObj);
      aa++;
   }
   else if (vao->VertexAttrib[VERT_ATTRIB_POS].Enabled) {
      aa->array = &vao->VertexAttrib[VERT_ATTRIB_POS];
      aa->binding = &vao->VertexBinding[aa->array->VertexBinding];
      aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)];
      check_vbo(actx, aa->binding->BufferObj);
      aa++;
   }

   check_vbo(actx, vao->IndexBufferObj);

   ASSERT(at - actx->attribs <= VERT_ATTRIB_MAX);
   ASSERT(aa - actx->arrays < 32);
   at->func = NULL;  /* terminate the list */
   aa->offset = -1;  /* terminate the list */

   actx->NewState = 0;
}
示例#23
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;
}
示例#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
/**
 * Helper to enable/disable client-side state.
 */
static void
client_state(struct gl_context *ctx, GLenum cap, GLboolean state)
{
   struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
   GLbitfield64 flag;
   GLboolean *var;

   switch (cap) {
      case GL_VERTEX_ARRAY:
         var = &arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled;
         flag = VERT_BIT_POS;
         break;
      case GL_NORMAL_ARRAY:
         var = &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled;
         flag = VERT_BIT_NORMAL;
         break;
      case GL_COLOR_ARRAY:
         var = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled;
         flag = VERT_BIT_COLOR0;
         break;
      case GL_INDEX_ARRAY:
         var = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled;
         flag = VERT_BIT_COLOR_INDEX;
         break;
      case GL_TEXTURE_COORD_ARRAY:
         var = &arrayObj->VertexAttrib[VERT_ATTRIB_TEX].Enabled;
         flag = VERT_BIT_TEX;
         break;
      case GL_EDGE_FLAG_ARRAY:
         var = &arrayObj->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled;
         flag = VERT_BIT_EDGEFLAG;
         break;
      case GL_FOG_COORDINATE_ARRAY_EXT:
         var = &arrayObj->VertexAttrib[VERT_ATTRIB_FOG].Enabled;
         flag = VERT_BIT_FOG;
         break;
      case GL_SECONDARY_COLOR_ARRAY_EXT:
         var = &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled;
         flag = VERT_BIT_COLOR1;
         break;

#if FEATURE_point_size_array
      case GL_POINT_SIZE_ARRAY_OES:
         var = &arrayObj->VertexAttrib[VERT_ATTRIB_POINT_SIZE].Enabled;
         flag = VERT_BIT_POINT_SIZE;
         break;
#endif

#if FEATURE_NV_vertex_program
      case GL_VERTEX_ATTRIB_ARRAY0_NV:
      case GL_VERTEX_ATTRIB_ARRAY1_NV:
      case GL_VERTEX_ATTRIB_ARRAY2_NV:
      case GL_VERTEX_ATTRIB_ARRAY3_NV:
      case GL_VERTEX_ATTRIB_ARRAY4_NV:
      case GL_VERTEX_ATTRIB_ARRAY5_NV:
      case GL_VERTEX_ATTRIB_ARRAY6_NV:
      case GL_VERTEX_ATTRIB_ARRAY7_NV:
      case GL_VERTEX_ATTRIB_ARRAY8_NV:
      case GL_VERTEX_ATTRIB_ARRAY9_NV:
      case GL_VERTEX_ATTRIB_ARRAY10_NV:
      case GL_VERTEX_ATTRIB_ARRAY11_NV:
      case GL_VERTEX_ATTRIB_ARRAY12_NV:
      case GL_VERTEX_ATTRIB_ARRAY13_NV:
      case GL_VERTEX_ATTRIB_ARRAY14_NV:
      case GL_VERTEX_ATTRIB_ARRAY15_NV:
         CHECK_EXTENSION(NV_vertex_program, cap);
         {
            GLint n = (GLint) cap - GL_VERTEX_ATTRIB_ARRAY0_NV;
            ASSERT(VERT_ATTRIB_GENERIC(n) < Elements(ctx->Array.ArrayObj->VertexAttrib));
            var = &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(n)].Enabled;
            flag = VERT_BIT_GENERIC(n);
         }
         break;
#endif /* FEATURE_NV_vertex_program */

      default:
         goto invalid_enum_error;
   }

   if (*var == state)
      return;

   FLUSH_VERTICES(ctx, _NEW_ARRAY);
   ctx->Array.NewState |= flag;

   _ae_invalidate_state(ctx, _NEW_ARRAY);

   *var = state;

   if (state)
      ctx->Array.ArrayObj->_Enabled |= flag;
   else
      ctx->Array.ArrayObj->_Enabled &= ~flag;

   if (ctx->Driver.Enable) {
      ctx->Driver.Enable( ctx, cap, state );
   }

   return;

invalid_enum_error:
   _mesa_error(ctx, GL_INVALID_ENUM, "gl%sClientState(0x%x)",
               state ? "Enable" : "Disable", cap);
}
示例#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 *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;
}