예제 #1
0
/* Emit any changed arrays to new agp memory, re-emit a packet to
 * update the arrays.  
 */
void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
{
   radeonContextPtr rmesa = RADEON_CONTEXT( ctx );
   struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
   struct radeon_dma_region **component = rmesa->tcl.aos_components;
   GLuint nr = 0;
   GLuint vfmt = 0;
   GLuint count = VB->Count;
   GLuint vtx;
   
   if (RADEON_DEBUG & DEBUG_VERTS) 
      _tnl_print_vert_flags( __FUNCTION__, inputs );

   if (1) {
      if (!rmesa->tcl.obj.buf) 
	 emit_vector( ctx, 
		      &rmesa->tcl.obj, 
		      (char *)VB->ObjPtr->data,
		      VB->ObjPtr->size,
		      VB->ObjPtr->stride,
		      count);

      switch( VB->ObjPtr->size ) {
      case 4: vfmt |= RADEON_CP_VC_FRMT_W0;
      case 3: vfmt |= RADEON_CP_VC_FRMT_Z;
      case 2: vfmt |= RADEON_CP_VC_FRMT_XY;
      default:
      }
      component[nr++] = &rmesa->tcl.obj;
   }
   

   if (inputs & VERT_NORM) {
      if (!rmesa->tcl.norm.buf)
	 emit_vector( ctx, 
		      &(rmesa->tcl.norm), 
		      (char *)VB->NormalPtr->data,
		      3,
		      VB->NormalPtr->stride,
		      count);

      vfmt |= RADEON_CP_VC_FRMT_N0;
      component[nr++] = &rmesa->tcl.norm;
   }

   if (inputs & VERT_RGBA) {
      if (VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE) {
	 if (!rmesa->tcl.rgba.buf)
	    emit_ubyte_rgba( ctx, 
			     &rmesa->tcl.rgba, 
			     (char *)VB->ColorPtr[0]->Ptr,
			     VB->ColorPtr[0]->Size,
			     VB->ColorPtr[0]->StrideB,
			     count);

	 vfmt |= RADEON_CP_VC_FRMT_PKCOLOR; 
      }
      else {
	 int emitsize;

	 if (VB->ColorPtr[0]->Size == 4 &&
	     (VB->ColorPtr[0]->StrideB != 0 ||
	      ((GLfloat *)VB->ColorPtr[0]->Ptr)[3] != 1.0)) { 
	    vfmt |= RADEON_CP_VC_FRMT_FPCOLOR | RADEON_CP_VC_FRMT_FPALPHA;
	    emitsize = 4;
	 }
	 else { 
	    vfmt |= RADEON_CP_VC_FRMT_FPCOLOR;
	    emitsize = 3;
	 }


	 if (!rmesa->tcl.rgba.buf)
	    emit_vector( ctx, 
			 &(rmesa->tcl.rgba), 
			 (char *)VB->ColorPtr[0]->Ptr,
			 emitsize,
			 VB->ColorPtr[0]->StrideB,
			 count);
      }

      component[nr++] = &rmesa->tcl.rgba;
   }


   if (inputs & VERT_SPEC_RGB) {
      if (!rmesa->tcl.spec.buf) {
	 if (VB->SecondaryColorPtr[0]->Type != GL_UNSIGNED_BYTE)
	    radeon_import_float_spec_colors( ctx );

	 emit_ubyte_rgba( ctx, 
			  &rmesa->tcl.spec, 
			  (char *)VB->SecondaryColorPtr[0]->Ptr,
			  3,
			  VB->SecondaryColorPtr[0]->StrideB,
			  count);
      }

      vfmt |= RADEON_CP_VC_FRMT_PKSPEC; 
      component[nr++] = &rmesa->tcl.spec;
   }

   vtx = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &
	  ~(RADEON_TCL_VTX_Q0|RADEON_TCL_VTX_Q1));
      
   if (inputs & VERT_TEX0) {
      if (!rmesa->tcl.tex[0].buf)
	 emit_tex_vector( ctx, 
			  &(rmesa->tcl.tex[0]), 
			  (char *)VB->TexCoordPtr[0]->data,
			  VB->TexCoordPtr[0]->size,
			  VB->TexCoordPtr[0]->stride,
			  count );

      switch( VB->TexCoordPtr[0]->size ) {
      case 4:
	 vtx |= RADEON_TCL_VTX_Q0; 
	 vfmt |= RADEON_CP_VC_FRMT_Q0;
      default: 
	 vfmt |= RADEON_CP_VC_FRMT_ST0;
      }
      component[nr++] = &rmesa->tcl.tex[0];
   }

   if (inputs & VERT_TEX1) {
      if (!rmesa->tcl.tex[1].buf)
	 emit_tex_vector( ctx, 
			  &(rmesa->tcl.tex[1]), 
			  (char *)VB->TexCoordPtr[1]->data,
			  VB->TexCoordPtr[1]->size,
			  VB->TexCoordPtr[1]->stride,
			  count );
	 
      switch( VB->TexCoordPtr[1]->size ) {
      case 4: 
	 vtx |= RADEON_TCL_VTX_Q1;
	 vfmt |= RADEON_CP_VC_FRMT_Q1;
      default: 
	 vfmt |= RADEON_CP_VC_FRMT_ST1;
      }
      component[nr++] = &rmesa->tcl.tex[1];
   }

   if (vtx != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT]) {
      RADEON_STATECHANGE( rmesa, tcl );
      rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] = vtx;
   }

   rmesa->tcl.nr_aos_components = nr;
   rmesa->tcl.vertex_format = vfmt;
}


