/*
Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.

The Weather Channel (TM) funded Tungsten Graphics to develop the
initial release of the Radeon 8500 driver under the XFree86 license.
This notice must be preserved.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

**************************************************************************/

/*
 * Authors:
 *   Keith Whitwell <keith@tungstengraphics.com>
 */

#include "glheader.h"
#include "mtypes.h"
#include "colormac.h"
#include "imports.h"
#include "macros.h"

#include "swrast_setup/swrast_setup.h"
#include "math/m_translate.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"

#include "r200_context.h"
#include "r200_ioctl.h"
#include "r200_state.h"
#include "r200_swtcl.h"
#include "r200_maos.h"
#include "r200_tcl.h"


#if 0
/* Usage:
 *   - from r200_tcl_render
 *   - call r200EmitArrays to ensure uptodate arrays in dma
 *   - emit primitives (new type?) which reference the data
 *       -- need to use elts for lineloop, quads, quadstrip/flat
 *       -- other primitives are all well-formed (need tristrip-1,fake-poly)
 *
 */
static void emit_ubyte_rgba3( GLcontext *ctx,
		       struct r200_dma_region *rvb,
		       char *data,
		       int stride,
		       int count )
{
   int i;
   r200_color_t *out = (r200_color_t *)(rvb->start + rvb->address);

   if (R200_DEBUG & DEBUG_VERTS)
      fprintf(stderr, "%s count %d stride %d out %p\n",
	      __FUNCTION__, count, stride, (void *)out);

   for (i = 0; i < count; i++) {
      out->red   = *data;
      out->green = *(data+1);
      out->blue  = *(data+2);
      out->alpha = 0xFF;
      out++;
      data += stride;
   }
}

static void emit_ubyte_rgba4( GLcontext *ctx,
			      struct r200_dma_region *rvb,
			      char *data,
			      int stride,
			      int count )
{
   int i;
   int *out = (int *)(rvb->address + rvb->start);

   if (R200_DEBUG & DEBUG_VERTS)
      fprintf(stderr, "%s count %d stride %d\n",
	      __FUNCTION__, count, stride);

   if (stride == 4) {
      for (i = 0; i < count; i++)
	 ((int *)out)[i] = LE32_TO_CPU(((int *)data)[i]);
   } else {
      for (i = 0; i < count; i++) {
	 *(int *)out++ = LE32_TO_CPU(*(int *)data);
	 data += stride;
      }
   }
}


static void emit_ubyte_rgba( GLcontext *ctx,
			     struct r200_dma_region *rvb,
			     char *data,
			     int size,
			     int stride,
			     int count )
{
   r200ContextPtr rmesa = R200_CONTEXT(ctx);

   if (R200_DEBUG & DEBUG_VERTS)
      fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size);

   assert (!rvb->buf);

   if (stride == 0) {
      r200AllocDmaRegion( rmesa, rvb, 4, 4 );
      count = 1;
      rvb->aos_start = GET_START(rvb);
      rvb->aos_stride = 0;
      rvb->aos_size = 1;
   }
   else {
      r200AllocDmaRegion( rmesa, rvb, 4 * count, 4 );	/* alignment? */
      rvb->aos_start = GET_START(rvb);
      rvb->aos_stride = 1;
      rvb->aos_size = 1;
   }

   /* Emit the data
    */
   switch (size) {
   case 3:
      emit_ubyte_rgba3( ctx, rvb, data, stride, count );
      break;
   case 4:
      emit_ubyte_rgba4( ctx, rvb, data, stride, count );
      break;
   default:
      assert(0);
      exit(1);
      break;
   }
}
#endif


#if defined(USE_X86_ASM)
#define COPY_DWORDS( dst, src, nr )					\
do {									\
	int __tmp;							\
	__asm__ __volatile__( "rep ; movsl"				\
			      : "=%c" (__tmp), "=D" (dst), "=S" (__tmp)	\
			      : "0" (nr),				\
			        "D" ((long)dst),			\
			        "S" ((long)src) );			\
} while (0)
#else
#define COPY_DWORDS( dst, src, nr )		\
do {						\
   int j;					\
   for ( j = 0 ; j < nr ; j++ )			\
      dst[j] = ((int *)src)[j];			\
   dst += nr;					\
} while (0)
#endif


