/*
 * Copyright 2001 by Alan Hourihane.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Alan Hourihane not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Alan Hourihane makes no representations
 * about the suitability of this software for any purpose.  It is provided
 * "as is" without express or implied warranty.
 *
 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 *
 * Authors:  Alan Hourihane, <alanh@tungstengraphics.com>
 *
 * 3DLabs Gamma driver.
 *
 */

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

#include "tnl/t_context.h"

#include "gamma_context.h"
#include "gamma_tris.h"
#include "gamma_vb.h"


/* !! Should template this eventually !! */

static void gamma_emit( GLcontext *ctx, GLuint start, GLuint end)
{
   gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
   GLfloat (*coord)[4];
   GLuint coord_stride;
   GLfloat (*col)[4];
   GLuint col_stride;
   int i;
   GLuint tc0_stride = 0;
   GLfloat (*tc0)[4] = 0;
   GLuint tc0_size = 0;

   col = VB->ColorPtr[0]->data;
   col_stride = VB->ColorPtr[0]->stride;

   if (ctx->Texture.Unit[0]._ReallyEnabled) {
      tc0_stride = VB->TexCoordPtr[0]->stride;
      tc0 = VB->TexCoordPtr[0]->data;
      tc0_size = VB->TexCoordPtr[0]->size;
      coord = VB->ClipPtr->data;
      coord_stride = VB->ClipPtr->stride;
   } else {
      coord = VB->NdcPtr->data;
      coord_stride = VB->NdcPtr->stride;
   }

   if (ctx->Texture.Unit[0]._ReallyEnabled && tc0_size == 4) {
      for (i=start; i < end; i++) {
	    CHECK_DMA_BUFFER(gmesa, 9);
	    WRITEF(gmesa->buf, Tq4, tc0[i][3]);
	    WRITEF(gmesa->buf, Tr4, tc0[i][2]);
	    WRITEF(gmesa->buf, Tt4, tc0[i][0]);
	    WRITEF(gmesa->buf, Ts4, tc0[i][1]);
	    WRITE(gmesa->buf, PackedColor4, *(u_int32_t*)col[i]);
	    WRITEF(gmesa->buf, Vw, coord[i][3]);
	    WRITEF(gmesa->buf, Vz, coord[i][2]);
	    WRITEF(gmesa->buf, Vy, coord[i][1]);
	    WRITEF(gmesa->buf, Vx4, coord[i][0]);
      }
   } else if (ctx->Texture.Unit[0]._ReallyEnabled && tc0_size == 2) {
      for (i=start; i < end; i++) {
	    CHECK_DMA_BUFFER(gmesa, 7);
	    WRITEF(gmesa->buf, Tt2, tc0[i][0]);
	    WRITEF(gmesa->buf, Ts2, tc0[i][1]);
	    WRITE(gmesa->buf, PackedColor4, *(u_int32_t*)col[i]);
	    WRITEF(gmesa->buf, Vw, coord[i][3]);
	    WRITEF(gmesa->buf, Vz, coord[i][2]);
	    WRITEF(gmesa->buf, Vy, coord[i][1]);
	    WRITEF(gmesa->buf, Vx4, coord[i][0]);
      }
   } else {
      for (i=start; i < end; i++) {
	    CHECK_DMA_BUFFER(gmesa, 4);
	    WRITE(gmesa->buf, PackedColor4, *(u_int32_t*)col[i]);
	    WRITEF(gmesa->buf, Vz, coord[i][2]);
	    WRITEF(gmesa->buf, Vy, coord[i][1]);
	    WRITEF(gmesa->buf, Vx3, coord[i][0]);
      }
   }
}

#define HAVE_POINTS      1
#define HAVE_LINES       1
#define HAVE_LINE_STRIPS 1
#define HAVE_TRIANGLES   1
#define HAVE_TRI_STRIPS  1
#define HAVE_TRI_STRIP_1 0
#define HAVE_TRI_FANS    1
#define HAVE_QUADS       1
#define HAVE_QUAD_STRIPS 1
#define HAVE_POLYGONS    1

#define HAVE_ELTS        0


static const GLuint hw_prim[GL_POLYGON+1] = {
   B_PrimType_Points,
   B_PrimType_Lines,
   B_PrimType_LineLoop,
   B_PrimType_LineStrip,
   B_PrimType_Triangles,
   B_PrimType_TriangleStrip,
   B_PrimType_TriangleFan,
   B_PrimType_Quads,
   B_PrimType_QuadStrip,
   B_PrimType_Polygon
};

static INLINE void gammaStartPrimitive( gammaContextPtr gmesa, GLenum prim )
{
   CHECK_DMA_BUFFER(gmesa, 1);
   WRITE(gmesa->buf, Begin, gmesa->Begin | hw_prim[prim]);
}

static INLINE void gammaEndPrimitive( gammaContextPtr gmesa )
{
   GLcontext *ctx = gmesa->glCtx;

   if ( ctx->Line.SmoothFlag || 
        ctx->Polygon.SmoothFlag || 
        ctx->Point.SmoothFlag ) {
      CHECK_DMA_BUFFER(gmesa, 1);
      WRITE(gmesa->buf, FlushSpan, 0);
   }

   CHECK_DMA_BUFFER(gmesa, 1);
   WRITE(gmesa->buf, End, 0);
}

#define LOCAL_VARS gammaContextPtr gmesa = GAMMA_CONTEXT(ctx)
#define INIT( prim ) gammaStartPrimitive( gmesa, prim )
#define FLUSH() gammaEndPrimitive( gmesa )
#define GET_CURRENT_VB_MAX_VERTS() \
  (gmesa->bufSize - gmesa->bufCount) / 2
#define GET_SUBSEQUENT_VB_MAX_VERTS() \
  GAMMA_DMA_BUFFER_SIZE / 2

#define ALLOC_VERTS( nr ) (void *)0	/* todo: explicit alloc */
#define EMIT_VERTS( ctx, j, nr, buf ) (gamma_emit(ctx, j, (j)+(nr)), (void *)0)

#define TAG(x) gamma_##x
#include "tnl_dd/t_dd_dmatmp.h"


/**********************************************************************/
/*                          Render pipeline stage                     */
/**********************************************************************/


static GLboolean gamma_run_render( GLcontext *ctx,
				  struct tnl_pipeline_stage *stage )
{
   gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
   TNLcontext *tnl = TNL_CONTEXT(ctx);
   struct vertex_buffer *VB = &tnl->vb;
   GLuint i;
   tnl_render_func *tab;

				/* GH: THIS IS A HACK!!! */
   if (VB->ClipOrMask || gmesa->RenderIndex != 0)
      return GL_TRUE;		/* don't handle clipping here */

   /* We don't do elts */
   if (VB->Elts || !gamma_validate_render( ctx, VB ))
      return GL_TRUE;

   tab = TAG(render_tab_verts);

   tnl->Driver.Render.Start( ctx );

   for (i = 0 ; i < VB->PrimitiveCount ; i++)
   {
      GLuint prim = _tnl_translate_prim(&VB->Primitive[i]);
      GLuint start = VB->Primitive[i].start;
      GLuint length = VB->Primitive[i].count;

      if (!length)
	 continue;

      tab[prim & PRIM_MODE_MASK]( ctx, start, start + length, prim);
   }

   tnl->Driver.Render.Finish( ctx );

   return GL_FALSE;		/* finished the pipe */
}


const struct tnl_pipeline_stage _gamma_render_stage =
{
   "gamma render",
   NULL,
   NULL,
   NULL,
   NULL,
   gamma_run_render		/* run */
};
