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>
23 * Keith Whitwell, <keith@tungstengraphics.com>
25 * 3DLabs Gamma driver.
28 #include "main/glheader.h"
29 #include "main/mtypes.h"
30 #include "main/imports.h"
31 #include "main/macros.h"
32 #include "main/colormac.h"
34 #include "swrast_setup/swrast_setup.h"
35 #include "tnl/tcontext.h"
38 #include "gamma_context.h"
40 #include "gamma_tris.h"
43 #define GAMMA_TEX0_BIT 0x1
44 #define GAMMA_RGBA_BIT 0x2
45 #define GAMMA_XYZW_BIT 0x4
46 #define GAMMA_PTEX_BIT 0x8
47 #define GAMMA_FOG_BIT 0x10
48 #define GAMMA_SPEC_BIT 0x20
49 #define GAMMA_MAX_SETUP 0x40
52 void (*emit
)( GLcontext
*, GLuint
, GLuint
, void *, GLuint
);
53 tnl_interp_func interp
;
54 tnl_copy_pv_func copy_pv
;
55 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
58 } setup_tab
[GAMMA_MAX_SETUP
];
60 #define TINY_VERTEX_FORMAT 1
61 #define NOTEX_VERTEX_FORMAT 2
62 #define TEX0_VERTEX_FORMAT 3
63 #define TEX1_VERTEX_FORMAT 0
64 #define PROJ_TEX1_VERTEX_FORMAT 0
65 #define TEX2_VERTEX_FORMAT 0
66 #define TEX3_VERTEX_FORMAT 0
67 #define PROJ_TEX3_VERTEX_FORMAT 0
69 #define DO_XYZW (IND & GAMMA_XYZW_BIT)
70 #define DO_RGBA (IND & GAMMA_RGBA_BIT)
71 #define DO_SPEC (IND & GAMMA_SPEC_BIT)
72 #define DO_FOG (IND & GAMMA_FOG_BIT)
73 #define DO_TEX0 (IND & GAMMA_TEX0_BIT)
77 #define DO_PTEX (IND & GAMMA_PTEX_BIT)
79 #define VERTEX gammaVertex
80 #define VERTEX_COLOR gamma_color_t
81 #define GET_VIEWPORT_MAT() 0
82 #define GET_TEXSOURCE(n) n
83 #define GET_VERTEX_FORMAT() GAMMA_CONTEXT(ctx)->vertex_format
84 #define GET_VERTEX_STORE() GAMMA_CONTEXT(ctx)->verts
85 #define GET_VERTEX_SIZE() GAMMA_CONTEXT(ctx)->vertex_size * sizeof(GLuint)
86 #define INVALIDATE_STORED_VERTICES()
88 #define HAVE_HW_VIEWPORT 1
89 #define HAVE_HW_DIVIDE 1
90 #define HAVE_RGBA_COLOR 0 /* we're BGRA */
91 #define HAVE_TINY_VERTICES 1
92 #define HAVE_NOTEX_VERTICES 1
93 #define HAVE_TEX0_VERTICES 1
94 #define HAVE_TEX1_VERTICES 0
95 #define HAVE_TEX2_VERTICES 0
96 #define HAVE_TEX3_VERTICES 0
97 #define HAVE_PTEX_VERTICES 1
99 #define PTEX_FALLBACK() /* never needed */
101 #define INTERP_VERTEX setup_tab[GAMMA_CONTEXT(ctx)->SetupIndex].interp
102 #define COPY_PV_VERTEX setup_tab[GAMMA_CONTEXT(ctx)->SetupIndex].copy_pv
106 /***********************************************************************
107 * Generate pv-copying and translation functions *
108 ***********************************************************************/
110 #define TAG(x) gamma_##x
111 #include "tnl_dd/t_dd_vb.c"
113 /***********************************************************************
114 * Generate vertex emit and interp functions *
115 ***********************************************************************/
117 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT)
118 #define TAG(x) x##_wg
119 #include "tnl_dd/t_dd_vbtmp.h"
121 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT)
122 #define TAG(x) x##_wgs
123 #include "tnl_dd/t_dd_vbtmp.h"
125 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_TEX0_BIT)
126 #define TAG(x) x##_wgt0
127 #include "tnl_dd/t_dd_vbtmp.h"
129 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_TEX0_BIT|GAMMA_PTEX_BIT)
130 #define TAG(x) x##_wgpt0
131 #include "tnl_dd/t_dd_vbtmp.h"
133 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT)
134 #define TAG(x) x##_wgst0
135 #include "tnl_dd/t_dd_vbtmp.h"
137 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT|\
139 #define TAG(x) x##_wgspt0
140 #include "tnl_dd/t_dd_vbtmp.h"
142 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT)
143 #define TAG(x) x##_wgf
144 #include "tnl_dd/t_dd_vbtmp.h"
146 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT)
147 #define TAG(x) x##_wgfs
148 #include "tnl_dd/t_dd_vbtmp.h"
150 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT)
151 #define TAG(x) x##_wgft0
152 #include "tnl_dd/t_dd_vbtmp.h"
154 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT|\
156 #define TAG(x) x##_wgfpt0
157 #include "tnl_dd/t_dd_vbtmp.h"
159 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|\
161 #define TAG(x) x##_wgfst0
162 #include "tnl_dd/t_dd_vbtmp.h"
164 #define IND (GAMMA_XYZW_BIT|GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|\
165 GAMMA_TEX0_BIT|GAMMA_PTEX_BIT)
166 #define TAG(x) x##_wgfspt0
167 #include "tnl_dd/t_dd_vbtmp.h"
169 #define IND (GAMMA_TEX0_BIT)
170 #define TAG(x) x##_t0
171 #include "tnl_dd/t_dd_vbtmp.h"
173 #define IND (GAMMA_FOG_BIT)
175 #include "tnl_dd/t_dd_vbtmp.h"
177 #define IND (GAMMA_FOG_BIT|GAMMA_TEX0_BIT)
178 #define TAG(x) x##_ft0
179 #include "tnl_dd/t_dd_vbtmp.h"
181 #define IND (GAMMA_RGBA_BIT)
183 #include "tnl_dd/t_dd_vbtmp.h"
185 #define IND (GAMMA_RGBA_BIT|GAMMA_SPEC_BIT)
186 #define TAG(x) x##_gs
187 #include "tnl_dd/t_dd_vbtmp.h"
189 #define IND (GAMMA_RGBA_BIT|GAMMA_TEX0_BIT)
190 #define TAG(x) x##_gt0
191 #include "tnl_dd/t_dd_vbtmp.h"
193 #define IND (GAMMA_RGBA_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT)
194 #define TAG(x) x##_gst0
195 #include "tnl_dd/t_dd_vbtmp.h"
197 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT)
198 #define TAG(x) x##_gf
199 #include "tnl_dd/t_dd_vbtmp.h"
201 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT)
202 #define TAG(x) x##_gfs
203 #include "tnl_dd/t_dd_vbtmp.h"
205 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_TEX0_BIT)
206 #define TAG(x) x##_gft0
207 #include "tnl_dd/t_dd_vbtmp.h"
209 #define IND (GAMMA_RGBA_BIT|GAMMA_FOG_BIT|GAMMA_SPEC_BIT|GAMMA_TEX0_BIT)
210 #define TAG(x) x##_gfst0
211 #include "tnl_dd/t_dd_vbtmp.h"
213 static void init_setup_tab( void )
240 void gammaCheckTexSizes( GLcontext
*ctx
)
242 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
243 gammaContextPtr gmesa
= GAMMA_CONTEXT( ctx
);
245 if (!setup_tab
[gmesa
->SetupIndex
].check_tex_sizes(ctx
)) {
246 /* Invalidate stored verts
248 gmesa
->SetupNewInputs
= ~0;
249 gmesa
->SetupIndex
|= GAMMA_PTEX_BIT
;
251 if (!(ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
252 tnl
->Driver
.Render
.Interp
= setup_tab
[gmesa
->SetupIndex
].interp
;
253 tnl
->Driver
.Render
.CopyPV
= setup_tab
[gmesa
->SetupIndex
].copy_pv
;
258 void gammaBuildVertices( GLcontext
*ctx
,
263 gammaContextPtr gmesa
= GAMMA_CONTEXT( ctx
);
264 GLuint stride
= gmesa
->vertex_size
* sizeof(int);
265 GLubyte
*v
= ((GLubyte
*)gmesa
->verts
+ (start
* stride
));
267 newinputs
|= gmesa
->SetupNewInputs
;
268 gmesa
->SetupNewInputs
= 0;
273 if (newinputs
& VERT_BIT_POS
) {
274 setup_tab
[gmesa
->SetupIndex
].emit( ctx
, start
, count
, v
, stride
);
278 if (newinputs
& VERT_BIT_COLOR0
)
279 ind
|= GAMMA_RGBA_BIT
;
281 if (newinputs
& VERT_BIT_COLOR1
)
282 ind
|= GAMMA_SPEC_BIT
;
284 if (newinputs
& VERT_BIT_TEX0
)
285 ind
|= GAMMA_TEX0_BIT
;
287 if (newinputs
& VERT_BIT_FOG
)
288 ind
|= GAMMA_FOG_BIT
;
290 if (gmesa
->SetupIndex
& GAMMA_PTEX_BIT
)
293 ind
&= gmesa
->SetupIndex
;
296 setup_tab
[ind
].emit( ctx
, start
, count
, v
, stride
);
301 void gammaChooseVertexState( GLcontext
*ctx
)
303 gammaContextPtr gmesa
= GAMMA_CONTEXT( ctx
);
304 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
305 GLuint ind
= GAMMA_XYZW_BIT
|GAMMA_RGBA_BIT
;
307 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
)
308 ind
|= GAMMA_SPEC_BIT
;
310 if (ctx
->Fog
.Enabled
)
311 ind
|= GAMMA_FOG_BIT
;
313 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
) {
314 _tnl_need_projected_coords( ctx
, GL_FALSE
);
315 ind
|= GAMMA_TEX0_BIT
;
317 _tnl_need_projected_coords( ctx
, GL_FALSE
);
319 gmesa
->SetupIndex
= ind
;
321 if (setup_tab
[ind
].vertex_format
!= gmesa
->vertex_format
) {
322 gmesa
->vertex_format
= setup_tab
[ind
].vertex_format
;
323 gmesa
->vertex_size
= setup_tab
[ind
].vertex_size
;
326 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
327 tnl
->Driver
.Render
.Interp
= gamma_interp_extras
;
328 tnl
->Driver
.Render
.CopyPV
= gamma_copy_pv_extras
;
330 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
331 tnl
->Driver
.Render
.CopyPV
= setup_tab
[ind
].copy_pv
;
336 void gammaInitVB( GLcontext
*ctx
)
338 gammaContextPtr gmesa
= GAMMA_CONTEXT(ctx
);
339 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
341 gmesa
->verts
= (GLubyte
*)_mesa_align_malloc(size
* 4 * 16, 32);
344 static int firsttime
= 1;
348 gmesa
->vertex_size
= 16; /* FIXME - only one vertex setup */
354 void gammaFreeVB( GLcontext
*ctx
)
356 gammaContextPtr gmesa
= GAMMA_CONTEXT(ctx
);
358 _mesa_align_free(gmesa
->verts
);