1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.c,v 1.16 2003/03/26 20:43:49 tsi Exp $ */
2 /**************************************************************************
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 VA Linux Systems Inc., Fremont, California.
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the "Software"),
11 to deal in the Software without restriction, including without limitation
12 on the rights to use, copy, modify, merge, publish, distribute, sub
13 license, and/or sell copies of the Software, and to permit persons to whom
14 the Software is furnished to do so, subject to the following conditions:
16 The above copyright notice and this permission notice (including the next
17 paragraph) shall be included in all copies or substantial portions of the
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
23 ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
24 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
25 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
26 USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * Keith Whitwell <keith@tungstengraphics.com>
42 #include "swrast_setup/swrast_setup.h"
43 #include "tnl/t_context.h"
45 #include "r128_context.h"
47 #include "r128_ioctl.h"
48 #include "r128_tris.h"
49 #include "r128_state.h"
52 #define R128_TEX1_BIT 0x1
53 #define R128_TEX0_BIT 0x2
54 #define R128_RGBA_BIT 0x4
55 #define R128_SPEC_BIT 0x8
56 #define R128_FOG_BIT 0x10
57 #define R128_XYZW_BIT 0x20
58 #define R128_PTEX_BIT 0x40
59 #define R128_MAX_SETUP 0x80
62 void (*emit
)( GLcontext
*, GLuint
, GLuint
, void *, GLuint
);
63 tnl_interp_func interp
;
64 tnl_copy_pv_func copy_pv
;
65 GLboolean (*check_tex_sizes
)( GLcontext
*ctx
);
68 } setup_tab
[R128_MAX_SETUP
];
70 #define TINY_VERTEX_FORMAT (R128_CCE_VC_FRMT_DIFFUSE_ARGB)
72 #define NOTEX_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \
73 R128_CCE_VC_FRMT_DIFFUSE_ARGB |\
74 R128_CCE_VC_FRMT_SPEC_FRGB)
76 #define TEX0_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \
77 R128_CCE_VC_FRMT_DIFFUSE_ARGB |\
78 R128_CCE_VC_FRMT_SPEC_FRGB | \
81 #define TEX1_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \
82 R128_CCE_VC_FRMT_DIFFUSE_ARGB |\
83 R128_CCE_VC_FRMT_SPEC_FRGB | \
84 R128_CCE_VC_FRMT_S_T | \
85 R128_CCE_VC_FRMT_S2_T2)
88 #define PROJ_TEX1_VERTEX_FORMAT 0
89 #define TEX2_VERTEX_FORMAT 0
90 #define TEX3_VERTEX_FORMAT 0
91 #define PROJ_TEX3_VERTEX_FORMAT 0
93 #define DO_XYZW (IND & R128_XYZW_BIT)
94 #define DO_RGBA (IND & R128_RGBA_BIT)
95 #define DO_SPEC (IND & R128_SPEC_BIT)
96 #define DO_FOG (IND & R128_FOG_BIT)
97 #define DO_TEX0 (IND & R128_TEX0_BIT)
98 #define DO_TEX1 (IND & R128_TEX1_BIT)
101 #define DO_PTEX (IND & R128_PTEX_BIT)
103 #define VERTEX r128Vertex
104 #define VERTEX_COLOR r128_color_t
105 #define LOCALVARS r128ContextPtr rmesa = R128_CONTEXT(ctx);
106 #define GET_VIEWPORT_MAT() rmesa->hw_viewport
107 #define GET_TEXSOURCE(n) rmesa->tmu_source[n]
108 #define GET_VERTEX_FORMAT() rmesa->vertex_format
109 #define GET_VERTEX_STORE() rmesa->verts
110 #define GET_VERTEX_SIZE() rmesa->vertex_size * sizeof(GLuint)
111 #define INVALIDATE_STORED_VERTICES()
113 #define HAVE_HW_VIEWPORT 0
114 #define HAVE_HW_DIVIDE 0
115 #define HAVE_RGBA_COLOR 0
116 #define HAVE_TINY_VERTICES 1
117 #define HAVE_NOTEX_VERTICES 1
118 #define HAVE_TEX0_VERTICES 1
119 #define HAVE_TEX1_VERTICES 1
120 #define HAVE_TEX2_VERTICES 0
121 #define HAVE_TEX3_VERTICES 0
122 #define HAVE_PTEX_VERTICES 0 /* r128 rhw2 not supported by template */
124 #define UNVIEWPORT_VARS GLfloat h = R128_CONTEXT(ctx)->driDrawable->h
125 #define UNVIEWPORT_X(x) x - SUBPIXEL_X
126 #define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y
127 #define UNVIEWPORT_Z(z) z / rmesa->depth_scale
129 #define PTEX_FALLBACK() FALLBACK(R128_CONTEXT(ctx), R128_FALLBACK_TEXTURE, 1)
131 #define INTERP_VERTEX setup_tab[rmesa->SetupIndex].interp
132 #define COPY_PV_VERTEX setup_tab[rmesa->SetupIndex].copy_pv
134 /***********************************************************************
135 * Generate pv-copying and translation functions *
136 ***********************************************************************/
138 #define TAG(x) r128_##x
139 #include "tnl_dd/t_dd_vb.c"
141 /***********************************************************************
142 * Generate vertex emit and interp functions *
143 ***********************************************************************/
146 #define IND (R128_XYZW_BIT|R128_RGBA_BIT)
147 #define TAG(x) x##_wg
148 #include "tnl_dd/t_dd_vbtmp.h"
150 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_SPEC_BIT)
151 #define TAG(x) x##_wgs
152 #include "tnl_dd/t_dd_vbtmp.h"
154 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_TEX0_BIT)
155 #define TAG(x) x##_wgt0
156 #include "tnl_dd/t_dd_vbtmp.h"
158 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT)
159 #define TAG(x) x##_wgt0t1
160 #include "tnl_dd/t_dd_vbtmp.h"
162 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_TEX0_BIT|R128_PTEX_BIT)
163 #define TAG(x) x##_wgpt0
164 #include "tnl_dd/t_dd_vbtmp.h"
166 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT)
167 #define TAG(x) x##_wgst0
168 #include "tnl_dd/t_dd_vbtmp.h"
170 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|\
172 #define TAG(x) x##_wgst0t1
173 #include "tnl_dd/t_dd_vbtmp.h"
175 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|\
177 #define TAG(x) x##_wgspt0
178 #include "tnl_dd/t_dd_vbtmp.h"
180 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT)
181 #define TAG(x) x##_wgf
182 #include "tnl_dd/t_dd_vbtmp.h"
184 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT)
185 #define TAG(x) x##_wgfs
186 #include "tnl_dd/t_dd_vbtmp.h"
188 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT)
189 #define TAG(x) x##_wgft0
190 #include "tnl_dd/t_dd_vbtmp.h"
192 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|\
194 #define TAG(x) x##_wgft0t1
195 #include "tnl_dd/t_dd_vbtmp.h"
197 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|\
199 #define TAG(x) x##_wgfpt0
200 #include "tnl_dd/t_dd_vbtmp.h"
202 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|\
204 #define TAG(x) x##_wgfst0
205 #include "tnl_dd/t_dd_vbtmp.h"
207 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|\
208 R128_TEX0_BIT|R128_TEX1_BIT)
209 #define TAG(x) x##_wgfst0t1
210 #include "tnl_dd/t_dd_vbtmp.h"
212 #define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|\
213 R128_TEX0_BIT|R128_PTEX_BIT)
214 #define TAG(x) x##_wgfspt0
215 #include "tnl_dd/t_dd_vbtmp.h"
217 #define IND (R128_TEX0_BIT)
218 #define TAG(x) x##_t0
219 #include "tnl_dd/t_dd_vbtmp.h"
221 #define IND (R128_TEX0_BIT|R128_TEX1_BIT)
222 #define TAG(x) x##_t0t1
223 #include "tnl_dd/t_dd_vbtmp.h"
225 #define IND (R128_FOG_BIT)
227 #include "tnl_dd/t_dd_vbtmp.h"
229 #define IND (R128_FOG_BIT|R128_TEX0_BIT)
230 #define TAG(x) x##_ft0
231 #include "tnl_dd/t_dd_vbtmp.h"
233 #define IND (R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT)
234 #define TAG(x) x##_ft0t1
235 #include "tnl_dd/t_dd_vbtmp.h"
237 #define IND (R128_RGBA_BIT)
239 #include "tnl_dd/t_dd_vbtmp.h"
241 #define IND (R128_RGBA_BIT|R128_SPEC_BIT)
242 #define TAG(x) x##_gs
243 #include "tnl_dd/t_dd_vbtmp.h"
245 #define IND (R128_RGBA_BIT|R128_TEX0_BIT)
246 #define TAG(x) x##_gt0
247 #include "tnl_dd/t_dd_vbtmp.h"
249 #define IND (R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT)
250 #define TAG(x) x##_gt0t1
251 #include "tnl_dd/t_dd_vbtmp.h"
253 #define IND (R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT)
254 #define TAG(x) x##_gst0
255 #include "tnl_dd/t_dd_vbtmp.h"
257 #define IND (R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT)
258 #define TAG(x) x##_gst0t1
259 #include "tnl_dd/t_dd_vbtmp.h"
261 #define IND (R128_RGBA_BIT|R128_FOG_BIT)
262 #define TAG(x) x##_gf
263 #include "tnl_dd/t_dd_vbtmp.h"
265 #define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT)
266 #define TAG(x) x##_gfs
267 #include "tnl_dd/t_dd_vbtmp.h"
269 #define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT)
270 #define TAG(x) x##_gft0
271 #include "tnl_dd/t_dd_vbtmp.h"
273 #define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT)
274 #define TAG(x) x##_gft0t1
275 #include "tnl_dd/t_dd_vbtmp.h"
277 #define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT)
278 #define TAG(x) x##_gfst0
279 #include "tnl_dd/t_dd_vbtmp.h"
281 #define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|\
283 #define TAG(x) x##_gfst0t1
284 #include "tnl_dd/t_dd_vbtmp.h"
287 static void init_setup_tab( void )
326 void r128PrintSetupFlags(char *msg
, GLuint flags
)
328 fprintf(stderr
, "%s(%x): %s%s%s%s%s%s\n",
331 (flags
& R128_XYZW_BIT
) ? " xyzw," : "",
332 (flags
& R128_RGBA_BIT
) ? " rgba," : "",
333 (flags
& R128_SPEC_BIT
) ? " spec," : "",
334 (flags
& R128_FOG_BIT
) ? " fog," : "",
335 (flags
& R128_TEX0_BIT
) ? " tex-0," : "",
336 (flags
& R128_TEX1_BIT
) ? " tex-1," : "");
341 void r128CheckTexSizes( GLcontext
*ctx
)
343 r128ContextPtr rmesa
= R128_CONTEXT( ctx
);
345 if (!setup_tab
[rmesa
->SetupIndex
].check_tex_sizes(ctx
)) {
346 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
348 /* Invalidate stored verts
350 rmesa
->SetupNewInputs
= ~0;
351 rmesa
->SetupIndex
|= R128_PTEX_BIT
;
353 if (!rmesa
->Fallback
&&
354 !(ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
))) {
355 tnl
->Driver
.Render
.Interp
= setup_tab
[rmesa
->SetupIndex
].interp
;
356 tnl
->Driver
.Render
.CopyPV
= setup_tab
[rmesa
->SetupIndex
].copy_pv
;
358 if (rmesa
->Fallback
) {
359 tnl
->Driver
.Render
.Start(ctx
);
364 void r128BuildVertices( GLcontext
*ctx
,
369 r128ContextPtr rmesa
= R128_CONTEXT( ctx
);
370 GLuint stride
= rmesa
->vertex_size
* sizeof(int);
371 GLubyte
*v
= ((GLubyte
*)rmesa
->verts
+ (start
* stride
));
373 newinputs
|= rmesa
->SetupNewInputs
;
374 rmesa
->SetupNewInputs
= 0;
379 if (newinputs
& VERT_BIT_POS
) {
380 setup_tab
[rmesa
->SetupIndex
].emit( ctx
, start
, count
, v
, stride
);
384 if (newinputs
& VERT_BIT_COLOR0
)
385 ind
|= R128_RGBA_BIT
;
387 if (newinputs
& VERT_BIT_COLOR1
)
388 ind
|= R128_SPEC_BIT
;
390 if (newinputs
& VERT_BIT_TEX0
)
391 ind
|= R128_TEX0_BIT
;
393 if (newinputs
& VERT_BIT_TEX1
)
394 ind
|= R128_TEX1_BIT
;
396 if (newinputs
& VERT_BIT_FOG
)
399 if (rmesa
->SetupIndex
& R128_PTEX_BIT
)
402 ind
&= rmesa
->SetupIndex
;
405 setup_tab
[ind
].emit( ctx
, start
, count
, v
, stride
);
410 void r128ChooseVertexState( GLcontext
*ctx
)
412 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
413 r128ContextPtr rmesa
= R128_CONTEXT( ctx
);
414 GLuint ind
= R128_XYZW_BIT
|R128_RGBA_BIT
;
416 if (ctx
->_TriangleCaps
& DD_SEPARATE_SPECULAR
)
417 ind
|= R128_SPEC_BIT
;
419 if (ctx
->Fog
.Enabled
)
422 if (ctx
->Texture
._EnabledUnits
) {
423 ind
|= R128_TEX0_BIT
;
424 if (ctx
->Texture
.Unit
[0]._ReallyEnabled
&&
425 ctx
->Texture
.Unit
[1]._ReallyEnabled
)
426 ind
|= R128_TEX1_BIT
;
429 rmesa
->SetupIndex
= ind
;
431 if (ctx
->_TriangleCaps
& (DD_TRI_LIGHT_TWOSIDE
|DD_TRI_UNFILLED
)) {
432 tnl
->Driver
.Render
.Interp
= r128_interp_extras
;
433 tnl
->Driver
.Render
.CopyPV
= r128_copy_pv_extras
;
435 tnl
->Driver
.Render
.Interp
= setup_tab
[ind
].interp
;
436 tnl
->Driver
.Render
.CopyPV
= setup_tab
[ind
].copy_pv
;
439 if (setup_tab
[ind
].vertex_format
!= rmesa
->vertex_format
) {
441 rmesa
->vertex_format
= setup_tab
[ind
].vertex_format
;
442 rmesa
->vertex_size
= setup_tab
[ind
].vertex_size
;
448 void r128_emit_contiguous_verts( GLcontext
*ctx
,
452 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
453 GLuint vertex_size
= rmesa
->vertex_size
* 4;
454 GLuint
*dest
= r128AllocDmaLow( rmesa
, (count
-start
) * vertex_size
);
455 setup_tab
[rmesa
->SetupIndex
].emit( ctx
, start
, count
, dest
, vertex_size
);
460 void r128_emit_indexed_verts( GLcontext
*ctx
, GLuint start
, GLuint count
)
462 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
463 GLuint vertex_size
= rmesa
->vertex_size
* 4;
464 GLuint bufsz
= (count
-start
) * vertex_size
;
467 rmesa
->vertex_low
= (rmesa
->vertex_low
+ 63) & ~63; /* alignment */
468 rmesa
->vertex_last_prim
= rmesa
->vertex_low
;
470 dest
= r128AllocDmaLow( rmesa
, bufsz
, __FUNCTION__
);
471 setup_tab
[rmesa
->SetupIndex
].emit( ctx
, start
, count
, dest
, vertex_size
);
473 rmesa
->retained_buffer
= rmesa
->vertex_buffer
;
474 rmesa
->vb_offset
= (rmesa
->vertex_buffer
->idx
* R128_BUFFER_SIZE
+
475 rmesa
->vertex_low
- bufsz
);
477 rmesa
->vertex_low
= (rmesa
->vertex_low
+ 0x7) & ~0x7; /* alignment */
478 rmesa
->vertex_last_prim
= rmesa
->vertex_low
;
483 void r128InitVB( GLcontext
*ctx
)
485 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
486 GLuint size
= TNL_CONTEXT(ctx
)->vb
.Size
;
488 rmesa
->verts
= (GLubyte
*)ALIGN_MALLOC(size
* 4 * 16, 32);
491 static int firsttime
= 1;
500 void r128FreeVB( GLcontext
*ctx
)
502 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
504 ALIGN_FREE(rmesa
->verts
);