summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/gamma/gamma_render.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/gamma/gamma_render.c')
-rw-r--r--src/mesa/drivers/dri/gamma/gamma_render.c316
1 files changed, 316 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/gamma/gamma_render.c b/src/mesa/drivers/dri/gamma/gamma_render.c
new file mode 100644
index 00000000000..b8bf6171564
--- /dev/null
+++ b/src/mesa/drivers/dri/gamma/gamma_render.c
@@ -0,0 +1,316 @@
+/*
+ * 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;
+ GLubyte (*col)[4];
+ GLuint col_stride;
+ int i;
+ GLuint tc0_stride = 0;
+ GLfloat (*tc0)[4] = 0;
+ GLuint tc0_size = 0;
+
+ if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE)
+ gamma_import_float_colors( ctx );
+
+ col = VB->ColorPtr[0]->Ptr;
+ col_stride = VB->ColorPtr[0]->StrideB;
+
+ 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 (VB->importable_data) {
+ if (start) {
+ coord = (GLfloat (*)[4])((GLubyte *)coord + start * coord_stride);
+ STRIDE_4UB(col, start * col_stride);
+ if (ctx->Texture.Unit[0]._ReallyEnabled)
+ tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + start * tc0_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[0][3]);
+ WRITEF(gmesa->buf, Tr4, tc0[0][2]);
+ WRITEF(gmesa->buf, Tt4, tc0[0][0]);
+ WRITEF(gmesa->buf, Ts4, tc0[0][1]);
+ WRITE(gmesa->buf, PackedColor4, *(CARD32*)col[0]);
+ WRITEF(gmesa->buf, Vw, coord[0][3]);
+ WRITEF(gmesa->buf, Vz, coord[0][2]);
+ WRITEF(gmesa->buf, Vy, coord[0][1]);
+ WRITEF(gmesa->buf, Vx4, coord[0][0]);
+ STRIDE_4UB(col, col_stride);
+ tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride);
+ coord = (GLfloat (*)[4])((GLubyte *)coord + coord_stride);
+ }
+ } 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[0][0]);
+ WRITEF(gmesa->buf, Ts2, tc0[0][1]);
+ WRITE(gmesa->buf, PackedColor4, *(CARD32*)col[0]);
+ WRITEF(gmesa->buf, Vw, coord[0][3]);
+ WRITEF(gmesa->buf, Vz, coord[0][2]);
+ WRITEF(gmesa->buf, Vy, coord[0][1]);
+ WRITEF(gmesa->buf, Vx4, coord[0][0]);
+ STRIDE_4UB(col, col_stride);
+ tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride);
+ coord = (GLfloat (*)[4])((GLubyte *)coord + coord_stride);
+ }
+ } else {
+ for (i=start; i < end; i++) {
+ CHECK_DMA_BUFFER(gmesa, 4);
+ WRITE(gmesa->buf, PackedColor4, *(CARD32*)col[0]);
+ WRITEF(gmesa->buf, Vz, coord[0][2]);
+ WRITEF(gmesa->buf, Vy, coord[0][1]);
+ WRITEF(gmesa->buf, Vx3, coord[0][0]);
+ STRIDE_4UB(col, col_stride);
+ coord = (GLfloat (*)[4])((GLubyte *)coord + coord_stride);
+ }
+ }
+ } else {
+ 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, *(CARD32*)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, *(CARD32*)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, *(CARD32*)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 void VERT_FALLBACK( GLcontext *ctx,
+ GLuint start,
+ GLuint count,
+ GLuint flags )
+{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ tnl->Driver.Render.PrimitiveNotify( ctx, flags & PRIM_MODE_MASK );
+ tnl->Driver.Render.BuildVertices( ctx, start, count, ~0 );
+ tnl->Driver.Render.PrimTabVerts[flags&PRIM_MODE_MASK]( ctx, start, count, flags );
+ GAMMA_CONTEXT(ctx)->SetupNewInputs = VERT_BIT_CLIP;
+}
+
+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 FINISH gammaEndPrimitive( gmesa )
+#define NEW_PRIMITIVE() /* GAMMA_STATECHANGE( gmesa, 0 ) */
+#define NEW_BUFFER() /* GAMMA_FIREVERTICES( gmesa ) */
+#define GET_CURRENT_VB_MAX_VERTS() \
+ (gmesa->bufSize - gmesa->bufCount) / 2
+#define GET_SUBSEQUENT_VB_MAX_VERTS() \
+ GAMMA_DMA_BUFFER_SIZE / 2
+#define EMIT_VERTS( ctx, j, nr ) gamma_emit(ctx, j, (j)+(nr))
+
+#define TAG(x) gamma_##x
+#include "tnl_dd/t_dd_dmatmp.h"
+
+
+/**********************************************************************/
+/* Render pipeline stage */
+/**********************************************************************/
+
+
+static GLboolean gamma_run_render( GLcontext *ctx,
+ struct gl_pipeline_stage *stage )
+{
+ gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+ GLuint i, length, flags = 0;
+ 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)
+ return GL_TRUE;
+
+ tab = TAG(render_tab_verts);
+
+ tnl->Driver.Render.Start( ctx );
+
+ for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length)
+ {
+ flags = VB->Primitive[i];
+ length = VB->PrimitiveLength[i];
+ if (length)
+ tab[flags & PRIM_MODE_MASK]( ctx, i, i + length, flags );
+ }
+
+ tnl->Driver.Render.Finish( ctx );
+
+ return GL_FALSE; /* finished the pipe */
+}
+
+
+static void gamma_check_render( GLcontext *ctx,
+ struct gl_pipeline_stage *stage )
+{
+ GLuint inputs = VERT_BIT_CLIP | VERT_BIT_COLOR0;
+
+ if (ctx->RenderMode == GL_RENDER) {
+ if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
+ inputs |= VERT_BIT_COLOR1;
+
+ if (ctx->Texture.Unit[0]._ReallyEnabled)
+ inputs |= VERT_BIT_TEX0;
+
+ if (ctx->Texture.Unit[1]._ReallyEnabled)
+ inputs |= VERT_BIT_TEX1;
+
+ if (ctx->Fog.Enabled)
+ inputs |= VERT_BIT_FOG;
+ }
+
+ stage->inputs = inputs;
+}
+
+
+static void dtr( struct gl_pipeline_stage *stage )
+{
+ (void)stage;
+}
+
+
+const struct gl_pipeline_stage _gamma_render_stage =
+{
+ "gamma render",
+ (_DD_NEW_SEPARATE_SPECULAR |
+ _NEW_TEXTURE|
+ _NEW_FOG|
+ _NEW_RENDERMODE), /* re-check (new inputs) */
+ 0, /* re-run (always runs) */
+ GL_TRUE, /* active */
+ 0, 0, /* inputs (set in check_render), outputs */
+ 0, 0, /* changed_inputs, private */
+ dtr, /* destructor */
+ gamma_check_render, /* check - initially set to alloc data */
+ gamma_run_render /* run */
+};