static void emit_vecfog( GLcontext *ctx,
			 struct r200_dma_region *rvb,
			 char *data,
			 int stride,
			 int count )
{
   int i;
   GLfloat *out;

   r200ContextPtr rmesa = R200_CONTEXT(ctx);
   
   if (R200_DEBUG & DEBUG_VERTS)
      fprintf(stderr, "%s count %d stride %d\n",
	      __FUNCTION__, count, stride);

   assert (!rvb->buf);

   if (stride == 0) {
      r200AllocDmaRegion( rmesa, rvb, 4, 4 );
      count = 1;
      rvb->aos_start = GET_START(rvb);
      rvb->aos_stride = 0;
      rvb->aos_size = 1;
   }
   else {
      r200AllocDmaRegion( rmesa, rvb, count * 4, 4 );	/* alignment? */
      rvb->aos_start = GET_START(rvb);
      rvb->aos_stride = 1;
      rvb->aos_size = 1;
   }

   /* Emit the data
    */
   out = (GLfloat *)(rvb->address + rvb->start);
   for (i = 0; i < count; i++) {
      out[0] = r200ComputeFogBlendFactor( ctx, *(GLfloat *)data );
      out++;
      data += stride;
   }

}


static void emit_vec4( GLcontext *ctx,
		       struct r200_dma_region *rvb,
		       char *data,
		       int stride,
		       int count )
{
   int i;
   int *out = (int *)(rvb->address + rvb->start);

   if (R200_DEBUG & DEBUG_VERTS)
      fprintf(stderr, "%s count %d stride %d\n",
	      __FUNCTION__, count, stride);

   if (stride == 4)
      COPY_DWORDS( out, data, count );
   else
      for (i = 0; i < count; i++) {
	 out[0] = *(int *)data;
	 out++;
	 data += stride;
      }
}


static void emit_vec8( GLcontext *ctx,
		       struct r200_dma_region *rvb,
		       char *data,
		       int stride,
		       int count )
{
   int i;
   int *out = (int *)(rvb->address + rvb->start);

   if (R200_DEBUG & DEBUG_VERTS)
      fprintf(stderr, "%s count %d stride %d\n",
	      __FUNCTION__, count, stride);

   if (stride == 8)
      COPY_DWORDS( out, data, count*2 );
   else
      for (i = 0; i < count; i++) {
	 out[0] = *(int *)data;
	 out[1] = *(int *)(data+4);
	 out += 2;
	 data += stride;
      }
}

static void emit_vec12( GLcontext *ctx,
		       struct r200_dma_region *rvb,
		       char *data,
		       int stride,
		       int count )
{
   int i;
   int *out = (int *)(rvb->address + rvb->start);

   if (R200_DEBUG & DEBUG_VERTS)
      fprintf(stderr, "%s count %d stride %d out %p data %p\n",
	      __FUNCTION__, count, stride, (void *)out, (void *)data);

   if (stride == 12)
      COPY_DWORDS( out, data, count*3 );
   else
      for (i = 0; i < count; i++) {
	 out[0] = *(int *)data;
	 out[1] = *(int *)(data+4);
	 out[2] = *(int *)(data+8);
	 out += 3;
	 data += stride;
      }
}

static void emit_vec16( GLcontext *ctx,
			struct r200_dma_region *rvb,
			char *data,
			int stride,
			int count )
{
   int i;
   int *out = (int *)(rvb->address + rvb->start);

   if (R200_DEBUG & DEBUG_VERTS)
      fprintf(stderr, "%s count %d stride %d\n",
	      __FUNCTION__, count, stride);

   if (stride == 16)
      COPY_DWORDS( out, data, count*4 );
   else
      for (i = 0; i < count; i++) {
	 out[0] = *(int *)data;
	 out[1] = *(int *)(data+4);
	 out[2] = *(int *)(data+8);
	 out[3] = *(int *)(data+12);
	 out += 4;
	 data += stride;
      }
}


static void emit_vector( GLcontext *ctx,
			 struct r200_dma_region *rvb,
			 char *data,
			 int size,
			 int stride,
			 int count )
{
   r200ContextPtr rmesa = R200_CONTEXT(ctx);

   if (R200_DEBUG & DEBUG_VERTS)
      fprintf(stderr, "%s count %d size %d stride %d\n",
	      __FUNCTION__, count, size, stride);

   assert (!rvb->buf);

   if (stride == 0) {
      r200AllocDmaRegion( rmesa, rvb, size * 4, 4 );
      count = 1;
      rvb->aos_start = GET_START(rvb);
      rvb->aos_stride = 0;
      rvb->aos_size = size;
   }
   else {
      r200AllocDmaRegion( rmesa, rvb, size * count * 4, 4 );	/* alignment? */
      rvb->aos_start = GET_START(rvb);
      rvb->aos_stride = size;
      rvb->aos_size = size;
   }

   /* Emit the data
    */
   switch (size) {
   case 1:
      emit_vec4( ctx, rvb, data, stride, count );
      break;
   case 2:
      emit_vec8( ctx, rvb, data, stride, count );
      break;
   case 3:
      emit_vec12( ctx, rvb, data, stride, count );
      break;
   case 4:
      emit_vec16( ctx, rvb, data, stride, count );
      break;
   default:
      assert(0);
      exit(1);
      break;
   }

}



