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 if (VB
->ColorPtr
[0]->Type
!= GL_UNSIGNED_BYTE
)
57 gamma_import_float_colors( ctx
);
59 col
= VB
->ColorPtr
[0]->Ptr
;
60 col_stride
= VB
->ColorPtr
[0]->StrideB
;
62 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
) {
63 tc0_stride
= VB
->TexCoordPtr
[0]->stride
;
64 tc0
= VB
->TexCoordPtr
[0]->data
;
65 tc0_size
= VB
->TexCoordPtr
[0]->size
;
66 coord
= VB
->ClipPtr
->data
;
67 coord_stride
= VB
->ClipPtr
->stride
;
69 coord
= VB
->NdcPtr
->data
;
70 coord_stride
= VB
->NdcPtr
->stride
;
73 if (VB
->importable_data
) {
75 coord
= (GLfloat (*)[4])((GLubyte
*)coord
+ start
* coord_stride
);
76 STRIDE_4UB(col
, start
* col_stride
);
77 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
)
78 tc0
= (GLfloat (*)[4])((GLubyte
*)tc0
+ start
* tc0_stride
);
81 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
&& tc0_size
== 4) {
82 for (i
=start
; i
< end
; i
++) {
83 CHECK_DMA_BUFFER(gmesa
, 9);
84 WRITEF(gmesa
->buf
, Tq4
, tc0
[0][3]);
85 WRITEF(gmesa
->buf
, Tr4
, tc0
[0][2]);
86 WRITEF(gmesa
->buf
, Tt4
, tc0
[0][0]);
87 WRITEF(gmesa
->buf
, Ts4
, tc0
[0][1]);
88 WRITE(gmesa
->buf
, PackedColor4
, *(CARD32
*)col
[0]);
89 WRITEF(gmesa
->buf
, Vw
, coord
[0][3]);
90 WRITEF(gmesa
->buf
, Vz
, coord
[0][2]);
91 WRITEF(gmesa
->buf
, Vy
, coord
[0][1]);
92 WRITEF(gmesa
->buf
, Vx4
, coord
[0][0]);
93 STRIDE_4UB(col
, col_stride
);
94 tc0
= (GLfloat (*)[4])((GLubyte
*)tc0
+ tc0_stride
);
95 coord
= (GLfloat (*)[4])((GLubyte
*)coord
+ coord_stride
);
97 } else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
&& tc0_size
== 2) {
98 for (i
=start
; i
< end
; i
++) {
99 CHECK_DMA_BUFFER(gmesa
, 7);
100 WRITEF(gmesa
->buf
, Tt2
, tc0
[0][0]);
101 WRITEF(gmesa
->buf
, Ts2
, tc0
[0][1]);
102 WRITE(gmesa
->buf
, PackedColor4
, *(CARD32
*)col
[0]);
103 WRITEF(gmesa
->buf
, Vw
, coord
[0][3]);
104 WRITEF(gmesa
->buf
, Vz
, coord
[0][2]);
105 WRITEF(gmesa
->buf
, Vy
, coord
[0][1]);
106 WRITEF(gmesa
->buf
, Vx4
, coord
[0][0]);
107 STRIDE_4UB(col
, col_stride
);
108 tc0
= (GLfloat (*)[4])((GLubyte
*)tc0
+ tc0_stride
);
109 coord
= (GLfloat (*)[4])((GLubyte
*)coord
+ coord_stride
);
112 for (i
=start
; i
< end
; i
++) {
113 CHECK_DMA_BUFFER(gmesa
, 4);
114 WRITE(gmesa
->buf
, PackedColor4
, *(CARD32
*)col
[0]);
115 WRITEF(gmesa
->buf
, Vz
, coord
[0][2]);
116 WRITEF(gmesa
->buf
, Vy
, coord
[0][1]);
117 WRITEF(gmesa
->buf
, Vx3
, coord
[0][0]);
118 STRIDE_4UB(col
, col_stride
);
119 coord
= (GLfloat (*)[4])((GLubyte
*)coord
+ coord_stride
);
123 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
&& tc0_size
== 4) {
124 for (i
=start
; i
< end
; i
++) {
125 CHECK_DMA_BUFFER(gmesa
, 9);
126 WRITEF(gmesa
->buf
, Tq4
, tc0
[i
][3]);
127 WRITEF(gmesa
->buf
, Tr4
, tc0
[i
][2]);
128 WRITEF(gmesa
->buf
, Tt4
, tc0
[i
][0]);
129 WRITEF(gmesa
->buf
, Ts4
, tc0
[i
][1]);
130 WRITE(gmesa
->buf
, PackedColor4
, *(CARD32
*)col
[i
]);
131 WRITEF(gmesa
->buf
, Vw
, coord
[i
][3]);
132 WRITEF(gmesa
->buf
, Vz
, coord
[i
][2]);
133 WRITEF(gmesa
->buf
, Vy
, coord
[i
][1]);
134 WRITEF(gmesa
->buf
, Vx4
, coord
[i
][0]);
136 } else if (ctx
->Texture
.Unit
[0]._ReallyEnabled
&& tc0_size
== 2) {
137 for (i
=start
; i
< end
; i
++) {
138 CHECK_DMA_BUFFER(gmesa
, 7);
139 WRITEF(gmesa
->buf
, Tt2
, tc0
[i
][0]);
140 WRITEF(gmesa
->buf
, Ts2
, tc0
[i
][1]);
141 WRITE(gmesa
->buf
, PackedColor4
, *(CARD32
*)col
[i
]);
142 WRITEF(gmesa
->buf
, Vw
, coord
[i
][3]);
143 WRITEF(gmesa
->buf
, Vz
, coord
[i
][2]);
144 WRITEF(gmesa
->buf
, Vy
, coord
[i
][1]);
145 WRITEF(gmesa
->buf
, Vx4
, coord
[i
][0]);
148 for (i
=start
; i
< end
; i
++) {
149 CHECK_DMA_BUFFER(gmesa
, 4);
150 WRITE(gmesa
->buf
, PackedColor4
, *(CARD32
*)col
[i
]);
151 WRITEF(gmesa
->buf
, Vz
, coord
[i
][2]);
152 WRITEF(gmesa
->buf
, Vy
, coord
[i
][1]);
153 WRITEF(gmesa
->buf
, Vx3
, coord
[i
][0]);
159 #define HAVE_POINTS 1
161 #define HAVE_LINE_STRIPS 1
162 #define HAVE_TRIANGLES 1
163 #define HAVE_TRI_STRIPS 1
164 #define HAVE_TRI_STRIP_1 0
165 #define HAVE_TRI_FANS 1
167 #define HAVE_QUAD_STRIPS 1
168 #define HAVE_POLYGONS 1
172 static void VERT_FALLBACK( GLcontext
*ctx
,
177 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
178 tnl
->Driver
.Render
.PrimitiveNotify( ctx
, flags
& PRIM_MODE_MASK
);
179 tnl
->Driver
.Render
.BuildVertices( ctx
, start
, count
, ~0 );
180 tnl
->Driver
.Render
.PrimTabVerts
[flags
&PRIM_MODE_MASK
]( ctx
, start
, count
, flags
);
181 GAMMA_CONTEXT(ctx
)->SetupNewInputs
= VERT_BIT_CLIP
;
184 static const GLuint hw_prim
[GL_POLYGON
+1] = {
188 B_PrimType_LineStrip
,
189 B_PrimType_Triangles
,
190 B_PrimType_TriangleStrip
,
191 B_PrimType_TriangleFan
,
193 B_PrimType_QuadStrip
,
197 static __inline
void gammaStartPrimitive( gammaContextPtr gmesa
, GLenum prim
)
199 CHECK_DMA_BUFFER(gmesa
, 1);
200 WRITE(gmesa
->buf
, Begin
, gmesa
->Begin
| hw_prim
[prim
]);
203 static __inline
void gammaEndPrimitive( gammaContextPtr gmesa
)
205 GLcontext
*ctx
= gmesa
->glCtx
;
207 if ( ctx
->Line
.SmoothFlag
||
208 ctx
->Polygon
.SmoothFlag
||
209 ctx
->Point
.SmoothFlag
) {
210 CHECK_DMA_BUFFER(gmesa
, 1);
211 WRITE(gmesa
->buf
, FlushSpan
, 0);
214 CHECK_DMA_BUFFER(gmesa
, 1);
215 WRITE(gmesa
->buf
, End
, 0);
218 #define LOCAL_VARS gammaContextPtr gmesa = GAMMA_CONTEXT(ctx)
219 #define INIT( prim ) gammaStartPrimitive( gmesa, prim )
220 #define FINISH gammaEndPrimitive( gmesa )
221 #define NEW_PRIMITIVE() /* GAMMA_STATECHANGE( gmesa, 0 ) */
222 #define NEW_BUFFER() /* GAMMA_FIREVERTICES( gmesa ) */
223 #define GET_CURRENT_VB_MAX_VERTS() \
224 (gmesa->bufSize - gmesa->bufCount) / 2
225 #define GET_SUBSEQUENT_VB_MAX_VERTS() \
226 GAMMA_DMA_BUFFER_SIZE / 2
227 #define EMIT_VERTS( ctx, j, nr ) gamma_emit(ctx, j, (j)+(nr))
229 #define TAG(x) gamma_##x
230 #include "tnl_dd/t_dd_dmatmp.h"
233 /**********************************************************************/
234 /* Render pipeline stage */
235 /**********************************************************************/
238 static GLboolean
gamma_run_render( GLcontext
*ctx
,
239 struct gl_pipeline_stage
*stage
)
241 gammaContextPtr gmesa
= GAMMA_CONTEXT(ctx
);
242 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
243 struct vertex_buffer
*VB
= &tnl
->vb
;
244 GLuint i
, length
, flags
= 0;
247 /* GH: THIS IS A HACK!!! */
248 if (VB
->ClipOrMask
|| gmesa
->RenderIndex
!= 0)
249 return GL_TRUE
; /* don't handle clipping here */
251 /* We don't do elts */
255 tab
= TAG(render_tab_verts
);
257 tnl
->Driver
.Render
.Start( ctx
);
259 for (i
= VB
->FirstPrimitive
; !(flags
& PRIM_LAST
) ; i
+= length
)
261 flags
= VB
->Primitive
[i
];
262 length
= VB
->PrimitiveLength
[i
];
264 tab
[flags
& PRIM_MODE_MASK
]( ctx
, i
, i
+ length
, flags
);
267 tnl
->Driver
.Render
.Finish( ctx
);
269 return GL_FALSE
; /* finished the pipe */
273 static void gamma_check_render( GLcontext
*ctx
,
274 struct gl_pipeline_stage
*stage
)
276 GLuint inputs
= VERT_BIT_CLIP
| VERT_BIT_COLOR0
;
278 if (ctx
->RenderMode
== GL_RENDER
) {
279 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
)
280 inputs
|= VERT_BIT_COLOR1
;
282 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
)
283 inputs
|= VERT_BIT_TEX0
;
285 if (ctx
->Texture
.Unit
[1]._ReallyEnabled
)
286 inputs
|= VERT_BIT_TEX1
;
288 if (ctx
->Fog
.Enabled
)
289 inputs
|= VERT_BIT_FOG
;
292 stage
->inputs
= inputs
;
296 static void dtr( struct gl_pipeline_stage
*stage
)
302 const struct gl_pipeline_stage _gamma_render_stage
=
305 (_DD_NEW_SEPARATE_SPECULAR
|
308 _NEW_RENDERMODE
), /* re-check (new inputs) */
309 0, /* re-run (always runs) */
310 GL_TRUE
, /* active */
311 0, 0, /* inputs (set in check_render), outputs */
312 0, 0, /* changed_inputs, private */
313 dtr
, /* destructor */
314 gamma_check_render
, /* check - initially set to alloc data */
315 gamma_run_render
/* run */