void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs )
{
   radeonContextPtr rmesa = RADEON_CONTEXT( ctx );

   if (RADEON_DEBUG & DEBUG_VERTS) 
      _tnl_print_vert_flags( __FUNCTION__, newinputs );

   if (newinputs & VERT_OBJ) 
     radeonReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ );

   if (newinputs & VERT_NORM) 
      radeonReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ );

   if (newinputs & VERT_RGBA) 
      radeonReleaseDmaRegion( rmesa, &rmesa->tcl.rgba, __FUNCTION__ );

   if (newinputs & VERT_SPEC_RGB) 
      radeonReleaseDmaRegion( rmesa, &rmesa->tcl.spec, __FUNCTION__ );

   if (newinputs & VERT_TEX0)
      radeonReleaseDmaRegion( rmesa, &rmesa->tcl.tex[0], __FUNCTION__ );

   if (newinputs & VERT_TEX1)
      radeonReleaseDmaRegion( rmesa, &rmesa->tcl.tex[1], __FUNCTION__ );
}
예제 #2
0
/* Emit any changed arrays to new GART memory, re-emit a packet to
 * update the arrays.
 */
void r200EmitArrays( GLcontext *ctx, GLuint inputs )
{
    r200ContextPtr rmesa = R200_CONTEXT( ctx );
    struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
    struct r200_dma_region **component = rmesa->tcl.aos_components;
    GLuint nr = 0;
    GLuint vfmt0 = 0, vfmt1 = 0;
    GLuint count = VB->Count;
    GLuint i;

    if (1) {
        if (!rmesa->tcl.obj.buf)
            emit_vector( ctx,
                         &rmesa->tcl.obj,
                         (char *)VB->ObjPtr->data,
                         VB->ObjPtr->size,
                         VB->ObjPtr->stride,
                         count);

        switch( VB->ObjPtr->size ) {
        case 4:
            vfmt0 |= R200_VTX_W0;
        case 3:
            vfmt0 |= R200_VTX_Z0;
        case 2:
        default:
            break;
        }
        component[nr++] = &rmesa->tcl.obj;
    }


    if (inputs & VERT_BIT_NORMAL) {
        if (!rmesa->tcl.norm.buf)
            emit_vector( ctx,
                         &(rmesa->tcl.norm),
                         (char *)VB->NormalPtr->data,
                         3,
                         VB->NormalPtr->stride,
                         count);

        vfmt0 |= R200_VTX_N0;
        component[nr++] = &rmesa->tcl.norm;
    }

    if (inputs & VERT_BIT_FOG) {
        if (!rmesa->tcl.fog.buf)
            emit_vecfog( ctx,
                         &(rmesa->tcl.fog),
                         (char *)VB->FogCoordPtr->data,
                         VB->FogCoordPtr->stride,
                         count);

        vfmt0 |= R200_VTX_DISCRETE_FOG;
        component[nr++] = &rmesa->tcl.fog;
    }

    if (inputs & VERT_BIT_COLOR0) {
        int emitsize;

        if (VB->ColorPtr[0]->size == 4 &&
                (VB->ColorPtr[0]->stride != 0 ||
                 VB->ColorPtr[0]->data[0][3] != 1.0)) {
            vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT;
            emitsize = 4;
        }
        else {
            vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_0_SHIFT;
            emitsize = 3;
        }

        if (!rmesa->tcl.rgba.buf)
            emit_vector( ctx,
                         &(rmesa->tcl.rgba),
                         (char *)VB->ColorPtr[0]->data,
                         emitsize,
                         VB->ColorPtr[0]->stride,
                         count);

        component[nr++] = &rmesa->tcl.rgba;
    }


    if (inputs & VERT_BIT_COLOR1) {
        if (!rmesa->tcl.spec.buf) {
            emit_vector( ctx,
                         &rmesa->tcl.spec,
                         (char *)VB->SecondaryColorPtr[0]->data,
                         3,
                         VB->SecondaryColorPtr[0]->stride,
                         count);
        }

        /* How does this work?
         */
        vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_1_SHIFT;
        component[nr++] = &rmesa->tcl.spec;
    }

    for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) {
        if (inputs & (VERT_BIT_TEX0 << i)) {
            if (!rmesa->tcl.tex[i].buf)
                emit_vector( ctx,
                             &(rmesa->tcl.tex[i]),
                             (char *)VB->TexCoordPtr[i]->data,
                             VB->TexCoordPtr[i]->size,
                             VB->TexCoordPtr[i]->stride,
                             count );

            vfmt1 |= VB->TexCoordPtr[i]->size << (i * 3);
            component[nr++] = &rmesa->tcl.tex[i];
        }
    }

    if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] ||
            vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) {
        R200_STATECHANGE( rmesa, vtx );
        rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = vfmt0;
        rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = vfmt1;
    }

    rmesa->tcl.nr_aos_components = nr;
    rmesa->tcl.vertex_format = vfmt0;
}