2 * Copyright 2001 by Alan Hourihane.
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Alan Hourihane not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Alan Hourihane makes no representations
11 * about the suitability of this software for any purpose. It is provided
12 * "as is" without express or implied warranty.
14 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
22 * Authors: Alan Hourihane, <alanh@tungstengraphics.com>
24 * 3DLabs Gamma driver.
34 #include "tnl/t_context.h"
36 #include "gamma_context.h"
37 #include "gamma_tris.h"
41 /* !! Should template this eventually !! */
43 static void gamma_emit( GLcontext
*ctx
, GLuint start
, GLuint end
)
45 gammaContextPtr gmesa
= GAMMA_CONTEXT(ctx
);
46 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
52 GLuint tc0_stride
= 0;
53 GLfloat (*tc0
)[4] = 0;
56 col
= VB
->ColorPtr
[0]->data
;
57 col_stride
= VB
->ColorPtr
[0]->stride
;
59 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
) {
60 tc0_stride
= VB
->TexCoordPtr
[0]->stride
;
61 tc0
= VB
->TexCoordPtr
[0]->data
;
62 tc0_size
= VB
->TexCoordPtr
[0]->size
;
63 coord
= VB
->ClipPtr
->data
;
64 coord_stride
= VB
->ClipPtr
->stride
;
66 coord
= VB
->NdcPtr
->data
;
67 coord_stride
= VB
->NdcPtr
->stride
;
70 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
&& tc0_size
== 4) {
71 for (i
=start
; i
< end
; i
++) {
72 CHECK_DMA_BUFFER(gmesa
, 9);
73 WRITEF(gmesa
->buf
, Tq4
, tc0
[i
][3]);
74 WRITEF(gmesa
->buf
, Tr4
, tc0
[i
][2]);
75 WRITEF(gmesa
->buf
, Tt4
, tc0
[i
][0]);
76 WRITEF(gmesa
->buf
, Ts4
, tc0
[i
][1]);
77 WRITE(gmesa
->buf
, PackedColor4
, *(CARD32
*)col
[i
]);
78 WRITEF(gmesa
->buf
, Vw
, coord
[i
][3]);
79 WRITEF(gmesa
->buf
, Vz
, coord
[i
][2]);
80 WRITEF(gmesa
->buf
, Vy
, coord
[i
][1]);
81 WRITEF(gmesa
->buf
, Vx4
, coord
[i
][0]);
83 } else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
&& tc0_size
== 2) {
84 for (i
=start
; i
< end
; i
++) {
85 CHECK_DMA_BUFFER(gmesa
, 7);
86 WRITEF(gmesa
->buf
, Tt2
, tc0
[i
][0]);
87 WRITEF(gmesa
->buf
, Ts2
, tc0
[i
][1]);
88 WRITE(gmesa
->buf
, PackedColor4
, *(CARD32
*)col
[i
]);
89 WRITEF(gmesa
->buf
, Vw
, coord
[i
][3]);
90 WRITEF(gmesa
->buf
, Vz
, coord
[i
][2]);
91 WRITEF(gmesa
->buf
, Vy
, coord
[i
][1]);
92 WRITEF(gmesa
->buf
, Vx4
, coord
[i
][0]);
95 for (i
=start
; i
< end
; i
++) {
96 CHECK_DMA_BUFFER(gmesa
, 4);
97 WRITE(gmesa
->buf
, PackedColor4
, *(CARD32
*)col
[i
]);
98 WRITEF(gmesa
->buf
, Vz
, coord
[i
][2]);
99 WRITEF(gmesa
->buf
, Vy
, coord
[i
][1]);
100 WRITEF(gmesa
->buf
, Vx3
, coord
[i
][0]);
105 #define HAVE_POINTS 1
107 #define HAVE_LINE_STRIPS 1
108 #define HAVE_TRIANGLES 1
109 #define HAVE_TRI_STRIPS 1
110 #define HAVE_TRI_STRIP_1 0
111 #define HAVE_TRI_FANS 1
113 #define HAVE_QUAD_STRIPS 1
114 #define HAVE_POLYGONS 1
119 static const GLuint hw_prim
[GL_POLYGON
+1] = {
123 B_PrimType_LineStrip
,
124 B_PrimType_Triangles
,
125 B_PrimType_TriangleStrip
,
126 B_PrimType_TriangleFan
,
128 B_PrimType_QuadStrip
,
132 static __inline
void gammaStartPrimitive( gammaContextPtr gmesa
, GLenum prim
)
134 CHECK_DMA_BUFFER(gmesa
, 1);
135 WRITE(gmesa
->buf
, Begin
, gmesa
->Begin
| hw_prim
[prim
]);
138 static __inline
void gammaEndPrimitive( gammaContextPtr gmesa
)
140 GLcontext
*ctx
= gmesa
->glCtx
;
142 if ( ctx
->Line
.SmoothFlag
||
143 ctx
->Polygon
.SmoothFlag
||
144 ctx
->Point
.SmoothFlag
) {
145 CHECK_DMA_BUFFER(gmesa
, 1);
146 WRITE(gmesa
->buf
, FlushSpan
, 0);
149 CHECK_DMA_BUFFER(gmesa
, 1);
150 WRITE(gmesa
->buf
, End
, 0);
153 #define LOCAL_VARS gammaContextPtr gmesa = GAMMA_CONTEXT(ctx)
154 #define INIT( prim ) gammaStartPrimitive( gmesa, prim )
155 #define FLUSH() gammaEndPrimitive( gmesa )
156 #define GET_CURRENT_VB_MAX_VERTS() \
157 (gmesa->bufSize - gmesa->bufCount) / 2
158 #define GET_SUBSEQUENT_VB_MAX_VERTS() \
159 GAMMA_DMA_BUFFER_SIZE / 2
161 #define ALLOC_VERTS( nr ) (void *)0 /* todo: explicit alloc */
162 #define EMIT_VERTS( ctx, j, nr, buf ) (gamma_emit(ctx, j, (j)+(nr)), (void *)0)
164 #define TAG(x) gamma_##x
165 #include "tnl_dd/t_dd_dmatmp.h"
168 /**********************************************************************/
169 /* Render pipeline stage */
170 /**********************************************************************/
173 static GLboolean
gamma_run_render( GLcontext
*ctx
,
174 struct tnl_pipeline_stage
*stage
)
176 gammaContextPtr gmesa
= GAMMA_CONTEXT(ctx
);
177 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
178 struct vertex_buffer
*VB
= &tnl
->vb
;
182 /* GH: THIS IS A HACK!!! */
183 if (VB
->ClipOrMask
|| gmesa
->RenderIndex
!= 0)
184 return GL_TRUE
; /* don't handle clipping here */
186 /* We don't do elts */
187 if (VB
->Elts
|| !gamma_validate_render( ctx
, VB
))
190 tab
= TAG(render_tab_verts
);
192 tnl
->Driver
.Render
.Start( ctx
);
194 for (i
= 0 ; i
< VB
->PrimitiveCount
; i
++)
196 GLuint prim
= VB
->Primitive
[i
].mode
;
197 GLuint start
= VB
->Primitive
[i
].start
;
198 GLuint length
= VB
->Primitive
[i
].count
;
203 tab
[prim
& PRIM_MODE_MASK
]( ctx
, start
, start
+ length
, prim
);
206 tnl
->Driver
.Render
.Finish( ctx
);
208 return GL_FALSE
; /* finished the pipe */
212 static void gamma_check_render( GLcontext
*ctx
,
213 struct tnl_pipeline_stage
*stage
)
215 GLuint inputs
= VERT_BIT_POS
| VERT_BIT_COLOR0
;
217 if (ctx
->RenderMode
== GL_RENDER
) {
218 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
)
219 inputs
|= VERT_BIT_COLOR1
;
221 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
)
222 inputs
|= VERT_BIT_TEX0
;
224 if (ctx
->Texture
.Unit
[1]._ReallyEnabled
)
225 inputs
|= VERT_BIT_TEX1
;
227 if (ctx
->Fog
.Enabled
)
228 inputs
|= VERT_BIT_FOG
;
231 stage
->inputs
= inputs
;
235 static void dtr( struct tnl_pipeline_stage
*stage
)
241 const struct tnl_pipeline_stage _gamma_render_stage
=
244 (_DD_NEW_SEPARATE_SPECULAR
|
247 _NEW_RENDERMODE
), /* re-check (new inputs) */
248 0, /* re-run (always runs) */
249 GL_TRUE
, /* active */
250 0, 0, /* inputs (set in check_render), outputs */
251 0, 0, /* changed_inputs, private */
252 dtr
, /* destructor */
253 gamma_check_render
, /* check - initially set to alloc data */
254 gamma_run_render
/* run */