/* Emit any changed arrays to new GART memory, re-emit a packet to
 * update the arrays.  
 */
void r200EmitArrays( GLcontext *ctx, GLubyte *vimap_rev )
{
   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, emitsize;

   for ( i = 0; i < 15; i++ ) {
      GLubyte attrib = vimap_rev[i];
      if (attrib != 255) {
	 switch (i) {
	 case 0:
	    emitsize = (VB->AttribPtr[attrib]->size);
	    switch (emitsize) {
	    case 4:
	       vfmt0 |= R200_VTX_W0;
	       /* fallthrough */
	    case 3:
	       vfmt0 |= R200_VTX_Z0;
	       break;
	    case 2:
	       break;
	    default: assert(0);
	    }
	    break;
	 case 1:
	    assert(attrib == VERT_ATTRIB_WEIGHT);
	    emitsize = (VB->AttribPtr[attrib]->size);
	    vfmt0 |= emitsize << R200_VTX_WEIGHT_COUNT_SHIFT;
	    break;
	 case 2:
	    assert(attrib == VERT_ATTRIB_NORMAL);
	    emitsize = 3;
	    vfmt0 |= R200_VTX_N0;
	    break;
	 case 3:
	    /* special handling to fix up fog. Will get us into trouble with vbos...*/
	    assert(attrib == VERT_ATTRIB_FOG);
	    if (!rmesa->tcl.vertex_data[i].buf) {
	       if (ctx->VertexProgram._Enabled)
		  emit_vector( ctx,
			 &(rmesa->tcl.vertex_data[i]),
			 (char *)VB->AttribPtr[attrib]->data,
			 1,
			 VB->AttribPtr[attrib]->stride,
			 count);
	       else
		  emit_vecfog( ctx,
			 &(rmesa->tcl.vertex_data[i]),
			 (char *)VB->AttribPtr[attrib]->data,
			 VB->AttribPtr[attrib]->stride,
			 count);
	    }
	    vfmt0 |= R200_VTX_DISCRETE_FOG;
	    goto after_emit;
	    break;
	 case 4:
	 case 5:
	 case 6:
	 case 7:
	    if (VB->AttribPtr[attrib]->size == 4 &&
	       (VB->AttribPtr[attrib]->stride != 0 ||
		VB->AttribPtr[attrib]->data[0][3] != 1.0)) emitsize = 4;
	    else emitsize = 3;
	    if (emitsize == 4)
	       vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
	    else {
	       vfmt0 |= R200_VTX_FP_RGB << (R200_VTX_COLOR_0_SHIFT + (i - 4) * 2);
	    }
	    break;
	 case 8:
	 case 9:
	 case 10:
	 case 11:
	 case 12:
	 case 13:
	    emitsize = VB->AttribPtr[attrib]->size;
	    vfmt1 |= emitsize << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i - 8) * 3);
	    break;
	 case 14:
	    emitsize = VB->AttribPtr[attrib]->size >= 2 ? VB->AttribPtr[attrib]->size : 2;
	    switch (emitsize) {
	    case 2:
	       vfmt0 |= R200_VTX_XY1;
	       /* fallthrough */
	    case 3:
	       vfmt0 |= R200_VTX_Z1;
	       /* fallthrough */
	    case 4:
	       vfmt0 |= R200_VTX_W1;
	    break;
	    }
	 default:
	    assert(0);
	 }
	 if (!rmesa->tcl.vertex_data[i].buf) {
	    emit_vector( ctx,
			 &(rmesa->tcl.vertex_data[i]),
			 (char *)VB->AttribPtr[attrib]->data,
			 emitsize,
			 VB->AttribPtr[attrib]->stride,
			 count );
	 }
after_emit:
	 assert(nr < 12);
	 component[nr++] = &rmesa->tcl.vertex_data[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;
}


void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs )
{
   r200ContextPtr rmesa = R200_CONTEXT( ctx );

   /* only do it for changed inputs ? */
   int i;
   for (i = 0; i < 15; i++) {
      if (newinputs & (1 << i))
	 r200ReleaseDmaRegion( rmesa,
	    &rmesa->tcl.vertex_data[i], __FUNCTION__ );
   }
}
