1 /* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_vb.c,v 1.4 2003/03/26 20:43:48 tsi Exp $ */
3 * Copyright 2001 by Alan Hourihane.
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of Alan Hourihane not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission. Alan Hourihane makes no representations
12 * about the suitability of this software for any purpose. It is provided
13 * "as is" without express or implied warranty.
15 * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
23 * Authors: Alan Hourihane, <alanh@tungstengraphics.com>
24 * Keith Whitwell, <keith@tungstengraphics.com>
26 * 3DLabs Gamma driver.
35 #include "swrast_setup/swrast_setup.h"
36 #include "tnl/t_context.h"
39 #include "gamma_context.h"
41 #include "gamma_tris.h"
44 #define GAMMA_TEX0_BIT 0x1
45 #define GAMMA_RGBA_BIT 0x2
46 #define GAMMA_XYZW_BIT 0x4
47 #define GAMMA_PTEX_BIT 0x8
48 #define GAMMA_FOG_BIT 0x10
49 #define GAMMA_SPEC_BIT 0x20
50 #define GAMMA_MAX_SETUP 0x40
53 void (*emit
)( GLcontext
*, GLuint
, GLuint
, void *, GLuint
);
56 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
59 } setup_tab
[GAMMA_MAX_SETUP
];
61 #define TINY_VERTEX_FORMAT 1
62 #define NOTEX_VERTEX_FORMAT 2
63 #define TEX0_VERTEX_FORMAT 3
64 #define TEX1_VERTEX_FORMAT 0
65 #define PROJ_TEX1_VERTEX_FORMAT 0
66 #define TEX2_VERTEX_FORMAT 0
67 #define TEX3_VERTEX_FORMAT 0
68 #define PROJ_TEX3_VERTEX_FORMAT 0
70 #define DO_XYZW (IND & GAMMA_XYZW_BIT)
71 #define DO_RGBA (IND & GAMMA_RGBA_BIT)
72 #define DO_SPEC (IND & GAMMA_SPEC_BIT)
73 #define DO_FOG (IND & GAMMA_FOG_BIT)
74 #define DO_TEX0 (IND & GAMMA_TEX0_BIT)
78 #define DO_PTEX (IND & GAMMA_PTEX_BIT)
80 #define VERTEX gammaVertex
81 #define VERTEX_COLOR gamma_color_t
82 #define GET_VIEWPORT_MAT() 0
83 #define GET_TEXSOURCE(n) n
84 #define GET_VERTEX_FORMAT() GAMMA_CONTEXT(ctx)->vertex_format
85 #define GET_VERTEX_STORE() GAMMA_CONTEXT(ctx)->verts
86 #define GET_VERTEX_SIZE() GAMMA_CONTEXT(ctx)->vertex_size * sizeof(GLuint)
87 #define INVALIDATE_STORED_VERTICES()
89 #define HAVE_HW_VIEWPORT 1
90 #define HAVE_HW_DIVIDE 1
91 #define HAVE_RGBA_COLOR 0 /* we're BGRA */
92 #define HAVE_TINY_VERTICES 1
93 #define HAVE_NOTEX_VERTICES 1
94 #define HAVE_TEX0_VERTICES 1
95 #define HAVE_TEX1_VERTICES 0
96 #define HAVE_TEX2_VERTICES 0
97 #define HAVE_TEX3_VERTICES 0
98 #define HAVE_PTEX_VERTICES 1
100 #define PTEX_FALLBACK() /* never needed */
102 #define INTERP_VERTEX setup_tab[GAMMA_CONTEXT(ctx)->SetupIndex].interp
103 #define COPY_PV_VERTEX setup_tab[GAMMA_CONTEXT(ctx)->SetupIndex].copy_pv
107 /***********************************************************************
108 * Generate pv-copying and translation functions *
109 ***********************************************************************/
111 #define TAG(x) gamma_##x
112 #include "tnl_dd/t_dd_vb.c"
114 /***********************************************************************
115 * Generate vertex emit and interp functions *
116 ***********************************************************************/
118 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT)
119 #define TAG(x) x##_wg
120 #include "tnl_dd/t_dd_vbtmp.h"
122 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT)
123 #define TAG(x) x##_wgs
124 #include "tnl_dd/t_dd_vbtmp.h"
126 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_TEX0_BIT)
127 #define TAG(x) x##_wgt0
128 #include "tnl_dd/t_dd_vbtmp.h"
130 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_TEX0_BIT|GAMMA_PTEX_BIT)
131 #define TAG(x) x##_wgpt0
132 #include "tnl_dd/t_dd_vbtmp.h"
134 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT)
135 #define TAG(x) x##_wgst0
136 #include "tnl_dd/t_dd_vbtmp.h"
138 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT|\
140 #define TAG(x) x##_wgspt0
141 #include "tnl_dd/t_dd_vbtmp.h"
143 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT)
144 #define TAG(x) x##_wgf
145 #include "tnl_dd/t_dd_vbtmp.h"
147 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT)
148 #define TAG(x) x##_wgfs
149 #include "tnl_dd/t_dd_vbtmp.h"
151 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT)
152 #define TAG(x) x##_wgft0
153 #include "tnl_dd/t_dd_vbtmp.h"
155 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT|\
157 #define TAG(x) x##_wgfpt0
158 #include "tnl_dd/t_dd_vbtmp.h"
160 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|\
162 #define TAG(x) x##_wgfst0
163 #include "tnl_dd/t_dd_vbtmp.h"
165 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|\
166 GAMMA_TEX0_BIT|GAMMA_PTEX_BIT)
167 #define TAG(x) x##_wgfspt0
168 #include "tnl_dd/t_dd_vbtmp.h"
170 #define IND (GAMMA_TEX0_BIT)
171 #define TAG(x) x##_t0
172 #include "tnl_dd/t_dd_vbtmp.h"
174 #define IND (GAMMA_FOG_BIT)
176 #include "tnl_dd/t_dd_vbtmp.h"
178 #define IND (GAMMA_FOG_BIT|GAMMA_TEX0_BIT)
179 #define TAG(x) x##_ft0
180 #include "tnl_dd/t_dd_vbtmp.h"
182 #define IND (GAMMA_RGBA_BIT)
184 #include "tnl_dd/t_dd_vbtmp.h"
186 #define IND (GAMMA_RGBA_BIT|GAMMA_SPEC_BIT)
187 #define TAG(x) x##_gs
188 #include "tnl_dd/t_dd_vbtmp.h"
190 #define IND (GAMMA_RGBA_BIT|GAMMA_TEX0_BIT)
191 #define TAG(x) x##_gt0
192 #include "tnl_dd/t_dd_vbtmp.h"
194 #define IND (GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT)
195 #define TAG(x) x##_gst0
196 #include "tnl_dd/t_dd_vbtmp.h"
198 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT)
199 #define TAG(x) x##_gf
200 #include "tnl_dd/t_dd_vbtmp.h"
202 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT)
203 #define TAG(x) x##_gfs
204 #include "tnl_dd/t_dd_vbtmp.h"
206 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT)
207 #define TAG(x) x##_gft0
208 #include "tnl_dd/t_dd_vbtmp.h"
210 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT)
211 #define TAG(x) x##_gfst0
212 #include "tnl_dd/t_dd_vbtmp.h"
214 static void init_setup_tab( void )
241 void gammaCheckTexSizes( GLcontext
*ctx
)
243 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
244 gammaContextPtr gmesa
= GAMMA_CONTEXT( ctx
);
246 if (!setup_tab
[gmesa
->SetupIndex
].check_tex_sizes(ctx
)) {
247 /* Invalidate stored verts
249 gmesa
->SetupNewInputs
= ~0;
250 gmesa
->SetupIndex
|= GAMMA_PTEX_BIT
;
252 if (!(ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
253 tnl
->Driver
.Render
.Interp
= setup_tab
[gmesa
->SetupIndex
].interp
;
254 tnl
->Driver
.Render
.CopyPV
= setup_tab
[gmesa
->SetupIndex
].copy_pv
;
259 void gammaBuildVertices( GLcontext
*ctx
,
264 gammaContextPtr gmesa
= GAMMA_CONTEXT( ctx
);
265 GLuint stride
= gmesa
->vertex_size
* sizeof(int);
266 GLubyte
*v
= ((GLubyte
*)gmesa
->verts
+ (start
* stride
));
268 newinputs
|= gmesa
->SetupNewInputs
;
269 gmesa
->SetupNewInputs
= 0;
274 if (newinputs
& VERT_BIT_POS
) {
275 setup_tab
[gmesa
->SetupIndex
].emit( ctx
, start
, count
, v
, stride
);
279 if (newinputs
& VERT_BIT_COLOR0
)
280 ind
|= GAMMA_RGBA_BIT
;
282 if (newinputs
& VERT_BIT_COLOR1
)
283 ind
|= GAMMA_SPEC_BIT
;
285 if (newinputs
& VERT_BIT_TEX0
)
286 ind
|= GAMMA_TEX0_BIT
;
288 if (newinputs
& VERT_BIT_FOG
)
289 ind
|= GAMMA_FOG_BIT
;
291 if (gmesa
->SetupIndex
& GAMMA_PTEX_BIT
)
294 ind
&= gmesa
->SetupIndex
;
297 setup_tab
[ind
].emit( ctx
, start
, count
, v
, stride
);
302 void gammaChooseVertexState( GLcontext
*ctx
)
304 gammaContextPtr gmesa
= GAMMA_CONTEXT( ctx
);
305 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
306 GLuint ind
= GAMMA_XYZW_BIT
|GAMMA_RGBA_BIT
;
308 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
)
309 ind
|= GAMMA_SPEC_BIT
;
311 if (ctx
->Fog
.Enabled
)
312 ind
|= GAMMA_FOG_BIT
;
314 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
) {
315 _tnl_need_projected_coords( ctx
, GL_FALSE
);
316 ind
|= GAMMA_TEX0_BIT
;
318 _tnl_need_projected_coords( ctx
, GL_FALSE
);
320 gmesa
->SetupIndex
= ind
;
322 if (setup_tab
[ind
].vertex_format
!= gmesa
->vertex_format
) {
323 gmesa
->vertex_format
= setup_tab
[ind
].vertex_format
;
324 gmesa
->vertex_size
= setup_tab
[ind
].vertex_size
;
327 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
328 tnl
->Driver
.Render
.Interp
= gamma_interp_extras
;
329 tnl
->Driver
.Render
.CopyPV
= gamma_copy_pv_extras
;
331 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
332 tnl
->Driver
.Render
.CopyPV
= setup_tab
[ind
].copy_pv
;
337 void gammaInitVB( GLcontext
*ctx
)
339 gammaContextPtr gmesa
= GAMMA_CONTEXT(ctx
);
340 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
342 gmesa
->verts
= (GLubyte
*)ALIGN_MALLOC(size
* 4 * 16, 32);
345 static int firsttime
= 1;
349 gmesa
->vertex_size
= 16; /* FIXME - only one vertex setup */
355 void gammaFreeVB( GLcontext
*ctx
)
357 gammaContextPtr gmesa
= GAMMA_CONTEXT(ctx
);
359 ALIGN_FREE(gmesa
->verts
);